@wvdsh/sdk-js 1.3.27 → 1.3.30
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/index.js +242 -80
- package/dist/inject.global.js +2 -2
- package/package.json +2 -2
package/dist/inject.global.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";(()=>{var mn=Object.create;var Ut=Object.defineProperty;var yn=Object.getOwnPropertyDescriptor;var bn=Object.getOwnPropertyNames;var vn=Object.getPrototypeOf,wn=Object.prototype.hasOwnProperty;var En=(n,t)=>()=>(t||n((t={exports:{}}).exports,t),t.exports),Sn=(n,t)=>{for(var e in t)Ut(n,e,{get:t[e],enumerable:!0})},Cn=(n,t,e,r)=>{if(t&&typeof t=="object"||typeof t=="function")for(let s of bn(t))!wn.call(n,s)&&s!==e&&Ut(n,s,{get:()=>t[s],enumerable:!(r=yn(t,s))||r.enumerable});return n};var lr=(n,t,e)=>(e=n!=null?mn(vn(n)):{},Cn(t||!n||!n.__esModule?Ut(e,"default",{value:n,enumerable:!0}):e,n));var or=En((Yl,Yr)=>{"use strict";var zr="Expected a function",Jr=NaN,Gs="[object Symbol]",Vs=/^\s+|\s+$/g,Ws=/^[-+]0x[0-9a-f]+$/i,Qs=/^0b[01]+$/i,Hs=/^0o[0-7]+$/i,js=parseInt,Js=typeof global=="object"&&global&&global.Object===Object&&global,Ks=typeof self=="object"&&self&&self.Object===Object&&self,zs=Js||Ks||Function("return this")(),Ys=Object.prototype,Zs=Ys.toString,Xs=Math.max,ei=Math.min,ir=function(){return zs.Date.now()};function ti(n,t,e){var r,s,o,i,a,c,l=0,d=!1,f=!1,v=!0;if(typeof n!="function")throw new TypeError(zr);t=Kr(t)||0,St(e)&&(d=!!e.leading,f="maxWait"in e,o=f?Xs(Kr(e.maxWait)||0,t):o,v="trailing"in e?!!e.trailing:v);function h(T){var K=r,ye=s;return r=s=void 0,l=T,i=n.apply(ye,K),i}function m(T){return l=T,a=setTimeout(Oe,t),d?h(T):i}function N(T){var K=T-c,ye=T-l,ur=t-K;return f?ei(ur,o-ye):ur}function ue(T){var K=T-c,ye=T-l;return c===void 0||K>=t||K<0||f&&ye>=o}function Oe(){var T=ir();if(ue(T))return cr(T);a=setTimeout(Oe,N(T))}function cr(T){return a=void 0,v&&r?h(T):(r=s=void 0,i)}function pn(){a!==void 0&&clearTimeout(a),l=0,r=c=s=a=void 0}function gn(){return a===void 0?i:cr(ir())}function Dt(){var T=ir(),K=ue(T);if(r=arguments,s=this,c=T,K){if(a===void 0)return m(c);if(f)return a=setTimeout(Oe,t),h(c)}return a===void 0&&(a=setTimeout(Oe,t)),i}return Dt.cancel=pn,Dt.flush=gn,Dt}function ri(n,t,e){var r=!0,s=!0;if(typeof n!="function")throw new TypeError(zr);return St(e)&&(r="leading"in e?!!e.leading:r,s="trailing"in e?!!e.trailing:s),ti(n,t,{leading:r,maxWait:t,trailing:s})}function St(n){var t=typeof n;return!!n&&(t=="object"||t=="function")}function ni(n){return!!n&&typeof n=="object"}function si(n){return typeof n=="symbol"||ni(n)&&Zs.call(n)==Gs}function Kr(n){if(typeof n=="number")return n;if(si(n))return Jr;if(St(n)){var t=typeof n.valueOf=="function"?n.valueOf():n;n=St(t)?t+"":t}if(typeof n!="string")return n===0?n:+n;n=n.replace(Vs,"");var e=Qs.test(n);return e||Hs.test(n)?js(n.slice(2),e?2:8):Ws.test(n)?Jr:+n}Yr.exports=ri});var k="1.39.1";var de={};Sn(de,{byteLength:()=>Pn,fromByteArray:()=>ie,fromByteArrayUrlSafeNoPadding:()=>xn,toByteArray:()=>le});var $=[],O=[],In=Uint8Array,Ft="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";for(se=0,dr=Ft.length;se<dr;++se)$[se]=Ft[se],O[Ft.charCodeAt(se)]=se;var se,dr;O[45]=62;O[95]=63;function hr(n){var t=n.length;if(t%4>0)throw new Error("Invalid string. Length must be a multiple of 4");var e=n.indexOf("=");e===-1&&(e=t);var r=e===t?0:4-e%4;return[e,r]}function Pn(n){var t=hr(n),e=t[0],r=t[1];return(e+r)*3/4-r}function Tn(n,t,e){return(t+e)*3/4-e}function le(n){var t,e=hr(n),r=e[0],s=e[1],o=new In(Tn(n,r,s)),i=0,a=s>0?r-4:r,c;for(c=0;c<a;c+=4)t=O[n.charCodeAt(c)]<<18|O[n.charCodeAt(c+1)]<<12|O[n.charCodeAt(c+2)]<<6|O[n.charCodeAt(c+3)],o[i++]=t>>16&255,o[i++]=t>>8&255,o[i++]=t&255;return s===2&&(t=O[n.charCodeAt(c)]<<2|O[n.charCodeAt(c+1)]>>4,o[i++]=t&255),s===1&&(t=O[n.charCodeAt(c)]<<10|O[n.charCodeAt(c+1)]<<4|O[n.charCodeAt(c+2)]>>2,o[i++]=t>>8&255,o[i++]=t&255),o}function An(n){return $[n>>18&63]+$[n>>12&63]+$[n>>6&63]+$[n&63]}function Mn(n,t,e){for(var r,s=[],o=t;o<e;o+=3)r=(n[o]<<16&16711680)+(n[o+1]<<8&65280)+(n[o+2]&255),s.push(An(r));return s.join("")}function ie(n){for(var t,e=n.length,r=e%3,s=[],o=16383,i=0,a=e-r;i<a;i+=o)s.push(Mn(n,i,i+o>a?a:i+o));return r===1?(t=n[e-1],s.push($[t>>2]+$[t<<4&63]+"==")):r===2&&(t=(n[e-2]<<8)+n[e-1],s.push($[t>>10]+$[t>>4&63]+$[t<<2&63]+"=")),s.join("")}function xn(n){return ie(n).replace(/\+/g,"-").replace(/\//g,"_").replace(/=/g,"")}function R(n){if(n===void 0)return{};if(!De(n))throw new Error(`The arguments to a Convex function must be an object. Received: ${n}`);return n}function be(n){if(typeof n>"u")throw new Error("Client created with undefined deployment address. If you used an environment variable, check that it's set.");if(typeof n!="string")throw new Error(`Invalid deployment address: found ${n}".`);if(!(n.startsWith("http:")||n.startsWith("https:")))throw new Error(`Invalid deployment address: Must start with "https://" or "http://". Found "${n}".`);try{new URL(n)}catch{throw new Error(`Invalid deployment address: "${n}" is not a valid URL. If you believe this URL is correct, use the \`skipConvexDeploymentUrlCheck\` option to bypass this.`)}if(n.endsWith(".convex.site"))throw new Error(`Invalid deployment address: "${n}" ends with .convex.site, which is used for HTTP Actions. Convex deployment URLs typically end with .convex.cloud? If you believe this URL is correct, use the \`skipConvexDeploymentUrlCheck\` option to bypass this.`)}function De(n){let t=typeof n=="object",e=Object.getPrototypeOf(n),r=e===null||e===Object.prototype||e?.constructor?.name==="Object";return t&&r}var gr=!0,he=BigInt("-9223372036854775808"),Bt=BigInt("9223372036854775807"),$t=BigInt("0"),Rn=BigInt("8"),_n=BigInt("256");function mr(n){return Number.isNaN(n)||!Number.isFinite(n)||Object.is(n,-0)}function Ln(n){n<$t&&(n-=he+he);let t=n.toString(16);t.length%2===1&&(t="0"+t);let e=new Uint8Array(new ArrayBuffer(8)),r=0;for(let s of t.match(/.{2}/g).reverse())e.set([parseInt(s,16)],r++),n>>=Rn;return ie(e)}function kn(n){let t=le(n);if(t.byteLength!==8)throw new Error(`Received ${t.byteLength} bytes, expected 8 for $integer`);let e=$t,r=$t;for(let s of t)e+=BigInt(s)*_n**r,r++;return e>Bt&&(e+=he+he),e}function On(n){if(n<he||Bt<n)throw new Error(`BigInt ${n} does not fit into a 64-bit signed integer.`);let t=new ArrayBuffer(8);return new DataView(t).setBigInt64(0,n,!0),ie(new Uint8Array(t))}function Dn(n){let t=le(n);if(t.byteLength!==8)throw new Error(`Received ${t.byteLength} bytes, expected 8 for $integer`);return new DataView(t.buffer).getBigInt64(0,!0)}var Un=DataView.prototype.setBigInt64?On:Ln,Fn=DataView.prototype.getBigInt64?Dn:kn,fr=1024;function qt(n){if(n.length>fr)throw new Error(`Field name ${n} exceeds maximum field name length ${fr}.`);if(n.startsWith("$"))throw new Error(`Field name ${n} starts with a '$', which is reserved.`);for(let t=0;t<n.length;t+=1){let e=n.charCodeAt(t);if(e<32||e>=127)throw new Error(`Field name ${n} has invalid character '${n[t]}': Field names can only contain non-control ASCII characters`)}}function x(n){if(n===null||typeof n=="boolean"||typeof n=="number"||typeof n=="string")return n;if(Array.isArray(n))return n.map(r=>x(r));if(typeof n!="object")throw new Error(`Unexpected type of ${n}`);let t=Object.entries(n);if(t.length===1){let r=t[0][0];if(r==="$bytes"){if(typeof n.$bytes!="string")throw new Error(`Malformed $bytes field on ${n}`);return le(n.$bytes).buffer}if(r==="$integer"){if(typeof n.$integer!="string")throw new Error(`Malformed $integer field on ${n}`);return Fn(n.$integer)}if(r==="$float"){if(typeof n.$float!="string")throw new Error(`Malformed $float field on ${n}`);let s=le(n.$float);if(s.byteLength!==8)throw new Error(`Received ${s.byteLength} bytes, expected 8 for $float`);let i=new DataView(s.buffer).getFloat64(0,gr);if(!mr(i))throw new Error(`Float ${i} should be encoded as a number`);return i}if(r==="$set")throw new Error("Received a Set which is no longer supported as a Convex type.");if(r==="$map")throw new Error("Received a Map which is no longer supported as a Convex type.")}let e={};for(let[r,s]of Object.entries(n))qt(r),e[r]=x(s);return e}var pr=16384;function oe(n){let t=JSON.stringify(n,(e,r)=>r===void 0?"undefined":typeof r=="bigint"?`${r.toString()}n`:r);if(t.length>pr){let e="[...truncated]",r=pr-e.length,s=t.codePointAt(r-1);return s!==void 0&&s>65535&&(r-=1),t.substring(0,r)+e}return t}function Ue(n,t,e,r){if(n===void 0){let i=e&&` (present at path ${e} in original object ${oe(t)})`;throw new Error(`undefined is not a valid Convex value${i}. To learn about Convex's supported types, see https://docs.convex.dev/using/types.`)}if(n===null)return n;if(typeof n=="bigint"){if(n<he||Bt<n)throw new Error(`BigInt ${n} does not fit into a 64-bit signed integer.`);return{$integer:Un(n)}}if(typeof n=="number")if(mr(n)){let i=new ArrayBuffer(8);return new DataView(i).setFloat64(0,n,gr),{$float:ie(new Uint8Array(i))}}else return n;if(typeof n=="boolean"||typeof n=="string")return n;if(n instanceof ArrayBuffer)return{$bytes:ie(new Uint8Array(n))};if(Array.isArray(n))return n.map((i,a)=>Ue(i,t,e+`[${a}]`,!1));if(n instanceof Set)throw new Error(Nt(e,"Set",[...n],t));if(n instanceof Map)throw new Error(Nt(e,"Map",[...n],t));if(!De(n)){let i=n?.constructor?.name,a=i?`${i} `:"";throw new Error(Nt(e,a,n,t))}let s={},o=Object.entries(n);o.sort(([i,a],[c,l])=>i===c?0:i<c?-1:1);for(let[i,a]of o)a!==void 0?(qt(i),s[i]=Ue(a,t,e+`.${i}`,!1)):r&&(qt(i),s[i]=Nn(a,t,e+`.${i}`));return s}function Nt(n,t,e,r){return n?`${t}${oe(e)} is not a supported Convex type (present at path ${n} in original object ${oe(r)}). To learn about Convex's supported types, see https://docs.convex.dev/using/types.`:`${t}${oe(e)} is not a supported Convex type.`}function Nn(n,t,e){if(n===void 0)return{$undefined:null};if(t===void 0)throw new Error(`Programming error. Current value is ${oe(n)} but original value is undefined`);return Ue(n,t,e,!1)}function A(n){return Ue(n,n,"",!1)}var $n=Object.defineProperty,qn=(n,t,e)=>t in n?$n(n,t,{enumerable:!0,configurable:!0,writable:!0,value:e}):n[t]=e,S=(n,t,e)=>qn(n,typeof t!="symbol"?t+"":t,e),Bn="https://docs.convex.dev/error#undefined-validator";function ve(n,t){let e=t!==void 0?` for field "${t}"`:"";throw new Error(`A validator is undefined${e} in ${n}. This is often caused by circular imports. See ${Bn} for details.`)}var _=class{constructor({isOptional:t}){S(this,"type"),S(this,"fieldPaths"),S(this,"isOptional"),S(this,"isConvexValidator"),this.isOptional=t,this.isConvexValidator=!0}},Fe=class n extends _{constructor({isOptional:t,tableName:e}){if(super({isOptional:t}),S(this,"tableName"),S(this,"kind","id"),typeof e!="string")throw new Error("v.id(tableName) requires a string");this.tableName=e}get json(){return{type:"id",tableName:this.tableName}}asOptional(){return new n({isOptional:"optional",tableName:this.tableName})}},we=class n extends _{constructor(){super(...arguments),S(this,"kind","float64")}get json(){return{type:"number"}}asOptional(){return new n({isOptional:"optional"})}},Ee=class n extends _{constructor(){super(...arguments),S(this,"kind","int64")}get json(){return{type:"bigint"}}asOptional(){return new n({isOptional:"optional"})}},Ne=class n extends _{constructor(){super(...arguments),S(this,"kind","boolean")}get json(){return{type:this.kind}}asOptional(){return new n({isOptional:"optional"})}},$e=class n extends _{constructor(){super(...arguments),S(this,"kind","bytes")}get json(){return{type:this.kind}}asOptional(){return new n({isOptional:"optional"})}},qe=class n extends _{constructor(){super(...arguments),S(this,"kind","string")}get json(){return{type:this.kind}}asOptional(){return new n({isOptional:"optional"})}},Be=class n extends _{constructor(){super(...arguments),S(this,"kind","null")}get json(){return{type:this.kind}}asOptional(){return new n({isOptional:"optional"})}},Ge=class n extends _{constructor(){super(...arguments),S(this,"kind","any")}get json(){return{type:this.kind}}asOptional(){return new n({isOptional:"optional"})}},Ve=class n extends _{constructor({isOptional:t,fields:e}){super({isOptional:t}),S(this,"fields"),S(this,"kind","object"),globalThis.Object.entries(e).forEach(([r,s])=>{if(s===void 0&&ve("v.object()",r),!s.isConvexValidator)throw new Error("v.object() entries must be validators")}),this.fields=e}get json(){return{type:this.kind,value:globalThis.Object.fromEntries(globalThis.Object.entries(this.fields).map(([t,e])=>[t,{fieldType:e.json,optional:e.isOptional==="optional"}]))}}asOptional(){return new n({isOptional:"optional",fields:this.fields})}omit(...t){let e={...this.fields};for(let r of t)delete e[r];return new n({isOptional:this.isOptional,fields:e})}pick(...t){let e={};for(let r of t)e[r]=this.fields[r];return new n({isOptional:this.isOptional,fields:e})}partial(){let t={};for(let[e,r]of globalThis.Object.entries(this.fields))t[e]=r.asOptional();return new n({isOptional:this.isOptional,fields:t})}extend(t){return new n({isOptional:this.isOptional,fields:{...this.fields,...t}})}},We=class n extends _{constructor({isOptional:t,value:e}){if(super({isOptional:t}),S(this,"value"),S(this,"kind","literal"),typeof e!="string"&&typeof e!="boolean"&&typeof e!="number"&&typeof e!="bigint")throw new Error("v.literal(value) must be a string, number, or boolean");this.value=e}get json(){return{type:this.kind,value:A(this.value)}}asOptional(){return new n({isOptional:"optional",value:this.value})}},Qe=class n extends _{constructor({isOptional:t,element:e}){super({isOptional:t}),S(this,"element"),S(this,"kind","array"),e===void 0&&ve("v.array()"),this.element=e}get json(){return{type:this.kind,value:this.element.json}}asOptional(){return new n({isOptional:"optional",element:this.element})}},He=class n extends _{constructor({isOptional:t,key:e,value:r}){if(super({isOptional:t}),S(this,"key"),S(this,"value"),S(this,"kind","record"),e===void 0&&ve("v.record()","key"),r===void 0&&ve("v.record()","value"),e.isOptional==="optional")throw new Error("Record validator cannot have optional keys");if(r.isOptional==="optional")throw new Error("Record validator cannot have optional values");if(!e.isConvexValidator||!r.isConvexValidator)throw new Error("Key and value of v.record() but be validators");this.key=e,this.value=r}get json(){return{type:this.kind,keys:this.key.json,values:{fieldType:this.value.json,optional:!1}}}asOptional(){return new n({isOptional:"optional",key:this.key,value:this.value})}},je=class n extends _{constructor({isOptional:t,members:e}){super({isOptional:t}),S(this,"members"),S(this,"kind","union"),e.forEach((r,s)=>{if(r===void 0&&ve("v.union()",`member at index ${s}`),!r.isConvexValidator)throw new Error("All members of v.union() must be validators")}),this.members=e}get json(){return{type:this.kind,value:this.members.map(t=>t.json)}}asOptional(){return new n({isOptional:"optional",members:this.members})}};function Gt(n){return!!n.isConvexValidator}var p={id:n=>new Fe({isOptional:"required",tableName:n}),null:()=>new Be({isOptional:"required"}),number:()=>new we({isOptional:"required"}),float64:()=>new we({isOptional:"required"}),bigint:()=>new Ee({isOptional:"required"}),int64:()=>new Ee({isOptional:"required"}),boolean:()=>new Ne({isOptional:"required"}),string:()=>new qe({isOptional:"required"}),bytes:()=>new $e({isOptional:"required"}),literal:n=>new We({isOptional:"required",value:n}),array:n=>new Qe({isOptional:"required",element:n}),object:n=>new Ve({isOptional:"required",fields:n}),record:(n,t)=>new He({isOptional:"required",key:n,value:t}),union:(...n)=>new je({isOptional:"required",members:n}),any:()=>new Ge({isOptional:"required"}),optional:n=>n.asOptional(),nullable:n=>p.union(n,p.null())};var Gn=Object.defineProperty,Vn=(n,t,e)=>t in n?Gn(n,t,{enumerable:!0,configurable:!0,writable:!0,value:e}):n[t]=e,Vt=(n,t,e)=>Vn(n,typeof t!="symbol"?t+"":t,e),yr,br,Wn=Symbol.for("ConvexError"),H=class extends(br=Error,yr=Wn,br){constructor(t){super(typeof t=="string"?t:oe(t)),Vt(this,"name","ConvexError"),Vt(this,"data"),Vt(this,yr,!0),this.data=t}};var vr=()=>Array.from({length:4},()=>0),Ei=vr(),Si=vr();var Hn=Object.defineProperty,jn=(n,t,e)=>t in n?Hn(n,t,{enumerable:!0,configurable:!0,writable:!0,value:e}):n[t]=e,wr=(n,t,e)=>jn(n,typeof t!="symbol"?t+"":t,e),Jn="color:rgb(0, 145, 255)";function Er(n){switch(n){case"query":return"Q";case"mutation":return"M";case"action":return"A";case"any":return"?"}}var Je=class{constructor(t){wr(this,"_onLogLineFuncs"),wr(this,"_verbose"),this._onLogLineFuncs={},this._verbose=t.verbose}addLogLineListener(t){let e=Math.random().toString(36).substring(2,15);for(let r=0;r<10&&this._onLogLineFuncs[e]!==void 0;r++)e=Math.random().toString(36).substring(2,15);return this._onLogLineFuncs[e]=t,()=>{delete this._onLogLineFuncs[e]}}logVerbose(...t){if(this._verbose)for(let e of Object.values(this._onLogLineFuncs))e("debug",`${new Date().toISOString()}`,...t)}log(...t){for(let e of Object.values(this._onLogLineFuncs))e("info",...t)}warn(...t){for(let e of Object.values(this._onLogLineFuncs))e("warn",...t)}error(...t){for(let e of Object.values(this._onLogLineFuncs))e("error",...t)}};function Wt(n){let t=new Je(n);return t.addLogLineListener((e,...r)=>{switch(e){case"debug":console.debug(...r);break;case"info":console.log(...r);break;case"warn":console.warn(...r);break;case"error":console.error(...r);break;default:console.log(...r)}}),t}function Qt(n){return new Je(n)}function ae(n,t,e,r,s){let o=Er(e);if(typeof s=="object"&&(s=`ConvexError ${JSON.stringify(s.errorData,null,2)}`),t==="info"){let i=s.match(/^\[.*?\] /);if(i===null){n.error(`[CONVEX ${o}(${r})] Could not parse console.log`);return}let a=s.slice(1,i[0].length-2),c=s.slice(i[0].length);n.log(`%c[CONVEX ${o}(${r})] [${a}]`,Jn,c)}else n.error(`[CONVEX ${o}(${r})] ${s}`)}function Sr(n,t){let e=`[CONVEX FATAL ERROR] ${t}`;return n.error(e),new Error(e)}function z(n,t,e){return`[CONVEX ${Er(n)}(${t})] ${e.errorMessage}
|
|
2
|
-
Called by client`}function Se(n,t){return t.data=n.errorData,t}function q(n){let t=n.split(":"),e,r;return t.length===1?(e=t[0],r="default"):(e=t.slice(0,t.length-1).join(":"),r=t[t.length-1]),e.endsWith(".js")&&(e=e.slice(0,-3)),`${e}:${r}`}function B(n,t){return JSON.stringify({udfPath:q(n),args:A(t)})}function Ht(n,t,e){let{initialNumItems:r,id:s}=e;return JSON.stringify({type:"paginated",udfPath:q(n),args:A(t),options:A({initialNumItems:r,id:s})})}function Cr(n){return JSON.parse(n).type==="paginated"}var Kn=Object.defineProperty,zn=(n,t,e)=>t in n?Kn(n,t,{enumerable:!0,configurable:!0,writable:!0,value:e}):n[t]=e,G=(n,t,e)=>zn(n,typeof t!="symbol"?t+"":t,e),Ke=class{constructor(){G(this,"nextQueryId"),G(this,"querySetVersion"),G(this,"querySet"),G(this,"queryIdToToken"),G(this,"identityVersion"),G(this,"auth"),G(this,"outstandingQueriesOlderThanRestart"),G(this,"outstandingAuthOlderThanRestart"),G(this,"paused"),G(this,"pendingQuerySetModifications"),this.nextQueryId=0,this.querySetVersion=0,this.identityVersion=0,this.querySet=new Map,this.queryIdToToken=new Map,this.outstandingQueriesOlderThanRestart=new Set,this.outstandingAuthOlderThanRestart=!1,this.paused=!1,this.pendingQuerySetModifications=new Map}hasSyncedPastLastReconnect(){return this.outstandingQueriesOlderThanRestart.size===0&&!this.outstandingAuthOlderThanRestart}markAuthCompletion(){this.outstandingAuthOlderThanRestart=!1}subscribe(t,e,r,s){let o=q(t),i=B(o,e),a=this.querySet.get(i);if(a!==void 0)return a.numSubscribers+=1,{queryToken:i,modification:null,unsubscribe:()=>this.removeSubscriber(i)};{let c=this.nextQueryId++,l={id:c,canonicalizedUdfPath:o,args:e,numSubscribers:1,journal:r,componentPath:s};this.querySet.set(i,l),this.queryIdToToken.set(c,i);let d=this.querySetVersion,f=this.querySetVersion+1,v={type:"Add",queryId:c,udfPath:o,args:[A(e)],journal:r,componentPath:s};return this.paused?this.pendingQuerySetModifications.set(c,v):this.querySetVersion=f,{queryToken:i,modification:{type:"ModifyQuerySet",baseVersion:d,newVersion:f,modifications:[v]},unsubscribe:()=>this.removeSubscriber(i)}}}transition(t){for(let e of t.modifications)switch(e.type){case"QueryUpdated":case"QueryFailed":{this.outstandingQueriesOlderThanRestart.delete(e.queryId);let r=e.journal;if(r!==void 0){let s=this.queryIdToToken.get(e.queryId);s!==void 0&&(this.querySet.get(s).journal=r)}break}case"QueryRemoved":{this.outstandingQueriesOlderThanRestart.delete(e.queryId);break}default:throw new Error(`Invalid modification ${e.type}`)}}queryId(t,e){let r=q(t),s=B(r,e),o=this.querySet.get(s);return o!==void 0?o.id:null}isCurrentOrNewerAuthVersion(t){return t>=this.identityVersion}getAuth(){return this.auth}setAuth(t){this.auth={tokenType:"User",value:t};let e=this.identityVersion;return this.paused||(this.identityVersion=e+1),{type:"Authenticate",baseVersion:e,...this.auth}}setAdminAuth(t,e){let r={tokenType:"Admin",value:t,impersonating:e};this.auth=r;let s=this.identityVersion;return this.paused||(this.identityVersion=s+1),{type:"Authenticate",baseVersion:s,...r}}clearAuth(){this.auth=void 0,this.markAuthCompletion();let t=this.identityVersion;return this.paused||(this.identityVersion=t+1),{type:"Authenticate",tokenType:"None",baseVersion:t}}hasAuth(){return!!this.auth}isNewAuth(t){return this.auth?.value!==t}queryPath(t){let e=this.queryIdToToken.get(t);return e?this.querySet.get(e).canonicalizedUdfPath:null}queryArgs(t){let e=this.queryIdToToken.get(t);return e?this.querySet.get(e).args:null}queryToken(t){return this.queryIdToToken.get(t)??null}queryJournal(t){return this.querySet.get(t)?.journal}restart(){this.unpause(),this.outstandingQueriesOlderThanRestart.clear();let t=[];for(let s of this.querySet.values()){let o={type:"Add",queryId:s.id,udfPath:s.canonicalizedUdfPath,args:[A(s.args)],journal:s.journal,componentPath:s.componentPath};t.push(o),this.outstandingQueriesOlderThanRestart.add(s.id)}this.querySetVersion=1;let e={type:"ModifyQuerySet",baseVersion:0,newVersion:1,modifications:t};if(!this.auth)return this.identityVersion=0,[e,void 0];this.outstandingAuthOlderThanRestart=!0;let r={type:"Authenticate",baseVersion:0,...this.auth};return this.identityVersion=1,[e,r]}pause(){this.paused=!0}resume(){let t=this.pendingQuerySetModifications.size>0?{type:"ModifyQuerySet",baseVersion:this.querySetVersion,newVersion:++this.querySetVersion,modifications:Array.from(this.pendingQuerySetModifications.values())}:void 0,e=this.auth!==void 0?{type:"Authenticate",baseVersion:this.identityVersion++,...this.auth}:void 0;return this.unpause(),[t,e]}unpause(){this.paused=!1,this.pendingQuerySetModifications.clear()}removeSubscriber(t){let e=this.querySet.get(t);if(e.numSubscribers>1)return e.numSubscribers-=1,null;{this.querySet.delete(t),this.queryIdToToken.delete(e.id),this.outstandingQueriesOlderThanRestart.delete(e.id);let r=this.querySetVersion,s=this.querySetVersion+1,o={type:"Remove",queryId:e.id};return this.paused?this.pendingQuerySetModifications.has(e.id)?this.pendingQuerySetModifications.delete(e.id):this.pendingQuerySetModifications.set(e.id,o):this.querySetVersion=s,{type:"ModifyQuerySet",baseVersion:r,newVersion:s,modifications:[o]}}}};var Yn=Object.defineProperty,Zn=(n,t,e)=>t in n?Yn(n,t,{enumerable:!0,configurable:!0,writable:!0,value:e}):n[t]=e,ze=(n,t,e)=>Zn(n,typeof t!="symbol"?t+"":t,e),Ye=class{constructor(t,e){this.logger=t,this.markConnectionStateDirty=e,ze(this,"inflightRequests"),ze(this,"requestsOlderThanRestart"),ze(this,"inflightMutationsCount",0),ze(this,"inflightActionsCount",0),this.inflightRequests=new Map,this.requestsOlderThanRestart=new Set}request(t,e){let r=new Promise(s=>{let o=e?"Requested":"NotSent";this.inflightRequests.set(t.requestId,{message:t,status:{status:o,requestedAt:new Date,onResult:s}}),t.type==="Mutation"?this.inflightMutationsCount++:t.type==="Action"&&this.inflightActionsCount++});return this.markConnectionStateDirty(),r}onResponse(t){let e=this.inflightRequests.get(t.requestId);if(e===void 0||e.status.status==="Completed")return null;let r=e.message.type==="Mutation"?"mutation":"action",s=e.message.udfPath;for(let c of t.logLines)ae(this.logger,"info",r,s,c);let o=e.status,i,a;if(t.success)i={success:!0,logLines:t.logLines,value:x(t.result)},a=()=>o.onResult(i);else{let c=t.result,{errorData:l}=t;ae(this.logger,"error",r,s,c),i={success:!1,errorMessage:c,errorData:l!==void 0?x(l):void 0,logLines:t.logLines},a=()=>o.onResult(i)}return t.type==="ActionResponse"||!t.success?(a(),this.inflightRequests.delete(t.requestId),this.requestsOlderThanRestart.delete(t.requestId),e.message.type==="Action"?this.inflightActionsCount--:e.message.type==="Mutation"&&this.inflightMutationsCount--,this.markConnectionStateDirty(),{requestId:t.requestId,result:i}):(e.status={status:"Completed",result:i,ts:t.ts,onResolve:a},null)}removeCompleted(t){let e=new Map;for(let[r,s]of this.inflightRequests.entries()){let o=s.status;o.status==="Completed"&&o.ts.lessThanOrEqual(t)&&(o.onResolve(),e.set(r,o.result),s.message.type==="Mutation"?this.inflightMutationsCount--:s.message.type==="Action"&&this.inflightActionsCount--,this.inflightRequests.delete(r),this.requestsOlderThanRestart.delete(r))}return e.size>0&&this.markConnectionStateDirty(),e}restart(){this.requestsOlderThanRestart=new Set(this.inflightRequests.keys());let t=[];for(let[e,r]of this.inflightRequests){if(r.status.status==="NotSent"){r.status.status="Requested",t.push(r.message);continue}if(r.message.type==="Mutation")t.push(r.message);else if(r.message.type==="Action"){if(this.inflightRequests.delete(e),this.requestsOlderThanRestart.delete(e),this.inflightActionsCount--,r.status.status==="Completed")throw new Error("Action should never be in 'Completed' state");r.status.onResult({success:!1,errorMessage:"Connection lost while action was in flight",logLines:[]})}}return this.markConnectionStateDirty(),t}resume(){let t=[];for(let[,e]of this.inflightRequests)if(e.status.status==="NotSent"){e.status.status="Requested",t.push(e.message);continue}return t}hasIncompleteRequests(){for(let t of this.inflightRequests.values())if(t.status.status==="Requested")return!0;return!1}hasInflightRequests(){return this.inflightRequests.size>0}hasSyncedPastLastReconnect(){return this.requestsOlderThanRestart.size===0}timeOfOldestInflightRequest(){if(this.inflightRequests.size===0)return null;let t=Date.now();for(let e of this.inflightRequests.values())e.status.status!=="Completed"&&e.status.requestedAt.getTime()<t&&(t=e.status.requestedAt.getTime());return new Date(t)}inflightMutations(){return this.inflightMutationsCount}inflightActions(){return this.inflightActionsCount}};var fe=Symbol.for("functionName");var Ir=Symbol.for("toReferencePath");function Xn(n){return n[Ir]??null}function es(n){return n.startsWith("function://")}function Y(n){let t;if(typeof n=="string")es(n)?t={functionHandle:n}:t={name:n};else if(n[fe])t={name:n[fe]};else{let e=Xn(n);if(!e)throw new Error(`${n} is not a functionReference`);t={reference:e}}return t}function L(n){let t=Y(n);if(t.name===void 0)throw t.functionHandle!==void 0?new Error(`Expected function reference like "api.file.func" or "internal.file.func", but received function handle ${t.functionHandle}`):t.reference!==void 0?new Error(`Expected function reference in the current component like "api.file.func" or "internal.file.func", but received reference ${t.reference}`):new Error(`Expected function reference like "api.file.func" or "internal.file.func", but received ${JSON.stringify(t)}`);if(typeof n=="string")return n;let e=n[fe];if(!e)throw new Error(`${n} is not a functionReference`);return e}function Pr(n=[]){let t={get(e,r){if(typeof r=="string"){let s=[...n,r];return Pr(s)}else if(r===fe){if(n.length<2){let i=["api",...n].join(".");throw new Error(`API path is expected to be of the form \`api.moduleName.functionName\`. Found: \`${i}\``)}let s=n.slice(0,-1).join("/"),o=n[n.length-1];return o==="default"?s:s+":"+o}else return r===Symbol.toStringTag?"FunctionReference":void 0}};return new Proxy({},t)}var jt=Pr();var ts=Object.defineProperty,rs=(n,t,e)=>t in n?ts(n,t,{enumerable:!0,configurable:!0,writable:!0,value:e}):n[t]=e,Ze=(n,t,e)=>rs(n,typeof t!="symbol"?t+"":t,e),Xe=class n{constructor(t){Ze(this,"queryResults"),Ze(this,"modifiedQueries"),this.queryResults=t,this.modifiedQueries=[]}getQuery(t,...e){let r=R(e[0]),s=L(t),o=this.queryResults.get(B(s,r));if(o!==void 0)return n.queryValue(o.result)}getAllQueries(t){let e=[],r=L(t);for(let s of this.queryResults.values())s.udfPath===q(r)&&e.push({args:s.args,value:n.queryValue(s.result)});return e}setQuery(t,e,r){let s=R(e),o=L(t),i=B(o,s),a;r===void 0?a=void 0:a={success:!0,value:r,logLines:[]};let c={udfPath:o,args:s,result:a};this.queryResults.set(i,c),this.modifiedQueries.push(i)}static queryValue(t){if(t!==void 0)return t.success?t.value:void 0}},et=class{constructor(){Ze(this,"queryResults"),Ze(this,"optimisticUpdates"),this.queryResults=new Map,this.optimisticUpdates=[]}ingestQueryResultsFromServer(t,e){this.optimisticUpdates=this.optimisticUpdates.filter(i=>!e.has(i.mutationId));let r=this.queryResults;this.queryResults=new Map(t);let s=new Xe(this.queryResults);for(let i of this.optimisticUpdates)i.update(s);let o=[];for(let[i,a]of this.queryResults){let c=r.get(i);(c===void 0||c.result!==a.result)&&o.push(i)}return o}applyOptimisticUpdate(t,e){this.optimisticUpdates.push({update:t,mutationId:e});let r=new Xe(this.queryResults);return t(r),r.modifiedQueries}rawQueryResult(t){let e=this.queryResults.get(t);if(e!==void 0)return e.result}queryResult(t){let e=this.queryResults.get(t);if(e===void 0)return;let r=e.result;if(r!==void 0){if(r.success)return r.value;throw r.errorData!==void 0?Se(r,new H(z("query",e.udfPath,r))):new Error(z("query",e.udfPath,r))}}hasQueryResult(t){return this.queryResults.get(t)!==void 0}queryLogs(t){return this.queryResults.get(t)?.result?.logLines}};var ns=Object.defineProperty,ss=(n,t,e)=>t in n?ns(n,t,{enumerable:!0,configurable:!0,writable:!0,value:e}):n[t]=e,Jt=(n,t,e)=>ss(n,typeof t!="symbol"?t+"":t,e),V=class n{constructor(t,e){Jt(this,"low"),Jt(this,"high"),Jt(this,"__isUnsignedLong__"),this.low=t|0,this.high=e|0,this.__isUnsignedLong__=!0}static isLong(t){return(t&&t.__isUnsignedLong__)===!0}static fromBytesLE(t){return new n(t[0]|t[1]<<8|t[2]<<16|t[3]<<24,t[4]|t[5]<<8|t[6]<<16|t[7]<<24)}toBytesLE(){let t=this.high,e=this.low;return[e&255,e>>>8&255,e>>>16&255,e>>>24,t&255,t>>>8&255,t>>>16&255,t>>>24]}static fromNumber(t){return isNaN(t)||t<0?Tr:t>=is?os:new n(t%Ce|0,t/Ce|0)}toString(){return(BigInt(this.high)*BigInt(Ce)+BigInt(this.low)).toString()}equals(t){return n.isLong(t)||(t=n.fromValue(t)),this.high>>>31===1&&t.high>>>31===1?!1:this.high===t.high&&this.low===t.low}notEquals(t){return!this.equals(t)}comp(t){return n.isLong(t)||(t=n.fromValue(t)),this.equals(t)?0:t.high>>>0>this.high>>>0||t.high===this.high&&t.low>>>0>this.low>>>0?-1:1}lessThanOrEqual(t){return this.comp(t)<=0}static fromValue(t){return typeof t=="number"?n.fromNumber(t):new n(t.low,t.high)}},Tr=new V(0,0),Ar=65536,Ce=Ar*Ar,is=Ce*Ce,os=new V(-1,-1);var as=Object.defineProperty,cs=(n,t,e)=>t in n?as(n,t,{enumerable:!0,configurable:!0,writable:!0,value:e}):n[t]=e,tt=(n,t,e)=>cs(n,typeof t!="symbol"?t+"":t,e),Ie=class{constructor(t,e){tt(this,"version"),tt(this,"remoteQuerySet"),tt(this,"queryPath"),tt(this,"logger"),this.version={querySet:0,ts:V.fromNumber(0),identity:0},this.remoteQuerySet=new Map,this.queryPath=t,this.logger=e}transition(t){let e=t.startVersion;if(this.version.querySet!==e.querySet||this.version.ts.notEquals(e.ts)||this.version.identity!==e.identity)throw new Error(`Invalid start version: ${e.ts.toString()}:${e.querySet}:${e.identity}, transitioning from ${this.version.ts.toString()}:${this.version.querySet}:${this.version.identity}`);for(let r of t.modifications)switch(r.type){case"QueryUpdated":{let s=this.queryPath(r.queryId);if(s)for(let i of r.logLines)ae(this.logger,"info","query",s,i);let o=x(r.value??null);this.remoteQuerySet.set(r.queryId,{success:!0,value:o,logLines:r.logLines});break}case"QueryFailed":{let s=this.queryPath(r.queryId);if(s)for(let i of r.logLines)ae(this.logger,"info","query",s,i);let{errorData:o}=r;this.remoteQuerySet.set(r.queryId,{success:!1,errorMessage:r.errorMessage,errorData:o!==void 0?x(o):void 0,logLines:r.logLines});break}case"QueryRemoved":{this.remoteQuerySet.delete(r.queryId);break}default:throw new Error(`Invalid modification ${r.type}`)}this.version=t.endVersion}remoteQueryResults(){return this.remoteQuerySet}timestamp(){return this.version.ts}};function Kt(n){let t=de.toByteArray(n);return V.fromBytesLE(Array.from(t))}function us(n){let t=new Uint8Array(n.toBytesLE());return de.fromByteArray(t)}function zt(n){switch(n.type){case"FatalError":case"AuthError":case"ActionResponse":case"TransitionChunk":case"Ping":return{...n};case"MutationResponse":return n.success?{...n,ts:Kt(n.ts)}:{...n};case"Transition":return{...n,startVersion:{...n.startVersion,ts:Kt(n.startVersion.ts)},endVersion:{...n.endVersion,ts:Kt(n.endVersion.ts)}};default:}}function Mr(n){switch(n.type){case"Authenticate":case"ModifyQuerySet":case"Mutation":case"Action":case"Event":return{...n};case"Connect":return n.maxObservedTimestamp!==void 0?{...n,maxObservedTimestamp:us(n.maxObservedTimestamp)}:{...n,maxObservedTimestamp:void 0};default:}}var ls=Object.defineProperty,ds=(n,t,e)=>t in n?ls(n,t,{enumerable:!0,configurable:!0,writable:!0,value:e}):n[t]=e,I=(n,t,e)=>ds(n,typeof t!="symbol"?t+"":t,e),hs=1e3,fs=1001,ps=1005,gs=4040,rt;function pe(){return rt===void 0&&(rt=Date.now()),typeof performance>"u"||!performance.now?Date.now():Math.round(rt+performance.now())}function xr(){return`t=${Math.round((pe()-rt)/100)/10}s`}var Rr={InternalServerError:{timeout:1e3},SubscriptionsWorkerFullError:{timeout:3e3},TooManyConcurrentRequests:{timeout:3e3},CommitterFullError:{timeout:3e3},AwsTooManyRequestsException:{timeout:3e3},ExecuteFullError:{timeout:3e3},SystemTimeoutError:{timeout:3e3},ExpiredInQueue:{timeout:3e3},VectorIndexesUnavailable:{timeout:1e3},SearchIndexesUnavailable:{timeout:1e3},TableSummariesUnavailable:{timeout:1e3},VectorIndexTooLarge:{timeout:3e3},SearchIndexTooLarge:{timeout:3e3},TooManyWritesInTimePeriod:{timeout:3e3}};function ms(n){if(n===void 0)return"Unknown";for(let t of Object.keys(Rr))if(n.startsWith(t))return t;return"Unknown"}var nt=class{constructor(t,e,r,s,o,i){this.markConnectionStateDirty=o,this.debug=i,I(this,"socket"),I(this,"connectionCount"),I(this,"_hasEverConnected",!1),I(this,"lastCloseReason"),I(this,"transitionChunkBuffer",null),I(this,"defaultInitialBackoff"),I(this,"maxBackoff"),I(this,"retries"),I(this,"serverInactivityThreshold"),I(this,"reconnectDueToServerInactivityTimeout"),I(this,"scheduledReconnect",null),I(this,"networkOnlineHandler",null),I(this,"pendingNetworkRecoveryInfo",null),I(this,"uri"),I(this,"onOpen"),I(this,"onResume"),I(this,"onMessage"),I(this,"webSocketConstructor"),I(this,"logger"),I(this,"onServerDisconnectError"),this.webSocketConstructor=r,this.socket={state:"disconnected"},this.connectionCount=0,this.lastCloseReason="InitialConnect",this.defaultInitialBackoff=1e3,this.maxBackoff=16e3,this.retries=0,this.serverInactivityThreshold=6e4,this.reconnectDueToServerInactivityTimeout=null,this.uri=t,this.onOpen=e.onOpen,this.onResume=e.onResume,this.onMessage=e.onMessage,this.onServerDisconnectError=e.onServerDisconnectError,this.logger=s,this.setupNetworkListener(),this.connect()}setSocketState(t){this.socket=t,this._logVerbose(`socket state changed: ${this.socket.state}, paused: ${"paused"in this.socket?this.socket.paused:void 0}`),this.markConnectionStateDirty()}setupNetworkListener(){typeof window>"u"||typeof window.addEventListener!="function"||this.networkOnlineHandler===null&&(this.networkOnlineHandler=()=>{this._logVerbose("network online event detected"),this.tryReconnectImmediately()},window.addEventListener("online",this.networkOnlineHandler),this._logVerbose("network online event listener registered"))}cleanupNetworkListener(){this.networkOnlineHandler&&typeof window<"u"&&typeof window.removeEventListener=="function"&&(window.removeEventListener("online",this.networkOnlineHandler),this.networkOnlineHandler=null,this._logVerbose("network online event listener removed"))}assembleTransition(t){if(t.partNumber<0||t.partNumber>=t.totalParts||t.totalParts===0||this.transitionChunkBuffer&&(this.transitionChunkBuffer.totalParts!==t.totalParts||this.transitionChunkBuffer.transitionId!==t.transitionId))throw this.transitionChunkBuffer=null,new Error("Invalid TransitionChunk");if(this.transitionChunkBuffer===null&&(this.transitionChunkBuffer={chunks:[],totalParts:t.totalParts,transitionId:t.transitionId}),t.partNumber!==this.transitionChunkBuffer.chunks.length){let e=this.transitionChunkBuffer.chunks.length;throw this.transitionChunkBuffer=null,new Error(`TransitionChunk received out of order: expected part ${e}, got ${t.partNumber}`)}if(this.transitionChunkBuffer.chunks.push(t.chunk),this.transitionChunkBuffer.chunks.length===t.totalParts){let e=this.transitionChunkBuffer.chunks.join("");this.transitionChunkBuffer=null;let r=zt(JSON.parse(e));if(r.type!=="Transition")throw new Error(`Expected Transition, got ${r.type} after assembling chunks`);return r}return null}connect(){if(this.socket.state==="terminated")return;if(this.socket.state!=="disconnected"&&this.socket.state!=="stopped")throw new Error("Didn't start connection from disconnected state: "+this.socket.state);let t=new this.webSocketConstructor(this.uri);this._logVerbose("constructed WebSocket"),this.setSocketState({state:"connecting",ws:t,paused:"no"}),this.resetServerInactivityTimeout(),t.onopen=()=>{if(this.logger.logVerbose("begin ws.onopen"),this.socket.state!=="connecting")throw new Error("onopen called with socket not in connecting state");if(this.setSocketState({state:"ready",ws:t,paused:this.socket.paused==="yes"?"uninitialized":"no"}),this.resetServerInactivityTimeout(),this.socket.paused==="no"&&(this._hasEverConnected=!0,this.onOpen({connectionCount:this.connectionCount,lastCloseReason:this.lastCloseReason,clientTs:pe()})),this.lastCloseReason!=="InitialConnect"&&(this.lastCloseReason?this.logger.log("WebSocket reconnected at",xr(),"after disconnect due to",this.lastCloseReason):this.logger.log("WebSocket reconnected at",xr())),this.connectionCount+=1,this.lastCloseReason=null,this.pendingNetworkRecoveryInfo!==null){let{timeSavedMs:e}=this.pendingNetworkRecoveryInfo;this.pendingNetworkRecoveryInfo=null,this.sendMessage({type:"Event",eventType:"NetworkRecoveryReconnect",event:{timeSavedMs:e}}),this.logger.log(`Network recovery reconnect saved ~${Math.round(e/1e3)}s of waiting`)}},t.onerror=e=>{this.transitionChunkBuffer=null;let r=e.message;r&&this.logger.log(`WebSocket error message: ${r}`)},t.onmessage=e=>{this.resetServerInactivityTimeout();let r=e.data.length,s=zt(JSON.parse(e.data));if(this._logVerbose(`received ws message with type ${s.type}`),s.type==="Ping")return;if(s.type==="TransitionChunk"){let i=this.assembleTransition(s);if(!i)return;s=i,this._logVerbose(`assembled full ws message of type ${s.type}`)}this.transitionChunkBuffer!==null&&(this.transitionChunkBuffer=null,this.logger.log(`Received unexpected ${s.type} while buffering TransitionChunks`)),s.type==="Transition"&&this.reportLargeTransition({messageLength:r,transition:s}),this.onMessage(s).hasSyncedPastLastReconnect&&(this.retries=0,this.markConnectionStateDirty())},t.onclose=e=>{if(this._logVerbose("begin ws.onclose"),this.transitionChunkBuffer=null,this.lastCloseReason===null&&(this.lastCloseReason=e.reason||`closed with code ${e.code}`),e.code!==hs&&e.code!==fs&&e.code!==ps&&e.code!==gs){let s=`WebSocket closed with code ${e.code}`;e.reason&&(s+=`: ${e.reason}`),this.logger.log(s),this.onServerDisconnectError&&e.reason&&this.onServerDisconnectError(s)}let r=ms(e.reason);this.scheduleReconnect(r)}}socketState(){return this.socket.state}sendMessage(t){let e={type:t.type,...t.type==="Authenticate"&&t.tokenType==="User"?{value:`...${t.value.slice(-7)}`}:{}};if(this.socket.state==="ready"&&this.socket.paused==="no"){let r=Mr(t),s=JSON.stringify(r),o=!1;try{this.socket.ws.send(s),o=!0}catch(i){this.logger.log(`Failed to send message on WebSocket, reconnecting: ${i}`),this.closeAndReconnect("FailedToSendMessage")}return this._logVerbose(`${o?"sent":"failed to send"} message with type ${t.type}: ${JSON.stringify(e)}`),!0}return this._logVerbose(`message not sent (socket state: ${this.socket.state}, paused: ${"paused"in this.socket?this.socket.paused:void 0}): ${JSON.stringify(e)}`),!1}resetServerInactivityTimeout(){this.socket.state!=="terminated"&&(this.reconnectDueToServerInactivityTimeout!==null&&(clearTimeout(this.reconnectDueToServerInactivityTimeout),this.reconnectDueToServerInactivityTimeout=null),this.reconnectDueToServerInactivityTimeout=setTimeout(()=>{this.closeAndReconnect("InactiveServer")},this.serverInactivityThreshold))}scheduleReconnect(t){this.scheduledReconnect&&(clearTimeout(this.scheduledReconnect.timeout),this.scheduledReconnect=null),this.socket={state:"disconnected"};let e=this.nextBackoff(t);this.markConnectionStateDirty(),this.logger.log(`Attempting reconnect in ${Math.round(e)}ms`);let r=pe(),s=setTimeout(()=>{this.scheduledReconnect?.timeout===s&&(this.scheduledReconnect=null,this.connect())},e);this.scheduledReconnect={timeout:s,scheduledAt:r,backoffMs:e}}closeAndReconnect(t){switch(this._logVerbose(`begin closeAndReconnect with reason ${t}`),this.socket.state){case"disconnected":case"terminated":case"stopped":return;case"connecting":case"ready":{this.lastCloseReason=t,this.close(),this.scheduleReconnect("client");return}default:this.socket}}close(){switch(this.transitionChunkBuffer=null,this.socket.state){case"disconnected":case"terminated":case"stopped":return Promise.resolve();case"connecting":{let t=this.socket.ws;return t.onmessage=e=>{this._logVerbose("Ignoring message received after close")},new Promise(e=>{t.onclose=()=>{this._logVerbose("Closed after connecting"),e()},t.onopen=()=>{this._logVerbose("Opened after connecting"),t.close()}})}case"ready":{this._logVerbose("ws.close called");let t=this.socket.ws;t.onmessage=r=>{this._logVerbose("Ignoring message received after close")};let e=new Promise(r=>{t.onclose=()=>{r()}});return t.close(),e}default:return this.socket,Promise.resolve()}}terminate(){switch(this.reconnectDueToServerInactivityTimeout&&clearTimeout(this.reconnectDueToServerInactivityTimeout),this.scheduledReconnect&&(clearTimeout(this.scheduledReconnect.timeout),this.scheduledReconnect=null),this.cleanupNetworkListener(),this.socket.state){case"terminated":case"stopped":case"disconnected":case"connecting":case"ready":{let t=this.close();return this.setSocketState({state:"terminated"}),t}default:throw this.socket,new Error(`Invalid websocket state: ${this.socket.state}`)}}stop(){switch(this.socket.state){case"terminated":return Promise.resolve();case"connecting":case"stopped":case"disconnected":case"ready":{this.cleanupNetworkListener();let t=this.close();return this.socket={state:"stopped"},t}default:return this.socket,Promise.resolve()}}tryRestart(){switch(this.socket.state){case"stopped":break;case"terminated":case"connecting":case"ready":case"disconnected":this.logger.logVerbose("Restart called without stopping first");return;default:this.socket}this.setupNetworkListener(),this.connect()}pause(){switch(this.socket.state){case"disconnected":case"stopped":case"terminated":return;case"connecting":case"ready":{this.socket={...this.socket,paused:"yes"};return}default:{this.socket;return}}}tryReconnectImmediately(){if(this._logVerbose("tryReconnectImmediately called"),this.socket.state!=="disconnected"){this._logVerbose(`tryReconnectImmediately called but socket state is ${this.socket.state}, no action taken`);return}let t=null;if(this.scheduledReconnect){let e=pe()-this.scheduledReconnect.scheduledAt;t=Math.max(0,this.scheduledReconnect.backoffMs-e),this._logVerbose(`would have waited ${Math.round(t)}ms more (backoff was ${Math.round(this.scheduledReconnect.backoffMs)}ms, elapsed ${Math.round(e)}ms)`),clearTimeout(this.scheduledReconnect.timeout),this.scheduledReconnect=null,this._logVerbose("canceled scheduled reconnect")}this.logger.log("Network recovery detected, reconnecting immediately"),this.pendingNetworkRecoveryInfo=t!==null?{timeSavedMs:t}:null,this.connect()}resume(){switch(this.socket.state){case"connecting":this.socket={...this.socket,paused:"no"};return;case"ready":this.socket.paused==="uninitialized"?(this.socket={...this.socket,paused:"no"},this._hasEverConnected=!0,this.onOpen({connectionCount:this.connectionCount,lastCloseReason:this.lastCloseReason,clientTs:pe()})):this.socket.paused==="yes"&&(this.socket={...this.socket,paused:"no"},this.onResume());return;case"terminated":case"stopped":case"disconnected":return;default:this.socket}this.connect()}connectionState(){return{isConnected:this.socket.state==="ready",hasEverConnected:this._hasEverConnected,connectionCount:this.connectionCount,connectionRetries:this.retries}}_logVerbose(t){this.logger.logVerbose(t)}nextBackoff(t){let r=(t==="client"?100:t==="Unknown"?this.defaultInitialBackoff:Rr[t].timeout)*Math.pow(2,this.retries);this.retries+=1;let s=Math.min(r,this.maxBackoff),o=s*(Math.random()-.5);return s+o}reportLargeTransition({transition:t,messageLength:e}){if(t.clientClockSkew===void 0||t.serverTs===void 0)return;let r=pe()-t.clientClockSkew-t.serverTs/1e6,s=`${Math.round(r)}ms`,o=`${Math.round(e/1e4)/100}MB`,i=e/(r/1e3),a=`${Math.round(i/1e4)/100}MB per second`;this._logVerbose(`received ${o} transition in ${s} at ${a}`),e>2e7?this.logger.log(`received query results totaling more that 20MB (${o}) which will take a long time to download on slower connections`):r>2e4&&this.logger.log(`received query results totaling ${o} which took more than 20s to arrive (${s})`),this.debug&&this.sendMessage({type:"Event",eventType:"ClientReceivedTransition",event:{transitionTransitTime:r,messageLength:e}})}};function _r(){return ys()}function ys(){return"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,n=>{let t=Math.random()*16|0;return(n==="x"?t:t&3|8).toString(16)})}var ce=class extends Error{};ce.prototype.name="InvalidTokenError";function bs(n){return decodeURIComponent(atob(n).replace(/(.)/g,(t,e)=>{let r=e.charCodeAt(0).toString(16).toUpperCase();return r.length<2&&(r="0"+r),"%"+r}))}function vs(n){let t=n.replace(/-/g,"+").replace(/_/g,"/");switch(t.length%4){case 0:break;case 2:t+="==";break;case 3:t+="=";break;default:throw new Error("base64 string is not of the correct length")}try{return bs(t)}catch{return atob(t)}}function st(n,t){if(typeof n!="string")throw new ce("Invalid token specified: must be a string");t||(t={});let e=t.header===!0?0:1,r=n.split(".")[e];if(typeof r!="string")throw new ce(`Invalid token specified: missing part #${e+1}`);let s;try{s=vs(r)}catch(o){throw new ce(`Invalid token specified: invalid base64 for part #${e+1} (${o.message})`)}try{return JSON.parse(s)}catch(o){throw new ce(`Invalid token specified: invalid json for part #${e+1} (${o.message})`)}}var ws=Object.defineProperty,Es=(n,t,e)=>t in n?ws(n,t,{enumerable:!0,configurable:!0,writable:!0,value:e}):n[t]=e,D=(n,t,e)=>Es(n,typeof t!="symbol"?t+"":t,e),Ss=480*60*60*1e3,Lr=2,it=class{constructor(t,e,r){D(this,"authState",{state:"noAuth"}),D(this,"configVersion",0),D(this,"syncState"),D(this,"authenticate"),D(this,"stopSocket"),D(this,"tryRestartSocket"),D(this,"pauseSocket"),D(this,"resumeSocket"),D(this,"clearAuth"),D(this,"logger"),D(this,"refreshTokenLeewaySeconds"),D(this,"tokenConfirmationAttempts",0),this.syncState=t,this.authenticate=e.authenticate,this.stopSocket=e.stopSocket,this.tryRestartSocket=e.tryRestartSocket,this.pauseSocket=e.pauseSocket,this.resumeSocket=e.resumeSocket,this.clearAuth=e.clearAuth,this.logger=r.logger,this.refreshTokenLeewaySeconds=r.refreshTokenLeewaySeconds}async setConfig(t,e){this.resetAuthState(),this._logVerbose("pausing WS for auth token fetch"),this.pauseSocket();let r=await this.fetchTokenAndGuardAgainstRace(t,{forceRefreshToken:!1});r.isFromOutdatedConfig||(r.value?(this.setAuthState({state:"waitingForServerConfirmationOfCachedToken",config:{fetchToken:t,onAuthChange:e},hasRetried:!1}),this.authenticate(r.value)):(this.setAuthState({state:"initialRefetch",config:{fetchToken:t,onAuthChange:e}}),await this.refetchToken()),this._logVerbose("resuming WS after auth token fetch"),this.resumeSocket())}onTransition(t){if(this.syncState.isCurrentOrNewerAuthVersion(t.endVersion.identity)&&!(t.endVersion.identity<=t.startVersion.identity)){if(this._logVerbose(`auth state is ${this.authState.state} when handling transition`),this.syncState.markAuthCompletion(),this.authState.state==="waitingForServerConfirmationOfCachedToken"){this._logVerbose("server confirmed auth token is valid"),this.refetchToken(),this.authState.config.onAuthChange(!0);return}this.authState.state==="waitingForServerConfirmationOfFreshToken"&&(this._logVerbose("server confirmed new auth token is valid"),this.scheduleTokenRefetch(this.authState.token),this.tokenConfirmationAttempts=0,this.authState.hadAuth||this.authState.config.onAuthChange(!0))}}onAuthError(t){if(t.authUpdateAttempted===!1&&(this.authState.state==="waitingForServerConfirmationOfFreshToken"||this.authState.state==="waitingForServerConfirmationOfCachedToken")){this._logVerbose("ignoring non-auth token expired error");return}let{baseVersion:e}=t;if(!this.syncState.isCurrentOrNewerAuthVersion(e+1)){this._logVerbose("ignoring auth error for previous auth attempt");return}this.tryToReauthenticate(t)}async tryToReauthenticate(t){if(this._logVerbose(`attempting to reauthenticate: ${t.error}`),this.authState.state==="noAuth"||this.authState.state==="waitingForServerConfirmationOfFreshToken"&&this.tokenConfirmationAttempts>=Lr){this.logger.error(`Failed to authenticate: "${t.error}", check your server auth config`),this.syncState.hasAuth()&&this.syncState.clearAuth(),this.authState.state!=="noAuth"&&this.setAndReportAuthFailed(this.authState.config.onAuthChange);return}this.authState.state==="waitingForServerConfirmationOfFreshToken"&&(this.tokenConfirmationAttempts++,this._logVerbose(`retrying reauthentication, ${Lr-this.tokenConfirmationAttempts} attempts remaining`)),await this.stopSocket();let e=await this.fetchTokenAndGuardAgainstRace(this.authState.config.fetchToken,{forceRefreshToken:!0});e.isFromOutdatedConfig||(e.value&&this.syncState.isNewAuth(e.value)?(this.authenticate(e.value),this.setAuthState({state:"waitingForServerConfirmationOfFreshToken",config:this.authState.config,token:e.value,hadAuth:this.authState.state==="notRefetching"||this.authState.state==="waitingForScheduledRefetch"})):(this._logVerbose("reauthentication failed, could not fetch a new token"),this.syncState.hasAuth()&&this.syncState.clearAuth(),this.setAndReportAuthFailed(this.authState.config.onAuthChange)),this.tryRestartSocket())}async refetchToken(){if(this.authState.state==="noAuth")return;this._logVerbose("refetching auth token");let t=await this.fetchTokenAndGuardAgainstRace(this.authState.config.fetchToken,{forceRefreshToken:!0});t.isFromOutdatedConfig||(t.value?this.syncState.isNewAuth(t.value)?(this.setAuthState({state:"waitingForServerConfirmationOfFreshToken",hadAuth:this.syncState.hasAuth(),token:t.value,config:this.authState.config}),this.authenticate(t.value)):this.setAuthState({state:"notRefetching",config:this.authState.config}):(this._logVerbose("refetching token failed"),this.syncState.hasAuth()&&this.clearAuth(),this.setAndReportAuthFailed(this.authState.config.onAuthChange)),this._logVerbose("restarting WS after auth token fetch (if currently stopped)"),this.tryRestartSocket())}scheduleTokenRefetch(t){if(this.authState.state==="noAuth")return;let e=this.decodeToken(t);if(!e){this.logger.error("Auth token is not a valid JWT, cannot refetch the token");return}let{iat:r,exp:s}=e;if(!r||!s){this.logger.error("Auth token does not have required fields, cannot refetch the token");return}let o=s-r;if(o<=2){this.logger.error("Auth token does not live long enough, cannot refetch the token");return}let i=Math.min(Ss,(o-this.refreshTokenLeewaySeconds)*1e3);i<=0&&(this.logger.warn(`Refetching auth token immediately, configured leeway ${this.refreshTokenLeewaySeconds}s is larger than the token's lifetime ${o}s`),i=0);let a=setTimeout(()=>{this._logVerbose("running scheduled token refetch"),this.refetchToken()},i);this.setAuthState({state:"waitingForScheduledRefetch",refetchTokenTimeoutId:a,config:this.authState.config}),this._logVerbose(`scheduled preemptive auth token refetching in ${i}ms`)}async fetchTokenAndGuardAgainstRace(t,e){let r=++this.configVersion;this._logVerbose(`fetching token with config version ${r}`);let s=await t(e);return this.configVersion!==r?(this._logVerbose(`stale config version, expected ${r}, got ${this.configVersion}`),{isFromOutdatedConfig:!0}):{isFromOutdatedConfig:!1,value:s}}stop(){this.resetAuthState(),this.configVersion++,this._logVerbose(`config version bumped to ${this.configVersion}`)}setAndReportAuthFailed(t){t(!1),this.resetAuthState()}resetAuthState(){this.setAuthState({state:"noAuth"})}setAuthState(t){let e=t.state==="waitingForServerConfirmationOfFreshToken"?{hadAuth:t.hadAuth,state:t.state,token:`...${t.token.slice(-7)}`}:{state:t.state};switch(this._logVerbose(`setting auth state to ${JSON.stringify(e)}`),t.state){case"waitingForScheduledRefetch":case"notRefetching":case"noAuth":this.tokenConfirmationAttempts=0;break;case"waitingForServerConfirmationOfFreshToken":case"waitingForServerConfirmationOfCachedToken":case"initialRefetch":break;default:}this.authState.state==="waitingForScheduledRefetch"&&clearTimeout(this.authState.refetchTokenTimeoutId),this.authState=t}decodeToken(t){try{return st(t)}catch(e){return this._logVerbose(`Error decoding token: ${e instanceof Error?e.message:"Unknown error"}`),null}}_logVerbose(t){this.logger.logVerbose(`${t} [v${this.configVersion}]`)}};var Cs=["convexClientConstructed","convexWebSocketOpen","convexFirstMessageReceived"];function kr(n,t){let e={sessionId:t};typeof performance>"u"||!performance.mark||performance.mark(n,{detail:e})}function Is(n){let t=n.name.slice(6);return t=t.charAt(0).toLowerCase()+t.slice(1),{name:t,startTime:n.startTime}}function Or(n){if(typeof performance>"u"||!performance.getEntriesByName)return[];let t=[];for(let e of Cs){let r=performance.getEntriesByName(e).filter(s=>s.entryType==="mark").filter(s=>s.detail.sessionId===n);t.push(...r)}return t.map(Is)}var Ps=Object.defineProperty,Ts=(n,t,e)=>t in n?Ps(n,t,{enumerable:!0,configurable:!0,writable:!0,value:e}):n[t]=e,P=(n,t,e)=>Ts(n,typeof t!="symbol"?t+"":t,e),Pe=class{constructor(t,e,r){if(P(this,"address"),P(this,"state"),P(this,"requestManager"),P(this,"webSocketManager"),P(this,"authenticationManager"),P(this,"remoteQuerySet"),P(this,"optimisticQueryResults"),P(this,"_transitionHandlerCounter",0),P(this,"_nextRequestId"),P(this,"_onTransitionFns",new Map),P(this,"_sessionId"),P(this,"firstMessageReceived",!1),P(this,"debug"),P(this,"logger"),P(this,"maxObservedTimestamp"),P(this,"connectionStateSubscribers",new Map),P(this,"nextConnectionStateSubscriberId",0),P(this,"_lastPublishedConnectionState"),P(this,"markConnectionStateDirty",()=>{Promise.resolve().then(()=>{let h=this.connectionState();if(JSON.stringify(h)!==JSON.stringify(this._lastPublishedConnectionState)){this._lastPublishedConnectionState=h;for(let m of this.connectionStateSubscribers.values())m(h)}})}),P(this,"mark",h=>{this.debug&&kr(h,this.sessionId)}),typeof t=="object")throw new Error("Passing a ClientConfig object is no longer supported. Pass the URL of the Convex deployment as a string directly.");r?.skipConvexDeploymentUrlCheck!==!0&&be(t),r={...r};let s=r.authRefreshTokenLeewaySeconds??10,o=r.webSocketConstructor;if(!o&&typeof WebSocket>"u")throw new Error("No WebSocket global variable defined! To use Convex in an environment without WebSocket try the HTTP client: https://docs.convex.dev/api/classes/browser.ConvexHttpClient");o=o||WebSocket,this.debug=r.reportDebugInfoToConvex??!1,this.address=t,this.logger=r.logger===!1?Qt({verbose:r.verbose??!1}):r.logger!==!0&&r.logger?r.logger:Wt({verbose:r.verbose??!1});let i=t.search("://");if(i===-1)throw new Error("Provided address was not an absolute URL.");let a=t.substring(i+3),c=t.substring(0,i),l;if(c==="http")l="ws";else if(c==="https")l="wss";else throw new Error(`Unknown parent protocol ${c}`);let d=`${l}://${a}/api/${k}/sync`;this.state=new Ke,this.remoteQuerySet=new Ie(h=>this.state.queryPath(h),this.logger),this.requestManager=new Ye(this.logger,this.markConnectionStateDirty);let f=()=>{this.webSocketManager.pause(),this.state.pause()};this.authenticationManager=new it(this.state,{authenticate:h=>{let m=this.state.setAuth(h);return this.webSocketManager.sendMessage(m),m.baseVersion},stopSocket:()=>this.webSocketManager.stop(),tryRestartSocket:()=>this.webSocketManager.tryRestart(),pauseSocket:f,resumeSocket:()=>this.webSocketManager.resume(),clearAuth:()=>{this.clearAuth()}},{logger:this.logger,refreshTokenLeewaySeconds:s}),this.optimisticQueryResults=new et,this.addOnTransitionHandler(h=>{e(h.queries.map(m=>m.token))}),this._nextRequestId=0,this._sessionId=_r();let{unsavedChangesWarning:v}=r;if(typeof window>"u"||typeof window.addEventListener>"u"){if(v===!0)throw new Error("unsavedChangesWarning requested, but window.addEventListener not found! Remove {unsavedChangesWarning: true} from Convex client options.")}else v!==!1&&window.addEventListener("beforeunload",h=>{if(this.requestManager.hasIncompleteRequests()){h.preventDefault();let m="Are you sure you want to leave? Your changes may not be saved.";return(h||window.event).returnValue=m,m}});this.webSocketManager=new nt(d,{onOpen:h=>{this.mark("convexWebSocketOpen"),this.webSocketManager.sendMessage({...h,type:"Connect",sessionId:this._sessionId,maxObservedTimestamp:this.maxObservedTimestamp}),this.remoteQuerySet=new Ie(ue=>this.state.queryPath(ue),this.logger);let[m,N]=this.state.restart();N&&this.webSocketManager.sendMessage(N),this.webSocketManager.sendMessage(m);for(let ue of this.requestManager.restart())this.webSocketManager.sendMessage(ue)},onResume:()=>{let[h,m]=this.state.resume();m&&this.webSocketManager.sendMessage(m),h&&this.webSocketManager.sendMessage(h);for(let N of this.requestManager.resume())this.webSocketManager.sendMessage(N)},onMessage:h=>{switch(this.firstMessageReceived||(this.firstMessageReceived=!0,this.mark("convexFirstMessageReceived"),this.reportMarks()),h.type){case"Transition":{this.observedTimestamp(h.endVersion.ts),this.authenticationManager.onTransition(h),this.remoteQuerySet.transition(h),this.state.transition(h);let m=this.requestManager.removeCompleted(this.remoteQuerySet.timestamp());this.notifyOnQueryResultChanges(m);break}case"MutationResponse":{h.success&&this.observedTimestamp(h.ts);let m=this.requestManager.onResponse(h);m!==null&&this.notifyOnQueryResultChanges(new Map([[m.requestId,m.result]]));break}case"ActionResponse":{this.requestManager.onResponse(h);break}case"AuthError":{this.authenticationManager.onAuthError(h);break}case"FatalError":{let m=Sr(this.logger,h.error);throw this.webSocketManager.terminate(),m}default:}return{hasSyncedPastLastReconnect:this.hasSyncedPastLastReconnect()}},onServerDisconnectError:r.onServerDisconnectError},o,this.logger,this.markConnectionStateDirty,this.debug),this.mark("convexClientConstructed"),r.expectAuth&&f()}hasSyncedPastLastReconnect(){return this.requestManager.hasSyncedPastLastReconnect()&&this.state.hasSyncedPastLastReconnect()}observedTimestamp(t){(this.maxObservedTimestamp===void 0||this.maxObservedTimestamp.lessThanOrEqual(t))&&(this.maxObservedTimestamp=t)}getMaxObservedTimestamp(){return this.maxObservedTimestamp}notifyOnQueryResultChanges(t){let e=this.remoteQuerySet.remoteQueryResults(),r=new Map;for(let[o,i]of e){let a=this.state.queryToken(o);if(a!==null){let c={result:i,udfPath:this.state.queryPath(o),args:this.state.queryArgs(o)};r.set(a,c)}}let s=this.optimisticQueryResults.ingestQueryResultsFromServer(r,new Set(t.keys()));this.handleTransition({queries:s.map(o=>{let i=this.optimisticQueryResults.rawQueryResult(o);return{token:o,modification:{kind:"Updated",result:i}}}),reflectedMutations:Array.from(t).map(([o,i])=>({requestId:o,result:i})),timestamp:this.remoteQuerySet.timestamp()})}handleTransition(t){for(let e of this._onTransitionFns.values())e(t)}addOnTransitionHandler(t){let e=this._transitionHandlerCounter++;return this._onTransitionFns.set(e,t),()=>this._onTransitionFns.delete(e)}getCurrentAuthClaims(){let t=this.state.getAuth(),e={};if(t&&t.tokenType==="User")try{e=t?st(t.value):{}}catch{e={}}else return;return{token:t.value,decoded:e}}setAuth(t,e){this.authenticationManager.setConfig(t,e)}hasAuth(){return this.state.hasAuth()}setAdminAuth(t,e){let r=this.state.setAdminAuth(t,e);this.webSocketManager.sendMessage(r)}clearAuth(){let t=this.state.clearAuth();this.webSocketManager.sendMessage(t)}subscribe(t,e,r){let s=R(e),{modification:o,queryToken:i,unsubscribe:a}=this.state.subscribe(t,s,r?.journal,r?.componentPath);return o!==null&&this.webSocketManager.sendMessage(o),{queryToken:i,unsubscribe:()=>{let c=a();c&&this.webSocketManager.sendMessage(c)}}}localQueryResult(t,e){let r=R(e),s=B(t,r);return this.optimisticQueryResults.queryResult(s)}localQueryResultByToken(t){return this.optimisticQueryResults.queryResult(t)}hasLocalQueryResultByToken(t){return this.optimisticQueryResults.hasQueryResult(t)}localQueryLogs(t,e){let r=R(e),s=B(t,r);return this.optimisticQueryResults.queryLogs(s)}queryJournal(t,e){let r=R(e),s=B(t,r);return this.state.queryJournal(s)}connectionState(){let t=this.webSocketManager.connectionState();return{hasInflightRequests:this.requestManager.hasInflightRequests(),isWebSocketConnected:t.isConnected,hasEverConnected:t.hasEverConnected,connectionCount:t.connectionCount,connectionRetries:t.connectionRetries,timeOfOldestInflightRequest:this.requestManager.timeOfOldestInflightRequest(),inflightMutations:this.requestManager.inflightMutations(),inflightActions:this.requestManager.inflightActions()}}subscribeToConnectionState(t){let e=this.nextConnectionStateSubscriberId++;return this.connectionStateSubscribers.set(e,t),()=>{this.connectionStateSubscribers.delete(e)}}async mutation(t,e,r){let s=await this.mutationInternal(t,e,r);if(!s.success)throw s.errorData!==void 0?Se(s,new H(z("mutation",t,s))):new Error(z("mutation",t,s));return s.value}async mutationInternal(t,e,r,s){let{mutationPromise:o}=this.enqueueMutation(t,e,r,s);return o}enqueueMutation(t,e,r,s){let o=R(e);this.tryReportLongDisconnect();let i=this.nextRequestId;if(this._nextRequestId++,r!==void 0){let d=r.optimisticUpdate;if(d!==void 0){let f=m=>{d(m,o)instanceof Promise&&this.logger.warn("Optimistic update handler returned a Promise. Optimistic updates should be synchronous.")},h=this.optimisticQueryResults.applyOptimisticUpdate(f,i).map(m=>{let N=this.localQueryResultByToken(m);return{token:m,modification:{kind:"Updated",result:N===void 0?void 0:{success:!0,value:N,logLines:[]}}}});this.handleTransition({queries:h,reflectedMutations:[],timestamp:this.remoteQuerySet.timestamp()})}}let a={type:"Mutation",requestId:i,udfPath:t,componentPath:s,args:[A(o)]},c=this.webSocketManager.sendMessage(a),l=this.requestManager.request(a,c);return{requestId:i,mutationPromise:l}}async action(t,e){let r=await this.actionInternal(t,e);if(!r.success)throw r.errorData!==void 0?Se(r,new H(z("action",t,r))):new Error(z("action",t,r));return r.value}async actionInternal(t,e,r){let s=R(e),o=this.nextRequestId;this._nextRequestId++,this.tryReportLongDisconnect();let i={type:"Action",requestId:o,udfPath:t,componentPath:r,args:[A(s)]},a=this.webSocketManager.sendMessage(i);return this.requestManager.request(i,a)}async close(){return this.authenticationManager.stop(),this.webSocketManager.terminate()}get url(){return this.address}get nextRequestId(){return this._nextRequestId}get sessionId(){return this._sessionId}reportMarks(){if(this.debug){let t=Or(this.sessionId);this.webSocketManager.sendMessage({type:"Event",eventType:"ClientConnect",event:t})}}tryReportLongDisconnect(){if(!this.debug)return;let t=this.connectionState().timeOfOldestInflightRequest;if(t===null||Date.now()-t.getTime()<=60*1e3)return;let e=`${this.address}/api/debug_event`;fetch(e,{method:"POST",headers:{"Content-Type":"application/json","Convex-Client":`npm-${k}`},body:JSON.stringify({event:"LongWebsocketDisconnect"})}).then(r=>{r.ok||this.logger.warn("Analytics request failed with response:",r.body)}).catch(r=>{this.logger.warn("Analytics response failed with error:",r)})}};function ot(n){if(typeof n!="object"||n===null||!Array.isArray(n.page)||typeof n.isDone!="boolean"||typeof n.continueCursor!="string")throw new Error(`Not a valid paginated query result: ${n?.toString()}`);return n}var As=Object.defineProperty,Ms=(n,t,e)=>t in n?As(n,t,{enumerable:!0,configurable:!0,writable:!0,value:e}):n[t]=e,Dr=(n,t,e)=>Ms(n,typeof t!="symbol"?t+"":t,e),at=class{constructor(t,e){this.client=t,this.onTransition=e,Dr(this,"paginatedQuerySet",new Map),Dr(this,"lastTransitionTs"),this.lastTransitionTs=V.fromNumber(0),this.client.addOnTransitionHandler(r=>this.onBaseTransition(r))}subscribe(t,e,r){let s=q(t),o=Ht(s,e,r),i=()=>this.removePaginatedQuerySubscriber(o),a=this.paginatedQuerySet.get(o);return a?(a.numSubscribers+=1,{paginatedQueryToken:o,unsubscribe:i}):(this.paginatedQuerySet.set(o,{token:o,canonicalizedUdfPath:s,args:e,numSubscribers:1,options:{initialNumItems:r.initialNumItems},nextPageKey:0,pageKeys:[],pageKeyToQuery:new Map,ongoingSplits:new Map,skip:!1,id:r.id}),this.addPageToPaginatedQuery(o,null,r.initialNumItems),{paginatedQueryToken:o,unsubscribe:i})}localQueryResult(t,e,r){let s=q(t),o=Ht(s,e,r);return this.localQueryResultByToken(o)}localQueryResultByToken(t){let e=this.paginatedQuerySet.get(t);if(!e)return;let r=this.activePageQueryTokens(e);if(r.length===0)return{results:[],status:"LoadingFirstPage",loadMore:c=>this.loadMoreOfPaginatedQuery(t,c)};let s=[],o=!1,i=!1;for(let c of r){let l=this.client.localQueryResultByToken(c);if(l===void 0){o=!0,i=!1;continue}let d=ot(l);s=s.concat(d.page),i=!!d.isDone}let a;return o?a=s.length===0?"LoadingFirstPage":"LoadingMore":i?a="Exhausted":a="CanLoadMore",{results:s,status:a,loadMore:c=>this.loadMoreOfPaginatedQuery(t,c)}}onBaseTransition(t){let e=t.queries.map(i=>i.token),r=this.queriesContainingTokens(e),s=[];r.length>0&&(this.processPaginatedQuerySplits(r,i=>this.client.localQueryResultByToken(i)),s=r.map(i=>({token:i,modification:{kind:"Updated",result:this.localQueryResultByToken(i)}})));let o={...t,paginatedQueries:s};this.onTransition(o)}loadMoreOfPaginatedQuery(t,e){this.mustGetPaginatedQuery(t);let r=this.queryTokenForLastPageOfPaginatedQuery(t),s=this.client.localQueryResultByToken(r);if(!s)return!1;let o=ot(s);if(o.isDone)return!1;this.addPageToPaginatedQuery(t,o.continueCursor,e);let i={timestamp:this.lastTransitionTs,reflectedMutations:[],queries:[],paginatedQueries:[{token:t,modification:{kind:"Updated",result:this.localQueryResultByToken(t)}}]};return this.onTransition(i),!0}queriesContainingTokens(t){if(t.length===0)return[];let e=[],r=new Set(t);for(let[s,o]of this.paginatedQuerySet)for(let i of this.allQueryTokens(o))if(r.has(i)){e.push(s);break}return e}processPaginatedQuerySplits(t,e){for(let r of t){let s=this.mustGetPaginatedQuery(r),{ongoingSplits:o,pageKeyToQuery:i,pageKeys:a}=s;for(let[c,[l,d]]of o)e(i.get(l).queryToken)!==void 0&&e(i.get(d).queryToken)!==void 0&&this.completePaginatedQuerySplit(s,c,l,d);for(let c of a){if(o.has(c))continue;let l=i.get(c).queryToken,d=e(l);if(!d)continue;let f=ot(d);f.splitCursor&&(f.pageStatus==="SplitRecommended"||f.pageStatus==="SplitRequired"||f.page.length>s.options.initialNumItems*2)&&this.splitPaginatedQueryPage(s,c,f.splitCursor,f.continueCursor)}}}splitPaginatedQueryPage(t,e,r,s){let o=t.nextPageKey++,i=t.nextPageKey++,a={cursor:s,numItems:t.options.initialNumItems,id:t.id},c=this.client.subscribe(t.canonicalizedUdfPath,{...t.args,paginationOpts:{...a,cursor:null,endCursor:r}});t.pageKeyToQuery.set(o,c);let l=this.client.subscribe(t.canonicalizedUdfPath,{...t.args,paginationOpts:{...a,cursor:r,endCursor:s}});t.pageKeyToQuery.set(i,l),t.ongoingSplits.set(e,[o,i])}addPageToPaginatedQuery(t,e,r){let s=this.mustGetPaginatedQuery(t),o=s.nextPageKey++,i={cursor:e,numItems:r,id:s.id},a={...s.args,paginationOpts:i},c=this.client.subscribe(s.canonicalizedUdfPath,a);return s.pageKeys.push(o),s.pageKeyToQuery.set(o,c),c}removePaginatedQuerySubscriber(t){let e=this.paginatedQuerySet.get(t);if(e&&(e.numSubscribers-=1,!(e.numSubscribers>0))){for(let r of e.pageKeyToQuery.values())r.unsubscribe();this.paginatedQuerySet.delete(t)}}completePaginatedQuerySplit(t,e,r,s){let o=t.pageKeyToQuery.get(e);t.pageKeyToQuery.delete(e);let i=t.pageKeys.indexOf(e);t.pageKeys.splice(i,1,r,s),t.ongoingSplits.delete(e),o.unsubscribe()}activePageQueryTokens(t){return t.pageKeys.map(e=>t.pageKeyToQuery.get(e).queryToken)}allQueryTokens(t){return Array.from(t.pageKeyToQuery.values()).map(e=>e.queryToken)}queryTokenForLastPageOfPaginatedQuery(t){let e=this.mustGetPaginatedQuery(t),r=e.pageKeys[e.pageKeys.length-1];if(r===void 0)throw new Error(`No pages for paginated query ${t}`);return e.pageKeyToQuery.get(r).queryToken}mustGetPaginatedQuery(t){let e=this.paginatedQuerySet.get(t);if(!e)throw new Error("paginated query no longer exists for token "+t);return e}};var xs=Object.defineProperty,Rs=(n,t,e)=>t in n?xs(n,t,{enumerable:!0,configurable:!0,writable:!0,value:e}):n[t]=e,ge=(n,t,e)=>Rs(n,typeof t!="symbol"?t+"":t,e),Ur;var Te=class{constructor(t,e={}){ge(this,"listeners"),ge(this,"_client"),ge(this,"_paginatedClient"),ge(this,"callNewListenersWithCurrentValuesTimer"),ge(this,"_closed"),ge(this,"_disabled"),e.skipConvexDeploymentUrlCheck!==!0&&be(t);let{disabled:r,...s}=e;this._closed=!1,this._disabled=!!r,Ur&&!("webSocketConstructor"in s)&&typeof WebSocket>"u"&&(s.webSocketConstructor=Ur),typeof window>"u"&&!("unsavedChangesWarning"in s)&&(s.unsavedChangesWarning=!1),this.disabled||(this._client=new Pe(t,()=>{},s),this._paginatedClient=new at(this._client,o=>this._transition(o))),this.listeners=new Set}get closed(){return this._closed}get client(){if(this._client)return this._client;throw new Error("ConvexClient is disabled")}get paginatedClient(){if(this._paginatedClient)return this._paginatedClient;throw new Error("ConvexClient is disabled")}get disabled(){return this._disabled}onUpdate(t,e,r,s){if(this.disabled)return this.createDisabledUnsubscribe();let{queryToken:o,unsubscribe:i}=this.client.subscribe(L(t),e),a={queryToken:o,callback:r,onError:s,unsubscribe:i,hasEverRun:!1,query:t,args:e,paginationOptions:void 0};this.listeners.add(a),this.queryResultReady(o)&&this.callNewListenersWithCurrentValuesTimer===void 0&&(this.callNewListenersWithCurrentValuesTimer=setTimeout(()=>this.callNewListenersWithCurrentValues(),0));let c={unsubscribe:()=>{this.closed||(this.listeners.delete(a),i())},getCurrentValue:()=>this.client.localQueryResultByToken(o),getQueryLogs:()=>this.client.localQueryLogs(o)},l=c.unsubscribe;return Object.assign(l,c),l}onPaginatedUpdate_experimental(t,e,r,s,o){if(this.disabled)return this.createDisabledUnsubscribe();let i={initialNumItems:r.initialNumItems,id:-1},{paginatedQueryToken:a,unsubscribe:c}=this.paginatedClient.subscribe(L(t),e,i),l={queryToken:a,callback:s,onError:o,unsubscribe:c,hasEverRun:!1,query:t,args:e,paginationOptions:i};this.listeners.add(l),this.paginatedClient.localQueryResultByToken(a)&&this.callNewListenersWithCurrentValuesTimer===void 0&&(this.callNewListenersWithCurrentValuesTimer=setTimeout(()=>this.callNewListenersWithCurrentValues(),0));let d={unsubscribe:()=>{this.closed||(this.listeners.delete(l),c())},getCurrentValue:()=>this.paginatedClient.localQueryResult(L(t),e,i),getQueryLogs:()=>[]},f=d.unsubscribe;return Object.assign(f,d),f}callNewListenersWithCurrentValues(){this.callNewListenersWithCurrentValuesTimer=void 0,this._transition({queries:[],paginatedQueries:[]},!0)}queryResultReady(t){return this.client.hasLocalQueryResultByToken(t)}createDisabledUnsubscribe(){let t=(()=>{});return Object.assign(t,{unsubscribe:t,getCurrentValue:()=>{},getQueryLogs:()=>{}}),t}async close(){if(!this.disabled)return this.listeners.clear(),this._closed=!0,this._paginatedClient&&(this._paginatedClient=void 0),this.client.close()}getAuth(){if(!this.disabled)return this.client.getCurrentAuthClaims()}setAuth(t,e){this.disabled||this.client.setAuth(t,e??(()=>{}))}setAdminAuth(t,e){if(this.closed)throw new Error("ConvexClient has already been closed.");this.disabled||this.client.setAdminAuth(t,e)}_transition({queries:t,paginatedQueries:e},r=!1){let s=[...t.map(o=>o.token),...e.map(o=>o.token)];for(let o of this.listeners){let{callback:i,queryToken:a,onError:c,hasEverRun:l}=o,d=Cr(a),f=d?!!this.paginatedClient.localQueryResultByToken(a):this.client.hasLocalQueryResultByToken(a);if(s.includes(a)||r&&!l&&f){o.hasEverRun=!0;let v;try{d?v=this.paginatedClient.localQueryResultByToken(a):v=this.client.localQueryResultByToken(a)}catch(h){if(!(h instanceof Error))throw h;c?c(h,"Second argument to onUpdate onError is reserved for later use"):Promise.reject(h);continue}i(v,"Second argument to onUpdate callback is reserved for later use")}}}async mutation(t,e,r){if(this.disabled)throw new Error("ConvexClient is disabled");return await this.client.mutation(L(t),e,r)}async action(t,e){if(this.disabled)throw new Error("ConvexClient is disabled");return await this.client.action(L(t),e)}async query(t,e){if(this.disabled)throw new Error("ConvexClient is disabled");let r=this.client.localQueryResult(L(t),e);return r!==void 0?Promise.resolve(r):new Promise((s,o)=>{let{unsubscribe:i}=this.onUpdate(t,e,a=>{i(),s(a)},a=>{i(),o(a)})})}connectionState(){if(this.disabled)throw new Error("ConvexClient is disabled");return this.client.connectionState()}subscribeToConnectionState(t){return this.disabled?()=>{}:this.client.subscribeToConnectionState(t)}};var Zt={GODOT:"GODOT",UNITY:"UNITY",UNREAL:"UNREAL",JSDOS:"JSDOS",RUFFLE:"RUFFLE",RENPY:"RENPY",CUSTOM:"CUSTOM"},Fr=24,ca={MAX_PLAYERS:100,EXPIRY_HOURS:Fr,EXPIRY_MS:Fr*60*60*1e3},ct={PUBLIC:0,FRIENDS_ONLY:1,PRIVATE:2},ut=500,lt={ASC:0,DESC:1},dt={NUMERIC:0,TIME_SECONDS:1,TIME_MILLISECONDS:2,TIME_GAME_TICKS:3},Ae={SCREENSHOT:0,VIDEO:1,COMMUNITY:2,GAME_MANAGED:3,OTHER:4},Me={PUBLIC:0,PRIVATE:2};var ua={DEFAULT_LIMIT_BYTES:1024*1024*1024,UPLOADS_PER_MINUTE:30,UPLOADS_PER_HOUR:300},j={OFFER:"offer",ANSWER:"answer",ICE_CANDIDATE:"ice-candidate"};var E={PROGRESS_UPDATE:"ProgressUpdate",LOADING_COMPLETE:"LoadingComplete",TOGGLE_OVERLAY:"ToggleOverlay",TAKE_FOCUS:"TakeFocus",LOBBY_JOINED:"LobbyJoined",LOBBY_LEFT:"LobbyLeft",GET_LOBBY_INVITE_LINK:"GetLobbyInviteLink",GET_DEVICE_FINGERPRINT:"GetDeviceFingerprint",SET_FULLSCREEN:"SetFullscreen",TOGGLE_FULLSCREEN:"ToggleFullscreen",FULLSCREEN_CHANGED:"FullscreenChanged",SET_MUTE:"SetMute",TOGGLE_MUTE:"ToggleMute",MUTE_CHANGED:"MuteChanged",OVERLAY_CHANGED:"OverlayChanged",GAMEPLAY_JWT_READY:"GameplayJwtReady",END_SESSION:"EndSession",TRIGGER_PAYWALL:"TriggerPaywall"},Xt={EMBED_CONFIGURE:"embed.configure",EMBED_CONFIGURE_ACK:"embed.configure:ack",EMBED_CREDS_REQUEST:"embed.creds-request",EMBED_CREDS_RESPONSE:"embed.creds-response"};var xe={RedirectUrl:"rdurl",EntrypointParams:"entrypointparams",Entrypoint:"entrypoint",Engine:"engine",EngineVersion:"engineversion",PlayKey:"pk",SdkConfig:"sdkconfig",Caller:"caller"},Nr={Wavedash:"wavedash"},Yt=3e4,Re={CLIENT_INTERVAL_MS:Yt,CLIENT_REESTABLISH_THRESHOLD_MS:Yt*2.5,CLIENT_GRACE_MS:Yt/6};var nu=p.object({numItems:p.number(),cursor:p.union(p.string(),p.null()),endCursor:p.optional(p.union(p.string(),p.null())),id:p.optional(p.number()),maximumRowsRead:p.optional(p.number()),maximumBytesRead:p.optional(p.number())});var Os=Symbol("var.requestId"),Ds=Symbol("var.ip"),Us=Symbol("var.userAgent"),Fs=Symbol("var.now"),Ns={[Os]:"requestId",[Ds]:"ip",[Us]:"userAgent",[Fs]:"now"};var $s=Object.defineProperty,qs=(n,t,e)=>t in n?$s(n,t,{enumerable:!0,configurable:!0,writable:!0,value:e}):n[t]=e,Q=(n,t,e)=>qs(n,typeof t!="symbol"?t+"":t,e),ht=class{constructor(t){Q(this,"indexes"),Q(this,"stagedDbIndexes"),Q(this,"searchIndexes"),Q(this,"stagedSearchIndexes"),Q(this,"vectorIndexes"),Q(this,"stagedVectorIndexes"),Q(this,"validator"),this.indexes=[],this.stagedDbIndexes=[],this.searchIndexes=[],this.stagedSearchIndexes=[],this.vectorIndexes=[],this.stagedVectorIndexes=[],this.validator=t}" indexes"(){return this.indexes}index(t,e){return Array.isArray(e)?this.indexes.push({indexDescriptor:t,fields:e}):e.staged?this.stagedDbIndexes.push({indexDescriptor:t,fields:e.fields}):this.indexes.push({indexDescriptor:t,fields:e.fields}),this}searchIndex(t,e){return e.staged?this.stagedSearchIndexes.push({indexDescriptor:t,searchField:e.searchField,filterFields:e.filterFields||[]}):this.searchIndexes.push({indexDescriptor:t,searchField:e.searchField,filterFields:e.filterFields||[]}),this}vectorIndex(t,e){return e.staged?this.stagedVectorIndexes.push({indexDescriptor:t,vectorField:e.vectorField,dimensions:e.dimensions,filterFields:e.filterFields||[]}):this.vectorIndexes.push({indexDescriptor:t,vectorField:e.vectorField,dimensions:e.dimensions,filterFields:e.filterFields||[]}),this}self(){return this}export(){let t=this.validator.json;if(typeof t!="object")throw new Error("Invalid validator: please make sure that the parameter of `defineTable` is valid (see https://docs.convex.dev/database/schemas)");return{indexes:this.indexes,stagedDbIndexes:this.stagedDbIndexes,searchIndexes:this.searchIndexes,stagedSearchIndexes:this.stagedSearchIndexes,vectorIndexes:this.vectorIndexes,stagedVectorIndexes:this.stagedVectorIndexes,documentType:t}}};function tr(n){return Gt(n)?new ht(n):new ht(p.object(n))}var rr=class{constructor(t,e){Q(this,"tables"),Q(this,"strictTableNameTypes"),Q(this,"schemaValidation"),this.tables=t,this.schemaValidation=e?.schemaValidation===void 0?!0:e.schemaValidation}export(){return JSON.stringify({tables:Object.entries(this.tables).map(([t,e])=>{let{indexes:r,stagedDbIndexes:s,searchIndexes:o,stagedSearchIndexes:i,vectorIndexes:a,stagedVectorIndexes:c,documentType:l}=e.export();return{tableName:t,indexes:r,stagedDbIndexes:s,searchIndexes:o,stagedSearchIndexes:i,vectorIndexes:a,stagedVectorIndexes:c,documentType:l}}),schemaValidation:this.schemaValidation})}};function $r(n,t){return new rr(n,t)}var xu=$r({_scheduled_functions:tr({name:p.string(),args:p.array(p.any()),scheduledTime:p.float64(),completedTime:p.optional(p.float64()),state:p.union(p.object({kind:p.literal("pending")}),p.object({kind:p.literal("inProgress")}),p.object({kind:p.literal("success")}),p.object({kind:p.literal("failed"),error:p.string()}),p.object({kind:p.literal("canceled")}))}),_storage:tr({sha256:p.string(),size:p.float64(),contentType:p.optional(p.string())})});var g=jt;var me={KICKED:"KICKED",ERROR:"ERROR"},Le={JOINED:"JOINED",LEFT:"LEFT"},qr={QUEUE_FULL:"QUEUE_FULL",PAYLOAD_TOO_LARGE:"PAYLOAD_TOO_LARGE",INVALID_PAYLOAD_SIZE:"INVALID_PAYLOAD_SIZE",INVALID_CHANNEL:"INVALID_CHANNEL",MALFORMED:"MALFORMED",PEER_NOT_READY:"PEER_NOT_READY"},ft={SMALL:64,MEDIUM:128,LARGE:256};var b={LOBBY_MESSAGE:"LobbyMessage",LOBBY_JOINED:"LobbyJoined",LOBBY_KICKED:"LobbyKicked",LOBBY_USERS_UPDATED:"LobbyUsersUpdated",LOBBY_DATA_UPDATED:"LobbyDataUpdated",LOBBY_INVITE:"LobbyInvite",P2P_CONNECTION_ESTABLISHED:"P2PConnectionEstablished",P2P_CONNECTION_FAILED:"P2PConnectionFailed",P2P_PEER_DISCONNECTED:"P2PPeerDisconnected",P2P_PEER_RECONNECTING:"P2PPeerReconnecting",P2P_PEER_RECONNECTED:"P2PPeerReconnected",P2P_PACKET_DROPPED:"P2PPacketDropped",STATS_STORED:"StatsStored",BACKEND_CONNECTED:"BackendConnected",BACKEND_DISCONNECTED:"BackendDisconnected",BACKEND_RECONNECTING:"BackendReconnecting",FULLSCREEN_CHANGED:"FullscreenChanged",MUTE_CHANGED:"MuteChanged"};var w=class{constructor(t){this.sdk=t}destroy(){}};var pt=class extends w{constructor(e){super(e);this._isMuted=!1;this.frames=new Set;this.iframeBindings=new WeakMap;this.iframeLoadHandlers=new Map;this.boundIframes=new Set;this.handleMute=e=>{this._isMuted!==e.isMuted&&(this._isMuted=e.isMuted,this.frames.forEach(r=>r.applyMute(this._isMuted)),this.sdk.gameEventManager.notifyGame(b.MUTE_CHANGED,{isMuted:this._isMuted}))};typeof window<"u"&&this.attachWindow(window),this.sdk.iframeMessenger.addEventListener(E.MUTE_CHANGED,this.handleMute)}isMuted(){return this._isMuted}async requestMute(e){return(await this.sdk.iframeMessenger.requestFromParent(E.SET_MUTE,{muted:e})).success}async toggleMute(){return(await this.sdk.iframeMessenger.requestFromParent(E.TOGGLE_MUTE)).success}attachWindow(e){try{e.document}catch{return}let r=new gt(this,e);this.frames.add(r)}bindIframe(e){if(!this.boundIframes.has(e)){this.boundIframes.add(e);let r=()=>this.attachIframe(e);this.iframeLoadHandlers.set(e,r),e.addEventListener("load",r)}this.attachIframe(e)}unbindIframe(e){let r=this.iframeLoadHandlers.get(e);r&&(e.removeEventListener("load",r),this.iframeLoadHandlers.delete(e)),this.boundIframes.delete(e),this.teardownFrame(e)}attachIframe(e){let r=null,s=null;try{let a=e.contentWindow;a&&(s=a.document,r=a)}catch{}if(!r||!s){this.teardownFrame(e);return}let o=this.iframeBindings.get(e);if(o){if(o.doc===s)return;this.teardownFrame(e)}let i=new gt(this,r);this.frames.add(i),this.iframeBindings.set(e,{doc:s,shim:i}),this._isMuted&&i.applyMute(!0)}teardownFrame(e){let r=this.iframeBindings.get(e);r&&(this.frames.delete(r.shim),r.shim.uninstall(),this.iframeBindings.delete(e))}destroy(){this.sdk.iframeMessenger.removeEventListener(E.MUTE_CHANGED,this.handleMute),this.boundIframes.forEach(e=>{let r=this.iframeLoadHandlers.get(e);r&&e.removeEventListener("load",r)}),this.boundIframes.clear(),this.iframeLoadHandlers.clear(),this.frames.forEach(e=>e.uninstall()),this.frames.clear(),super.destroy()}},gt=class{constructor(t,e){this.contexts=new Map;this.elements=new nr;this.intendedMuted=new WeakMap;this.intendedUtteranceVolume=new WeakMap;this.boundChildren=new Set;this.originalAudioContext=null;this.originalWebKitAudioContext=null;this.originalAudio=null;this.originalMutedDescriptor=null;this.originalPlay=null;this.originalSpeak=null;this.originalUtteranceVolumeDescriptor=null;this.mutationObserver=null;this.manager=t,this.win=e,this.doc=e.document??null,this.installShims()}applyMute(t){let e=t?0:1;this.contexts.forEach((s,o)=>{let i=o.currentTime;s.gain.cancelScheduledValues(i),s.gain.setValueAtTime(s.gain.value,i),s.gain.linearRampToValueAtTime(e,i+.05)});let r=this.originalMutedDescriptor?.set;r&&this.elements.forEach(s=>{let o=this.intendedMuted.get(s)??!1;r.call(s,t?!0:o)})}bindChild(t){this.boundChildren.add(t),this.manager.bindIframe(t)}unbindChild(t){this.boundChildren.delete(t),this.manager.unbindIframe(t)}trackElement(t){if(this.intendedMuted.has(t))return;let e=this.originalMutedDescriptor?.get,r=this.originalMutedDescriptor?.set,s=e?e.call(t):t.muted;this.intendedMuted.set(t,s),this.elements.add(t),this.manager.isMuted()&&!s&&r&&r.call(t,!0)}installShims(){let t=this.win,e=this.doc;t.AudioContext&&(this.originalAudioContext=t.AudioContext,t.AudioContext=this.shimAudioContextClass(t.AudioContext));let r=t;if(r.webkitAudioContext&&(this.originalWebKitAudioContext=r.webkitAudioContext,r.webkitAudioContext=this.shimAudioContextClass(r.webkitAudioContext)),t.Audio){let i=t.Audio;this.originalAudio=i,(a=>{let c=function(l){let d=new i(l);return a.trackElement(d),d};c.prototype=i.prototype,t.Audio=c})(this)}if(e){let i=t.HTMLMediaElement,a=t.HTMLIFrameElement,c=t.HTMLElement;e.querySelectorAll("audio, video").forEach(l=>{this.trackElement(l)}),e.querySelectorAll("iframe").forEach(l=>{this.bindChild(l)}),this.mutationObserver=new t.MutationObserver(l=>{for(let d of l)d.addedNodes.forEach(f=>{if(f instanceof i)this.trackElement(f);else if(f instanceof a)this.bindChild(f);else if(f instanceof c){let v=f;v.querySelectorAll("audio, video").forEach(h=>{this.trackElement(h)}),v.querySelectorAll("iframe").forEach(h=>{this.bindChild(h)})}}),d.removedNodes.forEach(f=>{f instanceof a?this.unbindChild(f):f instanceof c&&f.querySelectorAll("iframe").forEach(v=>{this.unbindChild(v)})})}),this.mutationObserver.observe(e.documentElement,{childList:!0,subtree:!0})}this.originalMutedDescriptor=Object.getOwnPropertyDescriptor(t.HTMLMediaElement.prototype,"muted")??null;let s=this.originalMutedDescriptor;s?.get&&s?.set&&(i=>{Object.defineProperty(t.HTMLMediaElement.prototype,"muted",{configurable:!0,get(){let a=i.intendedMuted.get(this);return a!==void 0?a:s.get.call(this)},set(a){i.intendedMuted.set(this,a),i.elements.add(this),s.set.call(this,i.manager.isMuted()?!0:a)}})})(this);let o=t.HTMLMediaElement.prototype.play;this.originalPlay=o,(i=>{t.HTMLMediaElement.prototype.play=function(){return i.trackElement(this),o.call(this)}})(this),this.shimSpeechSynthesis()}shimSpeechSynthesis(){let t=this.win;if(!t.speechSynthesis||typeof t.SpeechSynthesisUtterance>"u")return;this.originalUtteranceVolumeDescriptor=Object.getOwnPropertyDescriptor(t.SpeechSynthesisUtterance.prototype,"volume")??null;let e=this.originalUtteranceVolumeDescriptor;e?.get&&e?.set&&(o=>{Object.defineProperty(t.SpeechSynthesisUtterance.prototype,"volume",{configurable:!0,get(){let i=o.intendedUtteranceVolume.get(this);return i!==void 0?i:e.get.call(this)},set(i){o.intendedUtteranceVolume.set(this,i),e.set.call(this,i)}})})(this);let r=t.speechSynthesis,s=r.speak;this.originalSpeak=s,(o=>{r.speak=function(i){if(o.manager.isMuted()){if(!o.intendedUtteranceVolume.has(i)){let a=e?.get?e.get.call(i):i.volume;o.intendedUtteranceVolume.set(i,a)}e?.set?e.set.call(i,0):i.volume=0}else{let a=o.intendedUtteranceVolume.get(i);a!==void 0&&(e?.set?e.set.call(i,a):i.volume=a,o.intendedUtteranceVolume.delete(i))}return s.call(r,i)}})(this)}shimAudioContextClass(t){return(e=>class extends t{constructor(r){super(r);let s=this.createGain();s.connect(this.destination),s.gain.setValueAtTime(e.manager.isMuted()?0:1,this.currentTime),Object.defineProperty(this,"destination",{configurable:!0,get(){return s}}),e.contexts.set(this,s)}close(){return e.contexts.delete(this),super.close()}})(this)}uninstall(){let t=this.win;try{this.mutationObserver&&(this.mutationObserver.disconnect(),this.mutationObserver=null)}catch{}this.boundChildren.forEach(r=>this.manager.unbindIframe(r)),this.boundChildren.clear();let e=r=>{try{r()}catch{}};e(()=>{this.originalAudioContext&&(t.AudioContext=this.originalAudioContext)}),e(()=>{let r=t;this.originalWebKitAudioContext&&r.webkitAudioContext&&(r.webkitAudioContext=this.originalWebKitAudioContext)}),e(()=>{this.originalAudio&&(t.Audio=this.originalAudio)}),e(()=>{this.originalSpeak&&t.speechSynthesis&&(t.speechSynthesis.speak=this.originalSpeak)}),e(()=>{this.originalUtteranceVolumeDescriptor&&typeof t.SpeechSynthesisUtterance<"u"&&Object.defineProperty(t.SpeechSynthesisUtterance.prototype,"volume",this.originalUtteranceVolumeDescriptor)}),e(()=>{this.originalPlay&&(t.HTMLMediaElement.prototype.play=this.originalPlay)}),e(()=>{this.originalMutedDescriptor&&Object.defineProperty(t.HTMLMediaElement.prototype,"muted",this.originalMutedDescriptor)}),this.contexts.clear(),this.elements.clear(),this.intendedMuted=new WeakMap,this.intendedUtteranceVolume=new WeakMap}},nr=class{constructor(){this.set=new Set}add(t){for(let e of this.set)if(e.deref()===t)return;this.set.add(new WeakRef(t))}forEach(t){for(let e of this.set){let r=e.deref();r===void 0?this.set.delete(e):t(r)}}clear(){this.set.clear()}};var Br="/userfs",Z="FILE_DATA";async function Gr(n,t){return new Promise((e,r)=>{let s=indexedDB.open(Br);s.onerror=()=>r(s.error),s.onupgradeneeded=o=>{let i=o.target.result;i.objectStoreNames.contains(Z)||i.createObjectStore(Z)},s.onsuccess=()=>{let o=s.result,i=o.transaction(Z,"readwrite"),a=i.objectStore(Z),c={contents:t,timestamp:Date.now(),mode:33206},l=a.put(c,n);l.onsuccess=()=>e(),l.onerror=()=>r(l.error),i.oncomplete=()=>o.close()}})}async function Vr(n){return new Promise((t,e)=>{let r=indexedDB.open(Br);r.onerror=()=>e(r.error),r.onupgradeneeded=s=>{let o=s.target.result;o.objectStoreNames.contains(Z)||o.createObjectStore(Z)},r.onsuccess=()=>{let s=r.result,o=s.transaction(Z,"readonly"),a=o.objectStore(Z).get(n);a.onsuccess=()=>t(a.result),a.onerror=()=>e(a.error),o.oncomplete=()=>s.close()}})}function Wr(n){if(n==null)throw new Error("File not found in IndexedDB");if("contents"in n&&n.contents!=null){let t=n.contents instanceof Uint8Array||n.contents instanceof Int8Array?n.contents:new Uint8Array(n.contents);return new Blob([t],{type:"application/octet-stream"})}if(n instanceof Blob)return n;if(n instanceof Uint8Array||n instanceof Int8Array)return new Blob([n],{type:"application/octet-stream"});if(n instanceof ArrayBuffer)return new Blob([n],{type:"application/octet-stream"});if("data"in n&&n.data instanceof ArrayBuffer)return new Blob([n.data],{type:"application/octet-stream"});if("blob"in n&&n.blob instanceof Blob)return n.blob;throw new Error("Unrecognized value shape from IndexedDB")}var X={DEBUG:0,INFO:1,WARN:2,ERROR:3},sr=class{constructor(t=X.WARN){this.logLevel=t}setLogLevel(t){this.logLevel=t}debug(t,...e){this.logLevel<=X.DEBUG&&console.log(`[WavedashJS] ${t}`,...e)}info(t,...e){this.logLevel<=X.INFO&&console.log(`[WavedashJS] ${t}`,...e)}warn(t,...e){this.logLevel<=X.WARN&&console.warn(`[WavedashJS] ${t}`,...e)}error(t,...e){this.logLevel<=X.ERROR&&console.error(`[WavedashJS] ${t}`,...e)}},u=new sr;var Qr="userfs",Hr="/idbfs/wavedash",mt=class extends w{constructor(t){super(t)}toRemoteKey(t){let e=this.sdk.engineInstance?.unityPersistentDataPath,r=e?t.replace(e,Hr):t,s=r.startsWith("/")?r.slice(1):r;return`${this.sdk.gameCloudId}/${Qr}/${this.sdk.wavedashUser.id}/${s}`}toLocalPath(t){let e=`${this.sdk.gameCloudId}/${Qr}/${this.sdk.wavedashUser.id}/`,r=t.startsWith(e)?"/"+t.slice(e.length):t,s=this.sdk.engineInstance?.unityPersistentDataPath;return s?r.replace(Hr,s):r}async uploadRemoteFile(t){let e=await this.sdk.convexClient.mutation(g.sdk.remoteFileStorage.getUploadUrl,{path:this.toRemoteKey(t)});if(!await this.upload(e,t))throw new Error(`Failed to upload file: ${t}`);return t}async deleteRemoteFile(t){let e=this.getRemoteStorageUrl(t),r=await this.sdk.ensureGameplayJwt(),s=await fetch(e,{method:"DELETE",headers:{Authorization:`Bearer ${r}`}});if(!s.ok){let o=`Failed to delete remote file ${t}: ${s.status} (${s.statusText})`;throw u.error(o),new Error(o)}return t}async downloadRemoteFile(t){let e=this.getRemoteStorageUrl(t);return await this.download(e,t),t}async remoteFileExists(t){let e=this.getRemoteStorageUrl(t),r=await this.sdk.ensureGameplayJwt(),s=await fetch(e,{method:"HEAD",headers:{Authorization:`Bearer ${r}`}});if(s.status===404)return!1;if(s.ok)return!0;throw new Error(`${s.status} (${s.statusText})`)}async listRemoteDirectory(t){let e=this.getRemoteStorageUrl(t)+"?list=true",r=await this.sdk.ensureGameplayJwt(),s=await fetch(e,{method:"GET",headers:{Authorization:`Bearer ${r}`}});if(s.status===404)return[];if(!s.ok)throw new Error(`${s.status} (${s.statusText})`);return(await s.json()).files.filter(i=>!i.key.endsWith("/")).map(i=>({...i,key:this.toLocalPath(i.key)}))}async downloadRemoteDirectory(t){let r=(await this.listRemoteDirectory(t)).map(async i=>{let a=this.getRemoteStorageUrl(i.key);try{return await this.download(a,i.key),{fileName:i.name,success:!0}}catch(c){let l=c instanceof Error?c.message:String(c);return u.error(`Failed to download ${i.name}: ${l}`),{fileName:i.name,success:!1}}}),o=(await Promise.all(r)).filter(i=>!i.success);if(o.length>0)throw new Error(`Failed to download ${o.length} files: ${o.map(i=>i.fileName).join(", ")}`);return t}async writeLocalFile(t,e){if(u.debug(`Writing local file: ${t}`),this.sdk.engineInstance?.FS)return u.error(`${this.sdk.engineInstance.type} engine detected, use engine's builtin file access to save files.`),!1;try{return await Gr(t,e),!0}catch(r){return u.error(`Failed to write local file: ${r}`),!1}}async readLocalFile(t){if(u.debug(`Reading local file: ${t}`),this.sdk.engineInstance?.FS)return u.error(`${this.sdk.engineInstance.type} engine detected, use engine's builtin file access to read files.`),null;try{let e=await this.readLocalFileBlob(t);if(!e)return null;let r=await e.arrayBuffer();return new Uint8Array(r)}catch(e){return u.error(`Failed to read local file: ${e}`),null}}async upload(t,e){if(u.debug(`Uploading ${e} to: ${t}`),this.sdk.engineInstance&&!this.sdk.engineInstance.FS)return u.error("Engine instance is missing the Emscripten FS API"),!1;let r=!1;return this.sdk.engineInstance?r=await this.uploadFromFS(t,e):r=await this.uploadFromIndexedDb(t,e),r}async download(t,e){if(u.debug(`Downloading ${e} from: ${t}`),this.sdk.engineInstance&&!this.sdk.engineInstance.FS)throw new Error("Engine instance is missing the Emscripten FS API");let r=await this.sdk.ensureGameplayJwt(),s=await fetch(t,{method:"GET",headers:{Authorization:`Bearer ${r}`}});if(!s.ok)throw new Error(`${s.status} (${s.statusText})`);let i=await(await s.blob()).arrayBuffer(),a=new Uint8Array(i);if(this.sdk.engineInstance){let c=e.substring(0,e.lastIndexOf("/"));if(c)try{this.sdk.engineInstance.FS.mkdirTree(c)}catch{}try{this.sdk.engineInstance.FS.writeFile(e,a)}catch(l){let d=l instanceof Error?l.message:String(l);throw new Error(`Failed to save file ${e} to engine FS: ${d}`)}}else if(!await this.writeLocalFile(e,a))throw new Error(`Failed to save file ${e} to local IndexedDB storage`);u.debug(`Successfully saved to: ${e}`)}getRemoteStorageOrigin(){if(this.remoteStorageOrigin)return this.remoteStorageOrigin;if(this.sdk.config?.remoteStorageOrigin)return this.remoteStorageOrigin=this.sdk.config.remoteStorageOrigin,this.remoteStorageOrigin;if(this.sdk.ugcHost)return this.remoteStorageOrigin=this.sdk.ugcHost.startsWith("http")?this.sdk.ugcHost:`https://${this.sdk.ugcHost}`,this.remoteStorageOrigin;if(typeof window<"u"&&window.location){let e=window.location.hostname.split(".");return this.remoteStorageOrigin=`${window.location.protocol}//ugc.`+e.slice(2).join("."),this.remoteStorageOrigin}throw new Error("Remote storage origin cannot be determined.")}getRemoteStorageUrl(t){return`${this.getRemoteStorageOrigin()}/${this.toRemoteKey(t)}`}async uploadFromIndexedDb(t,e){try{let r=await this.readLocalFileBlob(e);return r?(await fetch(t,{method:"PUT",body:r})).ok:(u.error(`File not found in IndexedDB: ${e}`),!1)}catch(r){return u.error(`Error uploading from IndexedDB: ${r}`),!1}}async uploadFromFS(t,e){try{if(!this.sdk.engineInstance.FS.analyzePath(e).exists)throw new Error(`File not found in FS: ${e}`);let s=this.sdk.engineInstance.FS.readFile(e),o=new Blob([s],{type:"application/octet-stream"});return(await fetch(t,{method:"PUT",body:o})).ok}catch(r){let s=r instanceof Error?r.message:String(r);return u.error(`Error uploading from FS: ${s}`),!1}}async readLocalFileBlob(t){if(u.debug(`Reading local file (blob): ${t}`),this.sdk.engineInstance?.FS)return u.error(`${this.sdk.engineInstance.type} engine detected, use engine's builtin file access to read files.`),null;try{let e=await Vr(t);return e?Wr(e):null}catch(e){return u.error(`Failed to read local file blob: ${e}`),null}}};function jr(n,t,e){if(n.startsWith("http://")||n.startsWith("https://"))return n;let r=e?Object.entries(e).filter(([,s])=>s!==void 0).map(([s,o])=>s==="background"?`${s}=${encodeURIComponent(o)}`:`${s}=${o}`).join(","):"";return`https://${t}/cdn-cgi/image/${r}/${n}`}var yt=class extends w{constructor(e){super(e);this.userCache=new Map;this.leaderboardPageUserCache=new Map}getUserAvatarUrl(e,r=ft.MEDIUM){let s=this.userCache.get(e)??this.leaderboardPageUserCache.get(e);return s?.avatarR2Key?jr(s.avatarR2Key,this.sdk.uploadsHost,{width:r,height:r,fit:"cover",quality:"high",sharpen:1}):null}getUsername(e){return this.userCache.get(e)?.username??this.leaderboardPageUserCache.get(e)?.username??null}async listFriends(){let e=await this.sdk.convexClient.query(g.sdk.friends.listFriends,{});return this.cacheUsers(e),e}cacheUsers(e){for(let r of e)this.userCache.set(r.userId,{username:r.username,avatarR2Key:r.avatarUrl??r.userAvatarUrl})}cacheLeaderboardPage(e){this.leaderboardPageUserCache.clear();for(let r of e)this.leaderboardPageUserCache.set(r.userId,{username:r.username,avatarR2Key:r.userAvatarUrl})}};var bt=class extends w{constructor(e){super(e);this._isFullscreen=!1;this.listeners=new Set;this.sdk.iframeMessenger.addEventListener(E.FULLSCREEN_CHANGED,r=>{this.sdk.gameEventManager.notifyGame(b.FULLSCREEN_CHANGED,{isFullscreen:r.isFullscreen}),this.setState(r.isFullscreen)}),this.installCompatShims()}isFullscreen(){return this._isFullscreen}async requestFullscreen(e){return(await this.sdk.iframeMessenger.requestFromParent(E.SET_FULLSCREEN,{fullscreen:e})).success}async toggleFullscreen(){return(await this.sdk.iframeMessenger.requestFromParent(E.TOGGLE_FULLSCREEN)).success}subscribe(e){return this.listeners.add(e),()=>this.listeners.delete(e)}setState(e){if(this._isFullscreen!==e){this._isFullscreen=e;for(let r of this.listeners)r(e)}}installCompatShims(){if(typeof document>"u")return;let e=()=>this._isFullscreen?document.body:null;Object.defineProperty(document,"fullscreenElement",{configurable:!0,get:e}),Object.defineProperty(document,"webkitFullscreenElement",{configurable:!0,get:e});let r=async()=>{if(this._isFullscreen)return;if(!await this.requestFullscreen(!0))throw new Error("Fullscreen request was denied")},s=async()=>{if(!this._isFullscreen)return;if(!await this.requestFullscreen(!1))throw new Error("Exit fullscreen request was denied")};Element.prototype.requestFullscreen=function(){return r()},Element.prototype.webkitRequestFullscreen=function(){return r()},Document.prototype.exitFullscreen=function(){return s()},Document.prototype.webkitExitFullscreen=function(){return s()},this.subscribe(()=>{document.dispatchEvent(new Event("fullscreenchange",{bubbles:!0}))})}};var vt=class extends w{constructor(e){super(e);this.eventQueue=[]}notifyGame(e,r){if(!this.sdk.eventsReady){this.eventQueue.push({event:e,payload:r}),u.debug(`Queued event: ${e}`);return}this.sdk.engineInstance?this.sendGameEvent(e,r):this.sdk.dispatchEvent(new CustomEvent(e,{detail:r}))}sendGameEvent(e,r){let s=typeof r=="object"?JSON.stringify(r):r;this.sdk.engineInstance?.SendMessage?this.sdk.engineInstance.SendMessage(this.sdk.engineCallbackReceiver,e,s):u.error("Engine instance not set. Dropping event:",e)}flushEventQueue(){let e=this.eventQueue;this.eventQueue=[];for(let r of e)this.notifyGame(r.event,r.payload)}};var ee={passive:!0,capture:!0},wt=class extends w{constructor(e){super(e);this.deviceFingerprint=void 0;this.testConnectionInterval=null;this.heartbeatInterval=null;this.gamepadPollInterval=null;this.inactivityTimeout=null;this.isConnected=!1;this.sentDisconnectedEvent=!1;this.disconnectedAt=null;this.lastHeartbeatTime=0;this.lastInputResetAt=0;this.heartbeatInFlight=!1;this.isFirstTick=!0;this.TEST_CONNECTION_INTERVAL_MS=1e3;this.DISCONNECTED_TIMEOUT_MS=9e4;this.INACTIVITY_TIMEOUT_MS=1800*1e3;this.INPUT_THROTTLE_MS=1e3;this.GAMEPAD_POLL_INTERVAL_MS=1e3;this.GAMEPAD_AXIS_DEADZONE=.2;this.cachedPresenceData={};this.handleVisibilityChange=()=>{document.visibilityState==="visible"?this.start():this.stop()};this.handleUserInput=()=>{let e=Date.now();e-this.lastInputResetAt<this.INPUT_THROTTLE_MS||(this.lastInputResetAt=e,this.start())};this.isConnected=this.sdk.convexClient.client.connectionState().isWebSocketConnected,document.addEventListener("visibilitychange",this.handleVisibilityChange),window.addEventListener("keydown",this.handleUserInput,ee),window.addEventListener("pointerdown",this.handleUserInput,ee),window.addEventListener("pointermove",this.handleUserInput,ee),window.addEventListener("wheel",this.handleUserInput,ee),this.gamepadPollInterval=setInterval(()=>{this.pollGamepads()},this.GAMEPAD_POLL_INTERVAL_MS),this.deviceFingerprintReady=this.sdk.iframeMessenger.requestFromParent(E.GET_DEVICE_FINGERPRINT).then(r=>{this.deviceFingerprint=r}).catch(()=>{})}start(){this.sdk.gameLoaded&&document.visibilityState==="visible"&&(this.inactivityTimeout!==null&&clearTimeout(this.inactivityTimeout),this.inactivityTimeout=setTimeout(()=>{this.stop()},this.INACTIVITY_TIMEOUT_MS),this.heartbeatInterval===null&&(this.isFirstTick?this.deviceFingerprintReady.then(()=>{!this.sdk.gameLoaded||!this.isFirstTick||this.tickHeartbeat()}):this.tickHeartbeat(),this.heartbeatInterval=setInterval(()=>{this.tickHeartbeat()},Re.CLIENT_INTERVAL_MS),this.testConnectionInterval=setInterval(()=>{this.testConnection()},this.TEST_CONNECTION_INTERVAL_MS)))}stop(){this.inactivityTimeout!==null&&(clearTimeout(this.inactivityTimeout),this.inactivityTimeout=null),this.heartbeatInterval!==null&&(clearInterval(this.heartbeatInterval),this.heartbeatInterval=null),this.testConnectionInterval!==null&&(clearInterval(this.testConnectionInterval),this.testConnectionInterval=null)}async updateUserPresence(e){try{return this.cachedPresenceData=e,await this.sdk.convexClient.mutation(g.sdk.presence.heartbeat,{data:e,deviceFingerprint:this.deviceFingerprint}),!0}catch(r){return u.error(`Error updating presence: ${r}`),!1}}isCurrentlyConnected(){return this.isConnected}destroy(){this.stop(),this.gamepadPollInterval!==null&&(clearInterval(this.gamepadPollInterval),this.gamepadPollInterval=null),document.removeEventListener("visibilitychange",this.handleVisibilityChange),window.removeEventListener("keydown",this.handleUserInput,ee),window.removeEventListener("pointerdown",this.handleUserInput,ee),window.removeEventListener("pointermove",this.handleUserInput,ee),window.removeEventListener("wheel",this.handleUserInput,ee)}tickHeartbeat(){let e=Date.now()-this.lastHeartbeatTime,r=this.isFirstTick||e>=Re.CLIENT_REESTABLISH_THRESHOLD_MS;this.isFirstTick=!1,r?this.sendHeartbeat(!0):e>=Re.CLIENT_INTERVAL_MS-Re.CLIENT_GRACE_MS&&this.sendHeartbeat(!1)}sendHeartbeat(e){!e&&this.heartbeatInFlight||(this.heartbeatInFlight=!0,this.sdk.convexClient.mutation(g.sdk.presence.heartbeat,{...e?{data:this.cachedPresenceData,deviceFingerprint:this.deviceFingerprint}:{}}).then(r=>{r&&(this.lastHeartbeatTime=Date.now())}).catch(r=>{u.error(`Heartbeat failed: ${r}`)}).finally(()=>{this.heartbeatInFlight=!1}))}pollGamepads(){if(typeof navigator>"u"||!navigator.getGamepads)return;let e=navigator.getGamepads();for(let r of e)if(r){if(r.buttons.some(s=>s.pressed)){this.start();return}if(r.axes.some(s=>Math.abs(s)>this.GAMEPAD_AXIS_DEADZONE)){this.start();return}}}testConnection(){try{let e=this.isConnected,r=this.sdk.convexClient.client.connectionState();this.isConnected=navigator.onLine&&r.isWebSocketConnected;let s={isConnected:this.isConnected,hasEverConnected:r.hasEverConnected,connectionCount:r.connectionCount,connectionRetries:r.connectionRetries};this.isConnected&&!e?(this.disconnectedAt=null,this.sentDisconnectedEvent=!1,this.sdk.gameEventManager.notifyGame(b.BACKEND_CONNECTED,s)):!this.isConnected&&e?(this.disconnectedAt=Date.now(),u.warn("Backend disconnected - attempting to reconnect..."),this.sdk.gameEventManager.notifyGame(b.BACKEND_RECONNECTING,s)):!this.isConnected&&!e?this.disconnectedAt&&!this.sentDisconnectedEvent&&Date.now()-this.disconnectedAt>this.DISCONNECTED_TIMEOUT_MS&&(this.sdk.gameEventManager.notifyGame(b.BACKEND_DISCONNECTED,s),this.sentDisconnectedEvent=!0):this.isConnected&&e&&(this.disconnectedAt=null,this.sentDisconnectedEvent=!1)}catch(e){u.error("Error testing connection:",e)}}};var Et=class extends w{constructor(e){super(e);this.leaderboardCache=new Map}async getLeaderboard(e){let r=await this.sdk.convexClient.query(g.sdk.leaderboards.getLeaderboard,{name:e});return this.leaderboardCache.set(r.id,r),r}async getOrCreateLeaderboard(e,r,s){let o=await this.sdk.convexClient.mutation(g.sdk.leaderboards.getOrCreateLeaderboard,{name:e,sortOrder:r,displayType:s});return this.leaderboardCache.set(o.id,o),o}getLeaderboardEntryCount(e){let r=this.leaderboardCache.get(e);return r?r.totalEntries:-1}async getMyLeaderboardEntries(e){let r=await this.sdk.convexClient.query(g.sdk.leaderboards.getMyLeaderboardEntry,{leaderboardId:e});r&&r.totalEntries&&this.updateCachedTotalEntries(e,r.totalEntries);let s=r.entry?{...r.entry,userId:this.sdk.wavedashUser.id,username:this.sdk.wavedashUser.username,userAvatarUrl:this.sdk.wavedashUser.avatarUrl}:null;return s?[s]:[]}async listLeaderboardEntriesAroundUser(e,r,s,o=!1){let i=await this.sdk.convexClient.query(g.sdk.leaderboards.listEntriesAroundUser,{leaderboardId:e,countAhead:r,countBehind:s,friendsOnly:o});return i&&i.totalEntries&&this.updateCachedTotalEntries(e,i.totalEntries),this.sdk.friendsManager.cacheLeaderboardPage(i.entries),i.entries}async listLeaderboardEntries(e,r,s,o=!1){let i=await this.sdk.convexClient.query(g.sdk.leaderboards.listEntries,{leaderboardId:e,offset:r,limit:s,friendsOnly:o});return i&&i.totalEntries&&this.updateCachedTotalEntries(e,i.totalEntries),this.sdk.friendsManager.cacheLeaderboardPage(i.entries),i.entries}async uploadLeaderboardScore(e,r,s,o){let i=await this.sdk.convexClient.mutation(g.sdk.leaderboards.upsertLeaderboardEntry,{leaderboardId:e,score:r,keepBest:s,ugcId:o});return i&&i.totalEntries&&this.updateCachedTotalEntries(e,i.totalEntries),{...i.entry,submittedScore:i.submission.score,submittedRank:i.submission.globalRank,userId:this.sdk.wavedashUser.id,username:this.sdk.wavedashUser.username,userAvatarUrl:this.sdk.wavedashUser.avatarUrl}}updateCachedTotalEntries(e,r){let s=this.leaderboardCache.get(e);s&&typeof r=="number"&&this.leaderboardCache.set(e,{...s,totalEntries:r})}};var Zr=lr(or(),1);var It=class It extends w{constructor(e){super(e);this.unsubscribeLobbyMessages=null;this.unsubscribeLobbyUsers=null;this.unsubscribeLobbyData=null;this.lobbyId=null;this.lobbyUsers=[];this.lobbyHostId=null;this.lobbyMetadata={};this.pendingMetadataUpdates={};this.recentMessageIds=[];this.maybeBeingDeletedLobbyIds=new Set;this.resetMaybeBeingDeletedLobbyIdTimeouts=new Map;this.inFlightMetadataUpdate=null;this.cachedLobbies={};this.unsubscribeLobbyInvites=null;this.seenInviteIds=new Set;this.p2pUpdateQueue=Promise.resolve();this.throttledSetMetadata=(0,Zr.default)(()=>this.setMetadata(),It.METADATA_UPDATE_THROTTLE_MS,{leading:!1,trailing:!0});this.processUserUpdates=e=>{this.sdk.friendsManager.cacheUsers(e);let r=this.lobbyUsers,s=new Set(r.map(i=>i.userId)),o=new Set(e.map(i=>i.userId));this.lobbyUsers=e;for(let i of e)i.isHost&&(this.lobbyHostId=i.userId),s.has(i.userId)||this.sdk.gameEventManager.notifyGame(b.LOBBY_USERS_UPDATED,{...i,changeType:Le.JOINED});for(let i of r)o.has(i.userId)||(i.userId===this.sdk.getUserId()&&u.warn("USER WAS KICKED FROM LOBBY! Received notification for myself leaving."),this.sdk.gameEventManager.notifyGame(b.LOBBY_USERS_UPDATED,{...i,isHost:!1,changeType:Le.LEFT}));this.lobbyId&&(this.p2pUpdateQueue=this.p2pUpdateQueue.then(()=>this.updateP2PConnections(e)).catch(i=>{u.error("Error in queued P2P update:",i)}))};this.processMessageUpdates=e=>{for(let r of e)this.recentMessageIds.includes(r.messageId)||(this.recentMessageIds.push(r.messageId),this.sdk.gameEventManager.notifyGame(b.LOBBY_MESSAGE,r));this.recentMessageIds=e.map(r=>r.messageId)};this.processInviteUpdates=e=>{for(let r of e)this.seenInviteIds.has(r.notificationId)||(this.seenInviteIds.add(r.notificationId),this.sdk.gameEventManager.notifyGame(b.LOBBY_INVITE,r));this.seenInviteIds=new Set(e.map(r=>r.notificationId))};this.unsubscribeLobbyInvites=this.sdk.convexClient.onUpdate(g.sdk.gameLobby.getLobbyInvites,{},this.processInviteUpdates,r=>{u.error(`Lobby invites subscription error: ${r}`)})}async createLobby(e,r){let s=await this.sdk.convexClient.mutation(g.sdk.gameLobby.createAndJoinLobby,{visibility:e,maxPlayers:r});return this.handleLobbyJoin(s),s.lobbyId}async joinLobby(e){let r=await this.sdk.convexClient.mutation(g.sdk.gameLobby.joinLobby,{lobbyId:e});return this.handleLobbyJoin(r),!0}getLobbyUsers(e){return this.lobbyId!==e?(u.error("Must be a member of the lobby to access user list"),[]):this.lobbyUsers}getHostId(e){return this.lobbyId!==e?(u.error("Must be a member of the lobby to access the host ID"),null):this.lobbyHostId}getLobbyData(e,r){return this.lobbyId===e?this.lobbyMetadata[r]??null:this.cachedLobbies[e]?this.cachedLobbies[e].metadata[r]??null:null}deleteLobbyData(e,r){return this.setLobbyData(e,r,null)}setLobbyData(e,r,s){return this.lobbyId!==e||this.lobbyHostId!==this.sdk.getUserId()?!1:(this.lobbyMetadata[r]===s||(s===null?delete this.lobbyMetadata[r]:this.lobbyMetadata[r]=s,this.pendingMetadataUpdates[r]=s,this.throttledSetMetadata()),!0)}getLobbyMaxPlayers(e){return this.cachedLobbies[e]?this.cachedLobbies[e].maxPlayers:0}getNumLobbyUsers(e){return this.lobbyId===e?this.lobbyUsers.length:this.cachedLobbies[e]?this.cachedLobbies[e].playerCount:0}async leaveLobby(e){return this.cleanupLobbyState(),await this.sdk.convexClient.mutation(g.sdk.gameLobby.leaveLobby,{lobbyId:e}),this.sdk.iframeMessenger.postToParent(E.LOBBY_LEFT,{lobbyId:e}),e}async listAvailableLobbies(e=!1){let r=e?{friendsOnly:e}:void 0,o=(await this.sdk.convexClient.query(g.sdk.gameLobby.listAvailable,{filters:r})).filter(i=>!this.maybeBeingDeletedLobbyIds.has(i.lobbyId));for(let i of o)this.cachedLobbies[i.lobbyId]=i;return o}sendLobbyMessage(e,r){let s={lobbyId:e,message:r};if(r.length===0)return u.error("Message cannot be empty"),!1;if(r.length>ut)return u.error(`Message cannot be longer than ${ut} characters`),!1;try{this.sdk.convexClient.mutation(g.sdk.gameLobby.sendMessage,s)}catch(o){return u.error(`Error sending lobby message: ${o}`),!1}return!0}async inviteUserToLobby(e,r){return await this.sdk.convexClient.mutation(g.sdk.gameLobby.inviteToLobby,{lobbyId:e,targetUserId:r}),!0}async getLobbyInviteLink(e=!1){if(!this.lobbyId)throw new Error("User is not in a lobby");let r=await this.sdk.iframeMessenger.requestFromParent(E.GET_LOBBY_INVITE_LINK,{lobbyId:this.lobbyId,copyToClipboard:e});if(!r)throw new Error("Parent could not generate invite link");return r}handleLobbyJoin(e){this.cleanupLobbyState(),this.lobbyId=e.lobbyId,this.lobbyHostId=e.hostId,this.lobbyUsers=e.users,this.lobbyMetadata=e.metadata,this.sdk.friendsManager.cacheUsers(e.users);let r=s=>{u.error(`Lobby subscription error: ${s.message}`),s.message.includes("not a member")?this.handleLobbyKicked(me.KICKED):this.handleLobbyKicked(me.ERROR)};this.unsubscribeLobbyMessages=this.sdk.convexClient.onUpdate(g.sdk.gameLobby.lobbyMessages,{lobbyId:e.lobbyId},this.processMessageUpdates,r),this.unsubscribeLobbyData=this.sdk.convexClient.onUpdate(g.sdk.gameLobby.getLobbyMetadata,{lobbyId:e.lobbyId},s=>{this.lobbyMetadata=s,this.sdk.gameEventManager.notifyGame(b.LOBBY_DATA_UPDATED,s)},r),this.unsubscribeLobbyUsers=this.sdk.convexClient.onUpdate(g.sdk.gameLobby.lobbyUsers,{lobbyId:e.lobbyId},this.processUserUpdates,r),e.users.length>1&&(this.p2pUpdateQueue=this.updateP2PConnections(e.users).catch(s=>{u.error("Error initializing P2P on join:",s)})),this.sdk.iframeMessenger.postToParent(E.LOBBY_JOINED,{lobbyId:e.lobbyId}),this.sdk.gameEventManager.notifyGame(b.LOBBY_JOINED,{lobbyId:e.lobbyId,hostId:e.hostId,users:e.users,metadata:e.metadata}),u.debug("Subscribed to lobby:",e.lobbyId)}handleLobbyKicked(e=me.KICKED){let r=this.lobbyId;r&&(u.warn(`User was removed from lobby: ${r} (reason: ${e})`),this.cleanupLobbyState(),this.sdk.iframeMessenger.postToParent(E.LOBBY_LEFT,{lobbyId:r}),this.sdk.gameEventManager.notifyGame(b.LOBBY_KICKED,{lobbyId:r,reason:e}))}cleanupLobbyState(){let e=this.lobbyId;if(this.lobbyId=null,this.throttledSetMetadata.cancel(),this.pendingMetadataUpdates={},this.unsubscribeLobbyMessages&&(this.unsubscribeLobbyMessages(),this.unsubscribeLobbyMessages=null),this.unsubscribeLobbyUsers&&(this.unsubscribeLobbyUsers(),this.unsubscribeLobbyUsers=null),this.unsubscribeLobbyData&&(this.unsubscribeLobbyData(),this.unsubscribeLobbyData=null),this.sdk.p2pManager.disconnectP2P(),e&&this.lobbyUsers.length===1){let r=this.resetMaybeBeingDeletedLobbyIdTimeouts.get(e);r&&clearTimeout(r),this.maybeBeingDeletedLobbyIds.add(e);let s=setTimeout(()=>{this.maybeBeingDeletedLobbyIds.delete(e),this.resetMaybeBeingDeletedLobbyIdTimeouts.delete(e)},500);this.resetMaybeBeingDeletedLobbyIdTimeouts.set(e,s)}this.lobbyUsers=[],this.lobbyHostId=null,this.lobbyMetadata={},this.recentMessageIds=[],this.p2pUpdateQueue=Promise.resolve()}unsubscribeFromCurrentLobby(){this.cleanupLobbyState()}destroy(){this.cleanupLobbyState(),this.unsubscribeLobbyInvites&&(this.unsubscribeLobbyInvites(),this.unsubscribeLobbyInvites=null);for(let e of this.resetMaybeBeingDeletedLobbyIdTimeouts.values())clearTimeout(e);this.resetMaybeBeingDeletedLobbyIdTimeouts.clear(),this.maybeBeingDeletedLobbyIds.clear(),this.seenInviteIds.clear(),this.cachedLobbies={}}setMetadata(){if(this.inFlightMetadataUpdate!==null||this.lobbyId===null||Object.keys(this.pendingMetadataUpdates).length===0)return;let e=this.pendingMetadataUpdates;this.pendingMetadataUpdates={},this.inFlightMetadataUpdate=this.sdk.convexClient.mutation(g.sdk.gameLobby.setLobbyMetadata,{lobbyId:this.lobbyId,updates:e}).catch(r=>{u.error("Error updating lobby metadata:",r)}).finally(()=>{this.inFlightMetadataUpdate=null,Object.keys(this.pendingMetadataUpdates).length>0&&this.throttledSetMetadata()})}async updateP2PConnections(e){if(this.lobbyId)try{if(e.length<=1){this.sdk.p2pManager.disconnectP2P(),u.debug("Only one user in lobby, P2P connections disconnected");return}let r=e.map(s=>({id:s.userId,username:s.username,avatarUrl:s.userAvatarUrl}));await this.sdk.p2pManager.initializeP2PForCurrentLobby(this.lobbyId,r),u.debug(`P2P connections updated for lobby ${this.lobbyId} with ${r.length} users`)}catch(r){u.error("Error updating P2P connections:",r)}}};It.METADATA_UPDATE_THROTTLE_MS=150;var Ct=It;function Xr(){if(typeof document>"u")return;let n=document.getElementsByClassName("game-focus-target");if(n.length>0){n[0].focus();return}document.querySelector("canvas, input, button, [tabindex]:not([tabindex='-1'])")?.focus()}var rn=typeof Element<"u"&&typeof document<"u",en=rn?Element.prototype.requestPointerLock:void 0,tn=0;function Pt(){if(!rn||!en)return()=>{};++tn===1&&(Element.prototype.requestPointerLock=function(){return Promise.resolve()}),document.exitPointerLock();let n=!1;return()=>{n||(n=!0,--tn===0&&(Element.prototype.requestPointerLock=en))}}var Tt=class extends w{constructor(e){super(e);this.handleKeyDown=e=>{e.key==="Tab"&&e.shiftKey&&(e.preventDefault(),this.toggleOverlay())};this.sdk.iframeMessenger.addEventListener(E.TAKE_FOCUS,Xr),this.sdk.iframeMessenger.addEventListener(E.OVERLAY_CHANGED,({isOpen:r})=>this.setOpen(r)),typeof window<"u"&&window.addEventListener("keydown",this.handleKeyDown)}setOpen(e){e?this.restorePointerLock??(this.restorePointerLock=Pt()):(this.restorePointerLock?.(),this.restorePointerLock=void 0)}toggleOverlay(){this.sdk.iframeMessenger.postToParent(E.TOGGLE_OVERLAY,{})}destroy(){this.restorePointerLock?.(),this.restorePointerLock=void 0,typeof window<"u"&&window.removeEventListener("keydown",this.handleKeyDown)}};var nn={enableReliableChannel:!0,enableUnreliableChannel:!0,messageSize:2048,maxIncomingMessages:1024},J=class J extends w{constructor(e){super(e);this.currentConnection=null;this.peerConnections=new Map;this.reliableChannels=new Map;this.unreliableChannels=new Map;this.pendingIceCandidates=new Map;this.iceRestartAttempts=new Map;this.iceRestartInProgress=new Set;this.MAX_ICE_RESTART_ATTEMPTS=3;this.reconnectingPeers=new Set;this.establishedPeers=new Set;this.packetDropTrackers=new Map;this.PACKET_DROP_WINDOW_MS=500;this.turnCredentials=null;this.turnCredentialsInitPromise=null;this.unsubscribeFromSignalingMessages=null;this.processedSignalingMessages=new Set;this.pendingProcessedMessageIds=new Set;this.initializationInProgress=null;this.initializationLobbyId=null;this.signalingSubscriptionReady=null;this.signalingSubscriptionReadyResolver=null;this.channelQueues=new Map;this.MESSAGE_SLOT_HEADER_SIZE=4;this.MAX_CHANNELS=8;this.USERID_SIZE=32;this.CHANNEL_SIZE=4;this.DATALENGTH_SIZE=4;this.CHANNEL_OFFSET=this.USERID_SIZE;this.DATALENGTH_OFFSET=this.USERID_SIZE+this.CHANNEL_SIZE;this.PAYLOAD_OFFSET=this.USERID_SIZE+this.CHANNEL_SIZE+this.DATALENGTH_SIZE;this.WIRE_CHANNEL_SIZE=1;this.WIRE_CHANNEL_OFFSET=0;this.WIRE_PAYLOAD_OFFSET=this.WIRE_CHANNEL_SIZE;this.textEncoder=new TextEncoder;this.textDecoder=new TextDecoder;this.initialized=!1;this.config={...nn}}destroy(){this.disconnectP2P()}ensureInitialized(){this.initialized||this.init()}init(e){if(this.initialized&&!e)return;this.config={...nn,...e};let r=this.MESSAGE_SLOT_HEADER_SIZE+this.PAYLOAD_OFFSET+1,s=this.config.messageSize,o=this.config.maxIncomingMessages;if(s<r)throw new Error(`P2P messageSize must be at least ${r} bytes (got ${s})`);if(s>J.MAX_MESSAGE_SIZE&&console.warn(`P2P messageSize ${s} exceeds max ${J.MAX_MESSAGE_SIZE}, clamping to ${J.MAX_MESSAGE_SIZE}`),o<1)throw new Error(`P2P maxIncomingMessages must be at least 1 (got ${o})`);this.MESSAGE_SIZE=Math.min(s,J.MAX_MESSAGE_SIZE),this.QUEUE_SIZE=o,this.MAX_PAYLOAD_SIZE=this.MESSAGE_SIZE-this.MESSAGE_SLOT_HEADER_SIZE-this.PAYLOAD_OFFSET,this.outgoingMessageBuffer=new Uint8Array(this.MAX_PAYLOAD_SIZE);let i=this.MESSAGE_SIZE*this.QUEUE_SIZE*this.MAX_CHANNELS;i>J.MEMORY_WARNING_THRESHOLD_BYTES&&console.warn(`P2P ring buffer memory could reach ${(i/1024/1024).toFixed(1)}MB if all ${this.MAX_CHANNELS} channels are used (messageSize=${this.MESSAGE_SIZE} x maxIncomingMessages=${this.QUEUE_SIZE} per channel). Consider reducing maxIncomingMessages if memory is a concern.`),this.initialized=!0}async initializeP2PForCurrentLobby(e,r){if(this.ensureInitialized(),this.currentConnection&&this.currentConnection.lobbyId===e)return this.updateP2PConnection(r);if(this.initializationInProgress&&this.initializationLobbyId===e&&(u.debug("P2P initialization already in progress, waiting..."),await this.initializationInProgress,this.currentConnection))return this.updateP2PConnection(r);this.initializationLobbyId=e,this.initializationInProgress=this.doInitializeP2P(e,r);try{return await this.initializationInProgress}finally{this.initializationInProgress=null,this.initializationLobbyId=null}}async doInitializeP2P(e,r){let s={lobbyId:e,peers:{}};return r.forEach(o=>{o.id!==this.sdk.getUserId()&&(s.peers[o.id]={userId:o.id,username:o.username})}),this.currentConnection=s,await this.establishWebRTCConnections(s),s}async getIceServers(){return this.turnCredentials&&this.turnCredentials.expiresAt>Date.now()+36e5?this.turnCredentials.iceServers:this.turnCredentialsInitPromise?(await this.turnCredentialsInitPromise,this.turnCredentials?.iceServers??null):(this.turnCredentialsInitPromise=(async()=>{try{this.turnCredentials=await this.sdk.convexClient.action(g.sdk.turnCredentials.getOrCreate,{})}finally{this.turnCredentialsInitPromise=null}})(),await this.turnCredentialsInitPromise,this.turnCredentials?.iceServers??null)}async updateP2PConnection(e){if(!this.currentConnection)throw new Error("No existing P2P connection to update");u.debug("Updating P2P connection with new member list"),new Set(Object.keys(this.currentConnection.peers)).add(this.sdk.getUserId());let s=new Set(e.map(i=>i.id)),o=[];for(let i of e){if(i.id===this.sdk.getUserId())continue;let a=this.currentConnection.peers[i.id];a?!a.username&&i.username&&(a.username=i.username):(u.debug(`Adding new peer: ${i.username} (${i.id})`),this.currentConnection.peers[i.id]={userId:i.id,username:i.username},o.push(i.id))}if(o.length>0){let i=this.sdk.getUserId(),a=o.map(l=>{let d=i<l;return u.debug(`Creating connection to new peer ${l}, shouldCreateChannels: ${d}`),this.createPeerConnection(l,this.currentConnection,d)});await Promise.all(a);let c=o.filter(l=>i<l);if(c.length>0){let l=c.map(d=>(u.debug(`Initiating offer to new peer ${d} (lower userId rule)`),this.createOfferToPeer(d)));await Promise.all(l),u.debug(`Initiated ${l.length} offers to new peers`)}}for(let i of Object.keys(this.currentConnection.peers))if(!s.has(i)){let a=this.currentConnection.peers[i];u.debug(`Peer left: ${a.username} (${i})`);let c=this.peerConnections.get(i);c&&(c.close(),this.peerConnections.delete(i)),this.reliableChannels.delete(i),this.unreliableChannels.delete(i),this.pendingIceCandidates.delete(i),this.iceRestartAttempts.delete(i),this.iceRestartInProgress.delete(i),this.reconnectingPeers.delete(i),this.establishedPeers.delete(i),delete this.currentConnection.peers[i]}return this.currentConnection}async establishWebRTCConnections(e){this.subscribeToSignalingMessages(e),this.signalingSubscriptionReady&&(await this.signalingSubscriptionReady,u.debug("Signaling subscription confirmed ready")),await this.establishPeerConnections(e)}subscribeToSignalingMessages(e){this.signalingSubscriptionReady=new Promise(s=>{this.signalingSubscriptionReadyResolver=s});let r=!1;this.unsubscribeFromSignalingMessages=this.sdk.convexClient.onUpdate(g.sdk.p2pSignaling.getSignalingMessages,{lobbyId:e.lobbyId},s=>{r||(r=!0,this.signalingSubscriptionReadyResolver?.(),this.signalingSubscriptionReadyResolver=null),s&&this.processSignalingMessages(s,e)})}stopSignalingMessageSubscription(){this.unsubscribeFromSignalingMessages!==null&&(this.unsubscribeFromSignalingMessages(),this.unsubscribeFromSignalingMessages=null)}async processSignalingMessages(e,r){if(e.length===0)return;let s=[],o=[];for(let i of e)!this.processedSignalingMessages.has(i._id)&&!this.pendingProcessedMessageIds.has(i._id)&&o.push(i),s.push(i._id);for(let i of o){this.pendingProcessedMessageIds.add(i._id);try{await this.handleSignalingMessage(i,r),this.processedSignalingMessages.add(i._id)}catch(a){u.error("Error handling signaling message:",a)}}if(s.length>0)try{await this.sdk.convexClient.mutation(g.sdk.p2pSignaling.markSignalingMessagesProcessed,{messageIds:s});for(let i of s)this.pendingProcessedMessageIds.delete(i)}catch(i){u.error("Failed to mark signaling messages as processed:",i);for(let a of s)this.pendingProcessedMessageIds.delete(a)}}async handleSignalingMessage(e,r){if(e.fromUserId===this.sdk.getUserId())return;let s=e.fromUserId;if(!this.peerConnections.has(s))if(e.messageType===j.OFFER){if(u.debug(`Received offer from ${s} before peer connection exists, creating on-demand`),r.peers[s]||(r.peers[s]={userId:s,username:""}),!await this.createPeerConnection(s,r,!1)){u.error(`Failed to create on-demand peer connection for ${s}`);return}}else{u.warn(`No peer connection for user ${s}, dropping ${e.messageType} message`);return}let o=this.peerConnections.get(s);switch(e.messageType){case j.OFFER:{this.iceRestartInProgress.delete(s),u.debug(`Processing offer from peer ${s}:`),await o.setRemoteDescription(new RTCSessionDescription(e.data)),await this.flushPendingIceCandidates(s,o);let i=await o.createAnswer();await o.setLocalDescription(i),u.debug(" Answer created, waiting for ondatachannel events...");let a={type:i.type,sdp:i.sdp};await this.sendSignalingMessage(s,{type:j.ANSWER,data:a});break}case j.ANSWER:await o.setRemoteDescription(new RTCSessionDescription(e.data)),await this.flushPendingIceCandidates(s,o);break;case j.ICE_CANDIDATE:{let i=e.data;if(o.remoteDescription)await o.addIceCandidate(new RTCIceCandidate(i));else{let a=this.pendingIceCandidates.get(s)||[];a.push(i),this.pendingIceCandidates.set(s,a),u.debug(`Buffered ICE candidate for ${s} (remote description not yet set, ${a.length} buffered)`)}break}default:u.warn("Unknown signaling message type:",e.messageType)}}async flushPendingIceCandidates(e,r){let s=this.pendingIceCandidates.get(e);if(s&&s.length>0){for(let o of s)try{await r.addIceCandidate(new RTCIceCandidate(o))}catch(i){u.warn(`Failed to add buffered ICE candidate for ${e}:`,i)}this.pendingIceCandidates.delete(e)}}async establishPeerConnections(e){u.debug("Establishing WebRTC connections to peers...");let r=this.sdk.getUserId(),s=[];Object.entries(e.peers).forEach(([i,a])=>{let c=r<i;u.debug(`Creating connection to peer ${i} (${a.username}), shouldCreateChannels: ${c}`),s.push(this.createPeerConnection(i,e,c))}),await Promise.all(s);let o=Object.keys(e.peers).filter(i=>r<i);if(o.length>0){let i=o.map(a=>(u.debug(`Initiating offer to peer ${a} (lower userId rule)`),this.createOfferToPeer(a)));await Promise.all(i),u.debug(`Created ${s.length} peer connections and initiated ${i.length} offers`)}else u.debug(`Created ${s.length} peer connections, no offers to initiate`)}async createOfferToPeer(e){let r=this.peerConnections.get(e);if(!r)throw new Error(`No peer connection for user ${e}`);let s=this.reliableChannels.get(e),o=this.unreliableChannels.get(e);u.debug(`Creating offer to peer ${e}:`),u.debug(` Reliable channel state: ${s?.readyState||"none"}`),u.debug(` Unreliable channel state: ${o?.readyState||"none"}`);let i=await r.createOffer();await r.setLocalDescription(i);let a={type:i.type,sdp:i.sdp};await this.sendSignalingMessage(e,{type:j.OFFER,data:a})}async createPeerConnection(e,r,s=!1){let o=await this.getIceServers();if(!o)return u.error(`No ICE servers available for peer ${e}`),this.sdk.gameEventManager.notifyGame(b.P2P_CONNECTION_FAILED,{userId:e,username:r.peers[e]?.username||"",error:"No ICE servers available"}),!1;let i=new RTCPeerConnection({iceServers:o,iceCandidatePoolSize:0,bundlePolicy:"max-bundle",rtcpMuxPolicy:"require"});if(s){if(u.debug(`Creating data channels for peer ${e}`),this.config.enableReliableChannel){let a=i.createDataChannel("reliable",{ordered:!0,maxRetransmits:void 0});this.reliableChannels.set(e,a),this.setupDataChannelHandlers(a,e,"reliable")}if(this.config.enableUnreliableChannel){let a=i.createDataChannel("unreliable",{ordered:!1,maxRetransmits:0});this.unreliableChannels.set(e,a),this.setupDataChannelHandlers(a,e,"unreliable")}}else u.debug(`Will receive data channels from peer ${e} via ondatachannel`);return i.onicecandidate=a=>{if(a.candidate){let c=a.candidate.candidate.includes("typ host")?"host":a.candidate.candidate.includes("typ srflx")?"srflx (STUN)":a.candidate.candidate.includes("typ relay")?"relay (TURN)":"unknown";u.debug(`Peer ${e} gathered ICE candidate: ${c}`),u.debug(` Candidate: ${a.candidate.candidate}`);let l={candidate:a.candidate.candidate,sdpMid:a.candidate.sdpMid,sdpMLineIndex:a.candidate.sdpMLineIndex,usernameFragment:a.candidate.usernameFragment};this.sendSignalingMessage(e,{type:j.ICE_CANDIDATE,data:l})}},i.ondatachannel=a=>{let c=a.channel;u.debug(`Received ${c.label} data channel from peer ${e}`),c.label==="reliable"?this.reliableChannels.set(e,c):c.label==="unreliable"&&this.unreliableChannels.set(e,c),this.setupDataChannelHandlers(c,e,c.label)},i.onconnectionstatechange=()=>{u.debug(`Peer ${e} connection state: ${i.connectionState}`),i.connectionState==="connected"&&u.debug(` Peer ${e} fully connected, expecting ondatachannel events now...`)},i.oniceconnectionstatechange=()=>{if(u.debug(`Peer ${e} ICE connection state: ${i.iceConnectionState}`),i.iceConnectionState==="connected"){if(u.debug(` ICE connected to peer ${e}, data channels should be available...`),this.iceRestartAttempts.delete(e),this.iceRestartInProgress.delete(e),this.reconnectingPeers.delete(e)){let a=this.currentConnection?.peers[e];a&&this.sdk.gameEventManager.notifyGame(b.P2P_PEER_RECONNECTED,{userId:a.userId,username:a.username})}}else if(i.iceConnectionState==="failed"){if(u.debug(`ICE connection to peer ${e} failed, will retry in 500ms...`),!this.reconnectingPeers.has(e)){this.reconnectingPeers.add(e);let a=this.currentConnection?.peers[e];a&&this.sdk.gameEventManager.notifyGame(b.P2P_PEER_RECONNECTING,{userId:a.userId,username:a.username})}setTimeout(()=>{i.iceConnectionState==="failed"&&(u.warn(`ICE connection to peer ${e} still failed after delay, attempting ICE restart...`),this.attemptIceRestart(e,i))},500)}else i.iceConnectionState==="disconnected"&&u.debug(`ICE connection to peer ${e} disconnected, may recover...`)},i.onicegatheringstatechange=()=>{u.debug(`Peer ${e} ICE gathering state: ${i.iceGatheringState}`)},this.peerConnections.set(e,i),!0}async attemptIceRestart(e,r){if(this.sdk.getUserId()>e){u.debug(`Waiting for peer ${e} to initiate ICE restart (they have lower userId)`);return}if(this.iceRestartInProgress.has(e)){u.debug(`ICE restart already in progress for peer ${e}, skipping`);return}let o=this.iceRestartAttempts.get(e)||0;if(o>=this.MAX_ICE_RESTART_ATTEMPTS){u.error(`Max ICE restart attempts (${this.MAX_ICE_RESTART_ATTEMPTS}) reached for peer ${e}, giving up`),this.reconnectingPeers.delete(e),this.establishedPeers.delete(e);let i=this.currentConnection?.peers[e];i&&this.sdk.gameEventManager.notifyGame(b.P2P_CONNECTION_FAILED,{userId:i.userId,username:i.username,error:"ICE restart failed after maximum attempts"}),r.close();return}this.iceRestartAttempts.set(e,o+1),this.iceRestartInProgress.add(e),u.debug(`ICE restart attempt ${o+1}/${this.MAX_ICE_RESTART_ATTEMPTS} for peer ${e}`);try{r.restartIce();let i=await r.createOffer({iceRestart:!0});await r.setLocalDescription(i);let a={type:i.type,sdp:i.sdp};await this.sendSignalingMessage(e,{type:j.OFFER,data:a}),u.debug(`ICE restart offer sent to peer ${e}`)}catch(i){u.error(`Failed to initiate ICE restart for peer ${e}:`,i)}}setupDataChannelHandlers(e,r,s){e.onopen=()=>{if(u.debug(`${s} data channel opened with peer ${r}`),this.isPeerReady(r)&&!this.establishedPeers.has(r)){this.establishedPeers.add(r);let o=this.currentConnection?.peers[r];o&&this.sdk.gameEventManager.notifyGame(b.P2P_CONNECTION_ESTABLISHED,{userId:o.userId,username:o.username})}},e.onmessage=o=>{this.enqueueMessage(o.data,r)},e.onerror=o=>{u.error(`Data channel error with peer ${r}:`,o);let i=this.currentConnection?.peers[r];i&&this.sdk.gameEventManager.notifyGame(b.P2P_CONNECTION_FAILED,{userId:i.userId,username:i.username,error:o.toString()})},e.onclose=()=>{u.debug(`${s} data channel closed with peer ${r}`),this.establishedPeers.delete(r),this.reconnectingPeers.delete(r);let o=this.currentConnection?.peers[r];o&&this.sdk.gameEventManager.notifyGame(b.P2P_PEER_DISCONNECTED,{userId:o.userId,username:o.username})}}sendP2PMessage(e,r=0,s=!0,o,i=o.length){this.ensureInitialized();try{if(!this.currentConnection)return u.error("P2P send called before P2P is initialized, dropping message."),this.reportPacketDrop(r,"SEND","PEER_NOT_READY"),!1;if(!o)return u.error("P2P send called with missing payload, dropping message."),this.reportPacketDrop(r,"SEND","INVALID_PAYLOAD_SIZE"),!1;if(!Number.isInteger(r)||r<0||r>=this.MAX_CHANNELS)return u.error(`P2P appChannel must be an integer in [0, ${this.MAX_CHANNELS}), received ${r}, dropping message.`),this.reportPacketDrop(-1,"SEND","INVALID_CHANNEL"),!1;if(i<=0)return u.error(`P2P payloadSize must be greater than 0, received ${i}, dropping message.`),this.reportPacketDrop(r,"SEND","INVALID_PAYLOAD_SIZE"),!1;if(i>this.MAX_PAYLOAD_SIZE)return u.error(`P2P payload too large: ${i} bytes exceeds max ${this.MAX_PAYLOAD_SIZE} bytes, dropping message.`),this.reportPacketDrop(r,"SEND","PAYLOAD_TOO_LARGE"),!1;if(i>o.length)return u.error(`payloadSize is greater than payload buffer length: ${i} > ${o.length}, dropping message.`),this.reportPacketDrop(r,"SEND","INVALID_PAYLOAD_SIZE"),!1;let a=i<o.length?o.subarray(0,i):o,c=this.encodeWireMessage(r,a),l=s?this.reliableChannels:this.unreliableChannels;if(e===void 0)l.forEach((d,f)=>{if(d.readyState==="open")try{d.send(c)}catch(v){u.error(`P2P broadcast to peer ${f} failed:`,v)}});else{let d=l.get(e);if(!d||d.readyState!=="open")return u.error(`P2P no open channel to peer ${e}, dropping message.`),this.reportPacketDrop(r,"SEND","PEER_NOT_READY"),!1;try{d.send(c)}catch(f){return u.error(`P2P send to peer ${e} failed, dropping message:`,f),this.reportPacketDrop(r,"SEND","PEER_NOT_READY"),!1}}return!0}catch(a){return u.error("Error sending P2P message:",a),!1}}async sendSignalingMessage(e,r){if(!this.currentConnection)throw new Error("No active P2P connection for signaling");try{await this.sdk.convexClient.mutation(g.sdk.p2pSignaling.sendSignalingMessage,{lobbyId:this.currentConnection.lobbyId,toUserId:e,messageType:r.type,data:r.data}),u.debug("Sent signaling message:",r.type)}catch(s){throw u.error("Failed to send signaling message:",s),s}}disconnectP2P(){this.currentConnection&&(this.stopSignalingMessageSubscription(),Object.entries(this.currentConnection.peers).forEach(([e,r])=>{let s=this.peerConnections.get(e);s&&(s.close(),this.peerConnections.delete(e)),this.reliableChannels.delete(e),this.unreliableChannels.delete(e)}),this.currentConnection=null,this.processedSignalingMessages.clear(),this.pendingProcessedMessageIds.clear(),this.pendingIceCandidates.clear(),this.iceRestartAttempts.clear(),this.iceRestartInProgress.clear(),this.reconnectingPeers.clear(),this.establishedPeers.clear(),this.clearPacketDropTrackers(),this.initializationInProgress=null,this.initializationLobbyId=null,this.signalingSubscriptionReady=null,this.signalingSubscriptionReadyResolver=null)}isPeerReady(e){if(!this.currentConnection)return!1;let r=this.reliableChannels.get(e),s=this.unreliableChannels.get(e),o=!this.config.enableReliableChannel||r?.readyState==="open",i=!this.config.enableUnreliableChannel||s?.readyState==="open";return o&&i}isBroadcastReady(){return this.currentConnection?this.reliableChannels.size>0&&this.unreliableChannels.size>0:!1}getPeerStatuses(){if(!this.currentConnection)return{};let e={};for(let r of Object.keys(this.currentConnection.peers)){let s=this.reliableChannels.get(r),o=this.unreliableChannels.get(r);e[r]={reliable:s?.readyState,unreliable:o?.readyState,ready:this.isPeerReady(r)}}return e}createChannelQueue(e){let r=this.MESSAGE_SIZE*this.QUEUE_SIZE,s=new ArrayBuffer(r),o=new Uint8Array(s);this.channelQueues.set(e,{buffer:s,writeIndex:0,readIndex:0,messageCount:0,incomingDataView:o}),u.debug(`Allocated P2P ring buffer for channel ${e} (${(r/1024/1024).toFixed(1)}MB)`)}reportPacketDrop(e,r,s){let o=`${r}:${e}:${s}`,i=this.packetDropTrackers.get(o);if(i||(i={channel:e,direction:r,reason:s,pendingCount:0,windowTimer:null,droppedTotal:0},this.packetDropTrackers.set(o,i)),i.droppedTotal+=1,i.windowTimer===null){this.emitPacketDropped(i,1),i.windowTimer=setTimeout(()=>this.flushPacketDropWindow(o),this.PACKET_DROP_WINDOW_MS);return}i.pendingCount+=1}flushPacketDropWindow(e){let r=this.packetDropTrackers.get(e);if(r)if(r.pendingCount>0){let s=r.pendingCount;r.pendingCount=0,this.emitPacketDropped(r,s),r.windowTimer=setTimeout(()=>this.flushPacketDropWindow(e),this.PACKET_DROP_WINDOW_MS)}else r.windowTimer=null}emitPacketDropped(e,r){this.sdk.gameEventManager.notifyGame(b.P2P_PACKET_DROPPED,{channel:e.channel,direction:e.direction,reason:e.reason,droppedCount:r,droppedTotal:e.droppedTotal})}clearPacketDropTrackers(){for(let e of this.packetDropTrackers.values())e.windowTimer!==null&&clearTimeout(e.windowTimer);this.packetDropTrackers.clear()}enqueueMessage(e,r){try{if(e.byteLength<this.WIRE_PAYLOAD_OFFSET){u.warn("Binary message too short to extract channel"),this.reportPacketDrop(-1,"RECEIVE","MALFORMED");return}let s=new Uint8Array(e),o=s[this.WIRE_CHANNEL_OFFSET];if(!this.channelQueues.has(o)){if(o>=this.MAX_CHANNELS){u.warn(`Channel ${o} exceeds max channels (${this.MAX_CHANNELS}), dropping message`),this.reportPacketDrop(o,"RECEIVE","INVALID_CHANNEL");return}this.createChannelQueue(o)}let i=this.channelQueues.get(o);if(i.messageCount>=this.QUEUE_SIZE){u.warn(`P2P message queue full for channel ${o}, dropping message`),this.reportPacketDrop(o,"RECEIVE","QUEUE_FULL");return}let a=e.byteLength-this.WIRE_PAYLOAD_OFFSET,c=this.PAYLOAD_OFFSET+a,l=this.MESSAGE_SIZE-this.MESSAGE_SLOT_HEADER_SIZE;if(c>l){u.warn(`Message too large for queue: ${c} > ${l}, dropping message.`),this.reportPacketDrop(o,"RECEIVE","PAYLOAD_TOO_LARGE");return}let d=i.writeIndex*this.MESSAGE_SIZE,f=d+this.MESSAGE_SLOT_HEADER_SIZE,v=new DataView(i.buffer,d,this.MESSAGE_SIZE);v.setUint32(0,c,!0);let h=this.textEncoder.encode(r).slice(0,this.USERID_SIZE);i.incomingDataView.fill(0,f,f+this.USERID_SIZE),i.incomingDataView.set(h,f),v.setUint32(this.MESSAGE_SLOT_HEADER_SIZE+this.CHANNEL_OFFSET,o,!0),v.setUint32(this.MESSAGE_SLOT_HEADER_SIZE+this.DATALENGTH_OFFSET,a,!0),a>0&&i.incomingDataView.set(s.subarray(this.WIRE_PAYLOAD_OFFSET),f+this.PAYLOAD_OFFSET),i.writeIndex=(i.writeIndex+1)%this.QUEUE_SIZE,i.messageCount++}catch(s){u.error("Error enqueuing binary P2P message:",s)}}getMaxPayloadSize(){return this.ensureInitialized(),this.MAX_PAYLOAD_SIZE}getMaxIncomingMessages(){return this.ensureInitialized(),this.QUEUE_SIZE}getOutgoingMessageBuffer(){return this.ensureInitialized(),this.outgoingMessageBuffer}readMessageFromChannel(e){this.ensureInitialized();let r=this.channelQueues.get(e);if(!r)return null;let s=this.readRawMessage(r);return s?this.decodeBinaryMessage(s):null}readRawMessage(e){if(e.messageCount===0)return null;let r=e.readIndex*this.MESSAGE_SIZE,o=new DataView(e.buffer,r,this.MESSAGE_SIZE).getUint32(0,!0),i=this.MESSAGE_SIZE-this.MESSAGE_SLOT_HEADER_SIZE;if(o===0||o>i)return e.readIndex=(e.readIndex+1)%this.QUEUE_SIZE,e.messageCount--,null;let a=new Uint8Array(e.buffer,r+this.MESSAGE_SLOT_HEADER_SIZE,o);return e.readIndex=(e.readIndex+1)%this.QUEUE_SIZE,e.messageCount--,a}drainChannelToBuffer(e,r){this.ensureInitialized();let s=this.channelQueues.get(e);if(!s||s.messageCount===0)return new Uint8Array(0);if(!r||r.byteLength===0){let l=[],d=0;for(;s.messageCount>0;){let m=this.readRawMessage(s);m&&(l.push(m),d+=this.MESSAGE_SLOT_HEADER_SIZE+m.length)}if(l.length===0)return new Uint8Array(0);let f=new Uint8Array(d),v=new DataView(f.buffer),h=0;for(let m of l)v.setUint32(h,m.length,!0),h+=this.MESSAGE_SLOT_HEADER_SIZE,f.set(m,h),h+=m.length;return f}let o=new DataView(r.buffer,r.byteOffset,r.byteLength),i=new DataView(s.buffer),a=this.MESSAGE_SIZE-this.MESSAGE_SLOT_HEADER_SIZE,c=0;for(;s.messageCount>0;){let l=s.readIndex*this.MESSAGE_SIZE,d=i.getUint32(l,!0);if(d===0||d>a){s.readIndex=(s.readIndex+1)%this.QUEUE_SIZE,s.messageCount--;continue}let f=this.MESSAGE_SLOT_HEADER_SIZE+d;if(c+f>r.byteLength)break;o.setUint32(c,d,!0),c+=this.MESSAGE_SLOT_HEADER_SIZE,r.set(new Uint8Array(s.buffer,l+this.MESSAGE_SLOT_HEADER_SIZE,d),c),c+=d,s.readIndex=(s.readIndex+1)%this.QUEUE_SIZE,s.messageCount--}return r.subarray(0,c)}encodeWireMessage(e,r){if(e<0||e>=this.MAX_CHANNELS)throw new Error(`P2P channel ${e} must be between 0 and ${this.MAX_CHANNELS-1}`);let s=this.WIRE_PAYLOAD_OFFSET+r.length,o=new Uint8Array(s);return o[this.WIRE_CHANNEL_OFFSET]=e,r.length>0&&o.set(r,this.WIRE_PAYLOAD_OFFSET),o}decodeBinaryMessage(e){if(e.byteLength<this.PAYLOAD_OFFSET)throw new Error("Invalid binary message: too short");let r=new DataView(e.buffer,e.byteOffset,e.byteLength),s=e,o=0,i=s.slice(o,o+this.USERID_SIZE),a=this.textDecoder.decode(i).replace(/\0+$/,"");o+=this.USERID_SIZE;let c=r.getUint32(o,!0);o+=this.CHANNEL_SIZE;let l=r.getUint32(o,!0);o+=this.DATALENGTH_SIZE;let d=e.slice(o,o+l);return{fromUserId:a,channel:c,payload:d}}};J.MAX_MESSAGE_SIZE=64*1024,J.MEMORY_WARNING_THRESHOLD_BYTES=128*1024*1024;var At=J;var ii=600*1e3;function oi(n){try{let[,t]=n.split(".");if(!t)return null;let e=t.replace(/-/g,"+").replace(/_/g,"/"),r=e+"===".slice((e.length+3)%4),s=Uint8Array.from(atob(r),i=>i.charCodeAt(0)),o=new TextDecoder().decode(s);return JSON.parse(o)}catch(t){return u.warn("Failed to decode JWT payload",t),null}}function sn(n){let e=oi(n)?.ents;return Array.isArray(e)?e.filter(r=>typeof r=="string"):[]}var Mt=class extends w{constructor(){super(...arguments);this.paywallOpen=!1}async isEntitled(e){let r=await this.sdk.ensureGameplayJwt();return sn(r).includes(e)}async getEntitlements(){let e=await this.sdk.ensureGameplayJwt();return sn(e)}async triggerPaywall(e){if(await this.isEntitled(e))return!0;if(this.paywallOpen)throw new Error("Paywall already in progress");this.paywallOpen=!0,this.restorePointerLock=Pt();let r;try{r=await this.sdk.iframeMessenger.requestFromParent(E.TRIGGER_PAYWALL,{contentIdentifier:e},ii)}finally{this.restorePointerLock?.(),this.restorePointerLock=void 0,this.paywallOpen=!1}return r.purchased?(await this.sdk.ensureGameplayJwt(!0),!0):!1}isPaywallOpen(){return this.paywallOpen}destroy(){this.restorePointerLock?.(),this.restorePointerLock=void 0}};var on=lr(or(),1),ai=1e3,xt=class extends w{constructor(e){super(e);this.stats=new Map;this.unlockedAchievements=new Set;this.dirtyStats=new Set;this.dirtyAchievements=new Set;this.knownStatIds=new Set;this.knownAchievementIds=new Set;this.loaded={stats:!1,achievements:!1};this.subscriptions=[];this.inFlightPersist=null;this.flushRequested=!1;this.throttledPersist=(0,on.default)(()=>this.persist(),ai,{leading:!1,trailing:!0});this.subscribe(),this.requestStats().catch(r=>{u.error("Initial stats fetch failed:",r)})}destroy(){this.throttledPersist.cancel();for(let e of this.subscriptions)e();this.subscriptions=[]}isReady(){return this.loaded.stats&&this.loaded.achievements}subscribe(){this.subscriptions.push(this.sdk.convexClient.onUpdate(g.sdk.gameAchievements.listStatIdentifiers,{},e=>{this.knownStatIds=new Set(e)},e=>{u.error("Stat identifiers subscription error:",e)}),this.sdk.convexClient.onUpdate(g.sdk.gameAchievements.listAchievementIdentifiers,{},e=>{this.knownAchievementIds=new Set(e)},e=>{u.error("Achievement identifiers subscription error:",e)}),this.sdk.convexClient.onUpdate(g.sdk.gameAchievements.getMyAchievementsForGame,{},e=>{this.loaded.achievements=!0;for(let{achievement:r}of e)this.unlockedAchievements.add(r.identifier)},e=>{u.error("Achievement subscription error:",e)}))}async requestStats(){let e=await this.sdk.convexClient.query(g.sdk.gameAchievements.getMyStatsForGame,{});this.loaded.stats=!0;for(let r of e)this.stats.has(r.identifier)||this.stats.set(r.identifier,r.value);return!0}storeStats(){return this.isReady()?(this.throttledPersist(),this.requestPersistFlush(),!0):!1}requestPersistFlush(){this.inFlightPersist!==null&&(this.flushRequested=!0),this.throttledPersist.flush()}persist(){if(this.inFlightPersist!==null||this.dirtyStats.size===0&&this.dirtyAchievements.size===0)return;let e=this.getPendingData();e&&(this.inFlightPersist=Promise.all([e.stats.length>0?this.sdk.convexClient.mutation(g.sdk.gameAchievements.setUserGameStats,{stats:e.stats}):Promise.resolve(),e.achievements.length>0?this.sdk.convexClient.mutation(g.sdk.gameAchievements.setUserGameAchievements,{achievements:e.achievements}):Promise.resolve()]).then(()=>{this.sdk.gameEventManager.notifyGame(b.STATS_STORED,{success:!0})}).catch(r=>{let s=r instanceof Error?r.message:`Error storing stats: ${r}`;u.error(s),this.sdk.gameEventManager.notifyGame(b.STATS_STORED,{success:!1,message:s})}).finally(()=>{this.inFlightPersist=null;let r=this.flushRequested;this.flushRequested=!1,(this.dirtyStats.size>0||this.dirtyAchievements.size>0)&&(this.throttledPersist(),r&&this.throttledPersist.flush())}))}getStat(e){return!this.isReady()||!this.knownStatIds.has(e)?0:this.stats.get(e)??0}setStat(e,r,s=!1){return!this.isReady()||!this.knownStatIds.has(e)?!1:(this.stats.get(e)!==r&&(this.stats.set(e,r),this.dirtyStats.add(e),this.throttledPersist()),s&&this.requestPersistFlush(),!0)}getAchievement(e){return!this.isReady()||!this.knownAchievementIds.has(e)?!1:this.unlockedAchievements.has(e)}setAchievement(e,r=!1){return!this.isReady()||!this.knownAchievementIds.has(e)?!1:(this.unlockedAchievements.has(e)||(this.unlockedAchievements.add(e),this.dirtyAchievements.add(e),this.throttledPersist()),r&&this.requestPersistFlush(),!0)}getPendingData(){if(this.dirtyStats.size===0&&this.dirtyAchievements.size===0)return null;let e=[...this.dirtyStats].map(s=>({identifier:s,value:this.stats.get(s)})),r=[...this.dirtyAchievements];return this.dirtyStats.clear(),this.dirtyAchievements.clear(),{stats:e,achievements:r}}};var Rt=class extends w{constructor(t){super(t)}async createUGCItem(t,e,r,s,o){let{ugcId:i,uploadUrl:a}=await this.sdk.convexClient.mutation(g.sdk.userGeneratedContent.createUGCItem,{ugcType:t,title:e,description:r,visibility:s,createPresignedUploadUrl:!!o});if(o&&!a)throw new Error(`Failed to create a presigned upload URL for UGC item: ${o}`);if(o&&a&&!await this.sdk.fileSystemManager.upload(a,o))throw new Error(`Failed to upload UGC item: ${o}`);return i}async updateUGCItem(t,e={}){let{title:r,description:s,visibility:o,filePath:i}=e,{uploadUrl:a}=await this.sdk.convexClient.mutation(g.sdk.userGeneratedContent.updateUGCItem,{ugcId:t,title:r,description:s,visibility:o,createPresignedUploadUrl:!!i});if(i&&!a)throw new Error(`Failed to create a presigned upload URL for UGC item: ${i}`);if(i&&a&&!await this.sdk.fileSystemManager.upload(a,i))throw new Error(`Failed to upload UGC item: ${i}`);return t}async deleteUGCItem(t){return await this.sdk.convexClient.mutation(g.sdk.userGeneratedContent.deleteUGCItem,{ugcId:t}),t}async downloadUGCItem(t,e){let r=await this.sdk.convexClient.query(g.sdk.userGeneratedContent.getUGCItemDownloadUrl,{ugcId:t});try{await this.sdk.fileSystemManager.download(r,e)}catch(s){let o=s instanceof Error?s.message:String(s);throw new Error(`Failed to download UGC item ${t}: ${o}`)}return t}async listUGCItems(t={}){let{createdBy:e,ugcType:r,titleSearch:s,numItems:o,continueCursor:i}=t,a=e!==void 0||r!==void 0||s!==void 0?{createdBy:e,ugcType:r,titleSearch:s}:void 0;return await this.sdk.convexClient.query(g.sdk.userGeneratedContent.listUGCItems,{filters:a,numItems:o,continueCursor:i})}};var an="";function cn(n){an=n}function _t(){return an}var ci=15e3,Lt=class{constructor(){this.handleMessage=t=>{if(t.origin!==_t()){t.source!==window&&console.warn(`Ignored message from untrusted origin: ${t.origin}`);return}if(t.data?.requestId){let s=this.pendingRequests.get(t.data.requestId);s&&(clearTimeout(s.timeout),this.pendingRequests.delete(t.data.requestId),s.resolve(t.data.data));return}let e=t.data?.type;if(!e)return;let r=this.listeners.get(e);if(r)for(let s of r)s(t.data)};this.pendingRequests=new Map,this.requestIdCounter=0,this.listeners=new Map,typeof window<"u"&&window.addEventListener("message",this.handleMessage)}addEventListener(t,e){let r=this.listeners.get(t);r||(r=new Set,this.listeners.set(t,r)),r.add(e)}removeEventListener(t,e){this.listeners.get(t)?.delete(e)}postToParent(t,e){let r=_t();return typeof window>"u"||!r?!1:(window.parent.postMessage({type:t,...e},r),!0)}async requestFromParent(t,e,r=ci){return new Promise((s,o)=>{let i=_t();if(typeof window>"u"||!i){o(new Error("Parent origin not found"));return}let a=`${t}_${++this.requestIdCounter}_${Date.now()}`,c=setTimeout(()=>{this.pendingRequests.delete(a),o(new Error(`${t} request timed out after ${r}ms`))},r);this.pendingRequests.set(a,{resolve:s,reject:o,timeout:c}),window.parent.postMessage({type:t,requestId:a,...e},i)})}};var kt=class{constructor(){this.handleMessage=t=>{let e=t.data,r=e?.type;if(!r)return;let s=this.listeners.get(r);if(!s||s.size===0)return;let o=t.ports?.[0],i=a=>{if(o)try{o.postMessage(a)}catch(c){u.warn("Failed to reply to SW via port",c)}this.postToServiceWorker(a)};for(let a of s)a(e?.payload,i)};this.listeners=new Map,typeof navigator<"u"&&navigator.serviceWorker&&navigator.serviceWorker.addEventListener("message",this.handleMessage)}addEventListener(t,e){let r=this.listeners.get(t);r||(r=new Set,this.listeners.set(t,r)),r.add(e)}removeEventListener(t,e){this.listeners.get(t)?.delete(e)}postToServiceWorker(t){if(typeof navigator>"u"||!navigator.serviceWorker)return!1;try{return navigator.serviceWorker.controller?.postMessage(t),!0}catch(e){return u.warn("Failed to post message to service worker",e),!1}}};var ui=/^[0-9a-z]{31,37}$/,y=(n,t)=>{if(typeof n!="string")throw new Error(`${t}: expected string, got ${F(n)}`);return n},U=(n,t)=>{if(typeof n!="number"||!Number.isFinite(n))throw new Error(`${t}: expected finite number, got ${F(n)}`);return n},te=(n,t)=>{if(typeof n!="boolean")throw new Error(`${t}: expected boolean, got ${F(n)}`);return n},un=(n,t)=>{if(n!==null)throw new Error(`${t}: expected null, got ${F(n)}`);return null},ln=(n,t)=>{if(!(n instanceof Uint8Array))throw new Error(`${t}: expected Uint8Array, got ${F(n)}`);return n},dn=(n,t)=>{if(typeof n!="object"||n===null||Array.isArray(n))throw new Error(`${t}: expected plain object, got ${F(n)}`);for(let[e,r]of Object.entries(n))if(typeof r=="object"&&r!==null)throw new Error(`${t}: expected flat record with no nested objects, but key "${e}" contains ${F(r)}`);return n};function C(n){return(t,e)=>{if(typeof t!="string"||!ui.test(t))throw new Error(`${e}: expected Id<"${n}"> (base32 string, 31-37 chars), got ${F(t)}`);return t}}function re(n,t){let e=Object.values(n);return(r,s)=>{if(!e.includes(r)){let o=Object.entries(n).map(([a,c])=>`${JSON.stringify(c)} (${a})`).join(", "),i=t?`${t} `:"";throw new Error(`${s}: invalid ${i}value ${F(r)}. Expected one of: ${o}`)}return r}}function M(n){return(t,e)=>{if(t!==void 0)return n(t,e)}}function hn(...n){return(t,e)=>{for(let r of n)try{return r(t,e)}catch{}throw new Error(`${e}: no variant matched, got ${F(t)}`)}}function Ot(n){return(t,e)=>{if(typeof t!="object"||t===null||Array.isArray(t))throw new Error(`${e}: expected plain object, got ${F(t)}`);let r=t;for(let s of Object.keys(r))if(!(s in n))throw new Error(`${e}: unrecognized property "${s}"`);for(let s of Object.keys(n))n[s](r[s],`${e}.${s}`);return r}}function ne(n,t,e){let r={},s={};for(let o=0;o<t.length;o++){let[i,a]=t[o];r[i]=a,s[i]=e[o]}Ot(r)(s,n)}function F(n){if(n===void 0)return"undefined";if(n===null)return"null";if(n instanceof Uint8Array)return`Uint8Array(byteLength=${n.byteLength})`;if(Array.isArray(n))return`array(length=${n.length})`;let t=typeof n;return t==="string"||t==="number"||t==="boolean"?`${t} ${JSON.stringify(n)}`:t}var ke=new Lt,ar=class extends EventTarget{constructor(e){super();this._initialized=!1;this._eventsReady=!1;this.destroyed=!1;this.gameFinishedLoading=!1;this.Events=b;this.LobbyVisibility=ct;this.LeaderboardSortOrder=lt;this.LeaderboardDisplayType=dt;this.UGCType=Ae;this.UGCVisibility=Me;this.AvatarSize=ft;this.LobbyKickedReason=me;this.LobbyUserChangeType=Le;this.P2PPacketDropReason=qr;this.config=null;this.engineCallbackReceiver="WavedashCallbackReceiver";this.engineInstance=null;this.gameplayJwt=null;this.gameplayJwtPromise=null;this.setupWarningTimeout=null;this.listenerWrappers=new Map;this.convexClient=new Te(e.convexCloudUrl,{expectAuth:!0}),this.gameCloudId=e.gameCloudId,this.iframeMessenger=ke,this.convexClient.setAuth(({forceRefreshToken:r})=>this.getAuthToken(r)),this.wavedashUser=e.wavedashUser,this.ugcHost=e.ugcHost,this.uploadsHost=e.uploadsHost,this.swMessenger=new kt,this.p2pManager=new At(this),this.lobbyManager=new Ct(this),this.statsManager=new xt(this),this.heartbeatManager=new wt(this),this.fileSystemManager=new mt(this),this.ugcManager=new Rt(this),this.leaderboardManager=new Et(this),this.friendsManager=new yt(this),this.gameEventManager=new vt(this),this.fullscreenManager=new bt(this),this.overlayManager=new Tt(this),this.audioManager=new pt(this),this.paidContentManager=new Mt(this),this.managers=[this.p2pManager,this.lobbyManager,this.statsManager,this.heartbeatManager,this.fileSystemManager,this.ugcManager,this.leaderboardManager,this.friendsManager,this.gameEventManager,this.fullscreenManager,this.overlayManager,this.audioManager,this.paidContentManager],this.friendsManager.cacheUsers([{userId:this.wavedashUser.id,username:this.wavedashUser.username,avatarUrl:this.wavedashUser.avatarUrl}]),this.setupSessionEndListeners(),this.setupSwCredsListener(),this.launchParams=e.launchParams??{},this.setupWarningTimeout=setTimeout(()=>{this.setupWarningTimeout=null,u.warn("Wavedash.init(), Wavedash.loadComplete(), or Wavedash.updateLoadProgressZeroToOne() not called yet")},1e4)}get initialized(){return this._initialized}get eventsReady(){return this._eventsReady}clearSetupWarning(){this.setupWarningTimeout!==null&&(clearTimeout(this.setupWarningTimeout),this.setupWarningTimeout=null)}init(e){if(this.loadComplete(),this._initialized)return u.warn("init called twice! Already initialized, skipping init"),!1;if(typeof e=="string")try{e=JSON.parse(e)}catch(r){return u.error("Initialized with invalid config:",r),!1}return this.config=e??{},this._initialized=!0,u.setLogLevel(this.config.debug?X.DEBUG:X.WARN),this.p2pManager.init(this.config.p2p),u.debug("Initialized with config:",this.config),this.config.deferEvents||this.readyForEvents(),!0}readyForEvents(){this._eventsReady||(this.ensureInit(),this._eventsReady=!0,this.gameEventManager.flushEventQueue())}on(e,r){let s=a=>{r(a.detail)},o=this.listenerWrappers.get(e);o||(o=new Map,this.listenerWrappers.set(e,o));let i=o.get(r);return i&&this.removeEventListener(e,i),o.set(r,s),this.addEventListener(e,s),()=>this.off(e,r)}off(e,r){let s=this.listenerWrappers.get(e),o=s?.get(r);!s||!o||(this.removeEventListener(e,o),s.delete(r),s.size===0&&this.listenerWrappers.delete(e))}addEventListener(e,r,s){super.addEventListener(e,r,s)}removeEventListener(e,r,s){super.removeEventListener(e,r,s)}loadScript(e){return ne("loadScript",[["src",y]],[e]),new Promise((r,s)=>{let o=document.createElement("script");o.type="text/javascript",o.crossOrigin="anonymous",o.src=e,o.onload=r,o.onerror=s,document.head.appendChild(o)})}updateLoadProgressZeroToOne(e){ne("updateLoadProgressZeroToOne",[["progress",U]],[e]),this.clearSetupWarning(),ke.postToParent(E.PROGRESS_UPDATE,{progress:e})}loadComplete(){this.clearSetupWarning(),!this.gameFinishedLoading&&(this.gameFinishedLoading=!0,this.heartbeatManager.start(),ke.postToParent(E.LOADING_COMPLETE,{}))}get gameLoaded(){return this.gameFinishedLoading}toggleOverlay(){this.overlayManager.toggleOverlay()}isFullscreen(){return this.fullscreenManager.isFullscreen()}async requestFullscreen(e){return this.fullscreenManager.requestFullscreen(e)}async toggleFullscreen(){return this.fullscreenManager.toggleFullscreen()}isMuted(){return this.audioManager.isMuted()}async requestMute(e){return this.audioManager.requestMute(e)}async toggleMute(){return this.audioManager.toggleMute()}getUser(){return this.formatResponse(this.wavedashUser)}getUsername(e){return e===void 0?this.wavedashUser.username:(ne("getUsername",[["userId",C("users")]],[e]),this.friendsManager.getUsername(e))}getUserId(){return this.wavedashUser.id}async getUserJwt(){u.debug("getUserJwt");try{let e=await this.ensureGameplayJwt();return this.formatResponse({success:!0,data:e})}catch(e){let r=e instanceof Error?e.message:String(e);return u.error("getUserJwt",r),this.formatResponse({success:!1,data:null,message:r})}}getLaunchParams(){return this.formatResponse(this.launchParams)}async listFriends(){return this.apiCall(this.friendsManager,"listFriends",[])}getUserAvatarUrl(e,r=this.AvatarSize.MEDIUM){return this.apiCallSync(this.friendsManager,"getUserAvatarUrl",[["userId",C("users")],["size",U]],e,r)}async getLeaderboard(e){return this.apiCall(this.leaderboardManager,"getLeaderboard",[["name",y]],e)}async getOrCreateLeaderboard(e,r,s){return this.apiCall(this.leaderboardManager,"getOrCreateLeaderboard",[["name",y],["sortOrder",re(lt,"LeaderboardSortOrder")],["displayType",re(dt,"LeaderboardDisplayType")]],e,r,s)}getLeaderboardEntryCount(e){return this.apiCallSync(this.leaderboardManager,"getLeaderboardEntryCount",[["leaderboardId",C("leaderboards")]],e)}async getMyLeaderboardEntries(e){return this.apiCall(this.leaderboardManager,"getMyLeaderboardEntries",[["leaderboardId",C("leaderboards")]],e)}async listLeaderboardEntriesAroundUser(e,r,s,o=!1){return this.apiCall(this.leaderboardManager,"listLeaderboardEntriesAroundUser",[["leaderboardId",C("leaderboards")],["countAhead",U],["countBehind",U],["friendsOnly",te]],e,r,s,o)}async listLeaderboardEntries(e,r,s,o=!1){return this.apiCall(this.leaderboardManager,"listLeaderboardEntries",[["leaderboardId",C("leaderboards")],["offset",U],["limit",U],["friendsOnly",te]],e,r,s,o)}async uploadLeaderboardScore(e,r,s,o){return this.apiCall(this.leaderboardManager,"uploadLeaderboardScore",[["leaderboardId",C("leaderboards")],["score",U],["keepBest",te],["ugcId",M(C("userGeneratedContent"))]],e,r,s,o)}async createUGCItem(e,r,s,o,i){return this.apiCall(this.ugcManager,"createUGCItem",[["ugcType",re(Ae,"UGCType")],["title",M(y)],["description",M(y)],["visibility",M(re(Me,"UGCVisibility"))],["filePath",M(y)]],e,r,s,o,i)}async updateUGCItem(e,r={}){if(typeof r=="string"){let s=r;try{r=JSON.parse(s)}catch(o){let i=`updateUGCItem: invalid JSON: ${s}`;return u.error(i,o),this.formatResponse({success:!1,data:null,message:i})}}return this.apiCall(this.ugcManager,"updateUGCItem",[["ugcId",C("userGeneratedContent")],["updates",M(Ot({title:M(y),description:M(y),visibility:M(re(Me,"UGCVisibility")),filePath:M(y)}))]],e,r)}async deleteUGCItem(e){return this.apiCall(this.ugcManager,"deleteUGCItem",[["ugcId",C("userGeneratedContent")]],e)}async downloadUGCItem(e,r){return this.apiCall(this.ugcManager,"downloadUGCItem",[["ugcId",C("userGeneratedContent")],["filePath",y]],e,r)}async listUGCItems(e={}){if(typeof e=="string"){let r=e;try{e=JSON.parse(r)}catch(s){let o=`listUGCItems: invalid JSON: ${r}`;return u.error(o,s),this.formatResponse({success:!1,data:null,message:o})}}return this.apiCall(this.ugcManager,"listUGCItems",[["args",M((r,s)=>{let o=Ot({createdBy:M(C("users")),ugcType:M(re(Ae,"UGCType")),titleSearch:M(y),numItems:M(U),continueCursor:M(y)})(r,s);if(o.continueCursor!==void 0&&(o.createdBy!==void 0||o.ugcType!==void 0||o.titleSearch!==void 0||o.numItems!==void 0))throw new Error(`${s}: continueCursor should be the only argument if present`);return o})]],e)}async deleteRemoteFile(e){return this.apiCall(this.fileSystemManager,"deleteRemoteFile",[["filePath",y]],e)}async downloadRemoteFile(e){return this.apiCall(this.fileSystemManager,"downloadRemoteFile",[["filePath",y]],e)}async remoteFileExists(e){return this.apiCall(this.fileSystemManager,"remoteFileExists",[["filePath",y]],e)}async uploadRemoteFile(e){return this.apiCall(this.fileSystemManager,"uploadRemoteFile",[["filePath",y]],e)}async listRemoteDirectory(e){return this.apiCall(this.fileSystemManager,"listRemoteDirectory",[["path",y]],e)}async downloadRemoteDirectory(e){return this.apiCall(this.fileSystemManager,"downloadRemoteDirectory",[["path",y]],e)}async writeLocalFile(e,r){return ne("writeLocalFile",[["filePath",y],["data",ln]],[e,r]),await this.fileSystemManager.writeLocalFile(e,r)}async readLocalFile(e){return ne("readLocalFile",[["filePath",y]],[e]),await this.fileSystemManager.readLocalFile(e)}getAchievement(e){return this.apiCallSync(this.statsManager,"getAchievement",[["identifier",y]],e)}getStat(e){return this.apiCallSync(this.statsManager,"getStat",[["identifier",y]],e)}setAchievement(e,r=!1){return this.apiCallSync(this.statsManager,"setAchievement",[["identifier",y],["storeNow",te]],e,r)}setStat(e,r,s=!1){return this.apiCallSync(this.statsManager,"setStat",[["identifier",y],["value",U],["storeNow",te]],e,r,s)}async requestStats(){return this.apiCall(this.statsManager,"requestStats",[])}storeStats(){return this.apiCallSync(this.statsManager,"storeStats",[])}getP2PMaxPayloadSize(){return this.ensureInit(),this.apiCallSync(this.p2pManager,"getMaxPayloadSize",[])}getP2PMaxIncomingMessages(){return this.ensureInit(),this.apiCallSync(this.p2pManager,"getMaxIncomingMessages",[])}getP2POutgoingMessageBuffer(){return this.ensureInit(),this.apiCallSync(this.p2pManager,"getOutgoingMessageBuffer",[])}sendP2PMessage(e,r=0,s=!0,o,i=o.length){return e&&!this.p2pManager.isPeerReady(e)||!e&&!this.p2pManager.isBroadcastReady()?!1:this.p2pManager.sendP2PMessage(e,r,s,o,i)}broadcastP2PMessage(e=0,r=!0,s,o=s.length){return this.p2pManager.isBroadcastReady()?this.p2pManager.sendP2PMessage(void 0,e,r,s,o):!1}readP2PMessageFromChannel(e){return this.p2pManager.readMessageFromChannel(e)}drainP2PChannelToBuffer(e,r){return this.p2pManager.drainChannelToBuffer(e,r)}async createLobby(e,r){return this.apiCall(this.lobbyManager,"createLobby",[["visibility",re(ct,"LobbyVisibility")],["maxPlayers",M(U)]],e,r)}async joinLobby(e){return this.apiCall(this.lobbyManager,"joinLobby",[["lobbyId",C("lobbies")]],e)}async listAvailableLobbies(e=!1){return this.apiCall(this.lobbyManager,"listAvailableLobbies",[["friendsOnly",te]],e)}getLobbyUsers(e){return this.apiCallSync(this.lobbyManager,"getLobbyUsers",[["lobbyId",C("lobbies")]],e)}getNumLobbyUsers(e){return this.apiCallSync(this.lobbyManager,"getNumLobbyUsers",[["lobbyId",C("lobbies")]],e)}getLobbyHostId(e){return this.apiCallSync(this.lobbyManager,"getHostId",[["lobbyId",C("lobbies")]],e)}getLobbyData(e,r){return this.apiCallSync(this.lobbyManager,"getLobbyData",[["lobbyId",C("lobbies")],["key",y]],e,r)}setLobbyData(e,r,s){return this.apiCallSync(this.lobbyManager,"setLobbyData",[["lobbyId",C("lobbies")],["key",y],["value",hn(y,U,un)]],e,r,s)}deleteLobbyData(e,r){return this.apiCallSync(this.lobbyManager,"deleteLobbyData",[["lobbyId",C("lobbies")],["key",y]],e,r)}async leaveLobby(e){return this.apiCall(this.lobbyManager,"leaveLobby",[["lobbyId",C("lobbies")]],e)}sendLobbyMessage(e,r){return this.apiCallSync(this.lobbyManager,"sendLobbyMessage",[["lobbyId",C("lobbies")],["message",y]],e,r)}async inviteUserToLobby(e,r){return this.apiCall(this.lobbyManager,"inviteUserToLobby",[["lobbyId",C("lobbies")],["userId",C("users")]],e,r)}async getLobbyInviteLink(e=!1){return this.apiCall(this.lobbyManager,"getLobbyInviteLink",[["copyToClipboard",te]],e)}async isEntitled(e){return this.apiCall(this.paidContentManager,"isEntitled",[["contentIdentifier",y]],e)}async isEntitled_EXPERIMENTAL(e){return this.isEntitled(e)}async getEntitlements(){return this.apiCall(this.paidContentManager,"getEntitlements",[])}async getEntitlements_EXPERIMENTAL(){return this.getEntitlements()}async triggerPaywall(e){return this.apiCall(this.paidContentManager,"triggerPaywall",[["contentIdentifier",y]],e)}async triggerPaywall_EXPERIMENTAL(e){return this.triggerPaywall(e)}async updateUserPresence(e){if(typeof e=="string"){let r=e;try{e=JSON.parse(r)}catch(s){let o=`updateUserPresence: invalid JSON: ${r}`;return u.error(o,s),this.formatResponse({success:!1,data:null,message:o})}}return this.apiCall(this.heartbeatManager,"updateUserPresence",[["data",dn]],e)}isGodot(){return this.engineInstance!==null&&this.engineInstance.type===Zt.GODOT}formatResponse(e){return this.isGodot()&&e!==null&&(Array.isArray(e)||Object.getPrototypeOf(e)===Object.prototype)?JSON.stringify(e):e}ensureInit(){if(!this._initialized)throw u.error("SDK not initialized. Call WavedashJS.init first."),new Error("SDK not initialized")}async apiCall(e,r,s,...o){u.debug(r,...o);try{ne(r,s,o);let i=await e[r](...o);return this.formatResponse({success:!0,data:i})}catch(i){let a=i instanceof Error?i.message:String(i);return u.error(r,a),this.formatResponse({success:!1,data:null,message:a})}}apiCallSync(e,r,s,...o){u.debug(r,...o);try{ne(r,s,o)}catch(i){let a=i instanceof Error?i.message:String(i);throw u.error(r,a),i}return this.formatResponse(e[r](...o))}setEngineInstance(e){this.engineInstance?Object.assign(this.engineInstance,e):this.engineInstance=e}getAuthToken(e=!1){if(!e&&this.gameplayJwt)return Promise.resolve(this.gameplayJwt);if(!e&&this.gameplayJwtPromise)return this.gameplayJwtPromise;let r=this.gameplayJwtPromise,o=(async()=>{r&&await r.catch(()=>{});let a=`/auth/refresh?${new URLSearchParams({[xe.Caller]:Nr.Wavedash}).toString()}`,c=await fetch(a,{method:"POST",credentials:"same-origin"});if(!c.ok)throw new Error(`Failed to refresh gameplay token: ${c.status}`);return c.text()})().then(i=>(this.gameplayJwt=i,this.gameplayJwtPromise===o&&ke.postToParent(E.GAMEPLAY_JWT_READY,{gameplayJwt:i}),i)).finally(()=>{this.gameplayJwtPromise===o&&(this.gameplayJwtPromise=null)});return this.gameplayJwtPromise=o,o}async ensureGameplayJwt(e=!1){return this.getAuthToken(e)}destroy(){if(!this.destroyed){this.destroyed=!0;for(let e of this.managers)e.destroy()}}setupSessionEndListeners(){ke.addEventListener(E.END_SESSION,()=>this.destroy())}setupSwCredsListener(){this.swMessenger.addEventListener(Xt.EMBED_CREDS_REQUEST,async(e,r)=>{let s;try{s=await this.ensureGameplayJwt()}catch(o){u.warn("Failed to resolve JWT for creds-request",o);return}r({type:Xt.EMBED_CREDS_RESPONSE,payload:{gameplayJwt:s}})})}};function fn(){let n=window.Wavedash;if(n)return n;let t=new URLSearchParams(window.location.search).get(xe.SdkConfig)??window.__wavedashSdkConfig;if(!t)throw new Error(`Wavedash SDK: missing ?${xe.SdkConfig}= query param (or __wavedashSdkConfig global) on the page.`);let e;try{e=JSON.parse(t)}catch(s){let o=s instanceof Error?s.message:String(s);throw new Error(`Wavedash SDK: failed to parse ?${xe.SdkConfig}= as JSON: ${o}`)}cn(e.parentOrigin);let r=new ar(e);return window.Wavedash=r,window.WavedashJS=r,r}fn();})();
|
|
1
|
+
"use strict";(()=>{var bn=Object.create;var Ut=Object.defineProperty;var vn=Object.getOwnPropertyDescriptor;var wn=Object.getOwnPropertyNames;var En=Object.getPrototypeOf,Sn=Object.prototype.hasOwnProperty;var Cn=(n,t)=>()=>(t||n((t={exports:{}}).exports,t),t.exports),In=(n,t)=>{for(var e in t)Ut(n,e,{get:t[e],enumerable:!0})},Pn=(n,t,e,r)=>{if(t&&typeof t=="object"||typeof t=="function")for(let s of wn(t))!Sn.call(n,s)&&s!==e&&Ut(n,s,{get:()=>t[s],enumerable:!(r=vn(t,s))||r.enumerable});return n};var hr=(n,t,e)=>(e=n!=null?bn(En(n)):{},Pn(t||!n||!n.__esModule?Ut(e,"default",{value:n,enumerable:!0}):e,n));var cr=Cn((id,en)=>{"use strict";var Xr="Expected a function",Yr=NaN,Ws="[object Symbol]",Qs=/^\s+|\s+$/g,Hs=/^[-+]0x[0-9a-f]+$/i,js=/^0b[01]+$/i,Js=/^0o[0-7]+$/i,Ks=parseInt,zs=typeof global=="object"&&global&&global.Object===Object&&global,Ys=typeof self=="object"&&self&&self.Object===Object&&self,Zs=zs||Ys||Function("return this")(),Xs=Object.prototype,ei=Xs.toString,ti=Math.max,ri=Math.min,ar=function(){return Zs.Date.now()};function ni(n,t,e){var r,s,o,i,a,c,l=0,d=!1,p=!1,y=!0;if(typeof n!="function")throw new TypeError(Xr);t=Zr(t)||0,Pt(e)&&(d=!!e.leading,p="maxWait"in e,o=p?ti(Zr(e.maxWait)||0,t):o,y="trailing"in e?!!e.trailing:y);function h(T){var z=r,be=s;return r=s=void 0,l=T,i=n.apply(be,z),i}function m(T){return l=T,a=setTimeout(De,t),d?h(T):i}function M(T){var z=T-c,be=T-l,dr=t-z;return p?ri(dr,o-be):dr}function le(T){var z=T-c,be=T-l;return c===void 0||z>=t||z<0||p&&be>=o}function De(){var T=ar();if(le(T))return lr(T);a=setTimeout(De,M(T))}function lr(T){return a=void 0,y&&r?h(T):(r=s=void 0,i)}function mn(){a!==void 0&&clearTimeout(a),l=0,r=c=s=a=void 0}function yn(){return a===void 0?i:lr(ar())}function Ft(){var T=ar(),z=le(T);if(r=arguments,s=this,c=T,z){if(a===void 0)return m(c);if(p)return a=setTimeout(De,t),h(c)}return a===void 0&&(a=setTimeout(De,t)),i}return Ft.cancel=mn,Ft.flush=yn,Ft}function si(n,t,e){var r=!0,s=!0;if(typeof n!="function")throw new TypeError(Xr);return Pt(e)&&(r="leading"in e?!!e.leading:r,s="trailing"in e?!!e.trailing:s),ni(n,t,{leading:r,maxWait:t,trailing:s})}function Pt(n){var t=typeof n;return!!n&&(t=="object"||t=="function")}function ii(n){return!!n&&typeof n=="object"}function oi(n){return typeof n=="symbol"||ii(n)&&ei.call(n)==Ws}function Zr(n){if(typeof n=="number")return n;if(oi(n))return Yr;if(Pt(n)){var t=typeof n.valueOf=="function"?n.valueOf():n;n=Pt(t)?t+"":t}if(typeof n!="string")return n===0?n:+n;n=n.replace(Qs,"");var e=js.test(n);return e||Js.test(n)?Ks(n.slice(2),e?2:8):Hs.test(n)?Yr:+n}en.exports=si});var D="1.39.1";var he={};In(he,{byteLength:()=>An,fromByteArray:()=>oe,fromByteArrayUrlSafeNoPadding:()=>_n,toByteArray:()=>de});var q=[],N=[],Tn=Uint8Array,$t="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";for(ie=0,pr=$t.length;ie<pr;++ie)q[ie]=$t[ie],N[$t.charCodeAt(ie)]=ie;var ie,pr;N[45]=62;N[95]=63;function fr(n){var t=n.length;if(t%4>0)throw new Error("Invalid string. Length must be a multiple of 4");var e=n.indexOf("=");e===-1&&(e=t);var r=e===t?0:4-e%4;return[e,r]}function An(n){var t=fr(n),e=t[0],r=t[1];return(e+r)*3/4-r}function xn(n,t,e){return(t+e)*3/4-e}function de(n){var t,e=fr(n),r=e[0],s=e[1],o=new Tn(xn(n,r,s)),i=0,a=s>0?r-4:r,c;for(c=0;c<a;c+=4)t=N[n.charCodeAt(c)]<<18|N[n.charCodeAt(c+1)]<<12|N[n.charCodeAt(c+2)]<<6|N[n.charCodeAt(c+3)],o[i++]=t>>16&255,o[i++]=t>>8&255,o[i++]=t&255;return s===2&&(t=N[n.charCodeAt(c)]<<2|N[n.charCodeAt(c+1)]>>4,o[i++]=t&255),s===1&&(t=N[n.charCodeAt(c)]<<10|N[n.charCodeAt(c+1)]<<4|N[n.charCodeAt(c+2)]>>2,o[i++]=t>>8&255,o[i++]=t&255),o}function Mn(n){return q[n>>18&63]+q[n>>12&63]+q[n>>6&63]+q[n&63]}function Rn(n,t,e){for(var r,s=[],o=t;o<e;o+=3)r=(n[o]<<16&16711680)+(n[o+1]<<8&65280)+(n[o+2]&255),s.push(Mn(r));return s.join("")}function oe(n){for(var t,e=n.length,r=e%3,s=[],o=16383,i=0,a=e-r;i<a;i+=o)s.push(Rn(n,i,i+o>a?a:i+o));return r===1?(t=n[e-1],s.push(q[t>>2]+q[t<<4&63]+"==")):r===2&&(t=(n[e-2]<<8)+n[e-1],s.push(q[t>>10]+q[t>>4&63]+q[t<<2&63]+"=")),s.join("")}function _n(n){return oe(n).replace(/\+/g,"-").replace(/\//g,"_").replace(/=/g,"")}function _(n){if(n===void 0)return{};if(!Ne(n))throw new Error(`The arguments to a Convex function must be an object. Received: ${n}`);return n}function ve(n){if(typeof n>"u")throw new Error("Client created with undefined deployment address. If you used an environment variable, check that it's set.");if(typeof n!="string")throw new Error(`Invalid deployment address: found ${n}".`);if(!(n.startsWith("http:")||n.startsWith("https:")))throw new Error(`Invalid deployment address: Must start with "https://" or "http://". Found "${n}".`);try{new URL(n)}catch{throw new Error(`Invalid deployment address: "${n}" is not a valid URL. If you believe this URL is correct, use the \`skipConvexDeploymentUrlCheck\` option to bypass this.`)}if(n.endsWith(".convex.site"))throw new Error(`Invalid deployment address: "${n}" ends with .convex.site, which is used for HTTP Actions. Convex deployment URLs typically end with .convex.cloud? If you believe this URL is correct, use the \`skipConvexDeploymentUrlCheck\` option to bypass this.`)}function Ne(n){let t=typeof n=="object",e=Object.getPrototypeOf(n),r=e===null||e===Object.prototype||e?.constructor?.name==="Object";return t&&r}var yr=!0,pe=BigInt("-9223372036854775808"),Vt=BigInt("9223372036854775807"),Bt=BigInt("0"),Ln=BigInt("8"),kn=BigInt("256");function br(n){return Number.isNaN(n)||!Number.isFinite(n)||Object.is(n,-0)}function On(n){n<Bt&&(n-=pe+pe);let t=n.toString(16);t.length%2===1&&(t="0"+t);let e=new Uint8Array(new ArrayBuffer(8)),r=0;for(let s of t.match(/.{2}/g).reverse())e.set([parseInt(s,16)],r++),n>>=Ln;return oe(e)}function Dn(n){let t=de(n);if(t.byteLength!==8)throw new Error(`Received ${t.byteLength} bytes, expected 8 for $integer`);let e=Bt,r=Bt;for(let s of t)e+=BigInt(s)*kn**r,r++;return e>Vt&&(e+=pe+pe),e}function Nn(n){if(n<pe||Vt<n)throw new Error(`BigInt ${n} does not fit into a 64-bit signed integer.`);let t=new ArrayBuffer(8);return new DataView(t).setBigInt64(0,n,!0),oe(new Uint8Array(t))}function Fn(n){let t=de(n);if(t.byteLength!==8)throw new Error(`Received ${t.byteLength} bytes, expected 8 for $integer`);return new DataView(t.buffer).getBigInt64(0,!0)}var Un=DataView.prototype.setBigInt64?Nn:On,$n=DataView.prototype.getBigInt64?Fn:Dn,gr=1024;function Gt(n){if(n.length>gr)throw new Error(`Field name ${n} exceeds maximum field name length ${gr}.`);if(n.startsWith("$"))throw new Error(`Field name ${n} starts with a '$', which is reserved.`);for(let t=0;t<n.length;t+=1){let e=n.charCodeAt(t);if(e<32||e>=127)throw new Error(`Field name ${n} has invalid character '${n[t]}': Field names can only contain non-control ASCII characters`)}}function R(n){if(n===null||typeof n=="boolean"||typeof n=="number"||typeof n=="string")return n;if(Array.isArray(n))return n.map(r=>R(r));if(typeof n!="object")throw new Error(`Unexpected type of ${n}`);let t=Object.entries(n);if(t.length===1){let r=t[0][0];if(r==="$bytes"){if(typeof n.$bytes!="string")throw new Error(`Malformed $bytes field on ${n}`);return de(n.$bytes).buffer}if(r==="$integer"){if(typeof n.$integer!="string")throw new Error(`Malformed $integer field on ${n}`);return $n(n.$integer)}if(r==="$float"){if(typeof n.$float!="string")throw new Error(`Malformed $float field on ${n}`);let s=de(n.$float);if(s.byteLength!==8)throw new Error(`Received ${s.byteLength} bytes, expected 8 for $float`);let i=new DataView(s.buffer).getFloat64(0,yr);if(!br(i))throw new Error(`Float ${i} should be encoded as a number`);return i}if(r==="$set")throw new Error("Received a Set which is no longer supported as a Convex type.");if(r==="$map")throw new Error("Received a Map which is no longer supported as a Convex type.")}let e={};for(let[r,s]of Object.entries(n))Gt(r),e[r]=R(s);return e}var mr=16384;function ae(n){let t=JSON.stringify(n,(e,r)=>r===void 0?"undefined":typeof r=="bigint"?`${r.toString()}n`:r);if(t.length>mr){let e="[...truncated]",r=mr-e.length,s=t.codePointAt(r-1);return s!==void 0&&s>65535&&(r-=1),t.substring(0,r)+e}return t}function Fe(n,t,e,r){if(n===void 0){let i=e&&` (present at path ${e} in original object ${ae(t)})`;throw new Error(`undefined is not a valid Convex value${i}. To learn about Convex's supported types, see https://docs.convex.dev/using/types.`)}if(n===null)return n;if(typeof n=="bigint"){if(n<pe||Vt<n)throw new Error(`BigInt ${n} does not fit into a 64-bit signed integer.`);return{$integer:Un(n)}}if(typeof n=="number")if(br(n)){let i=new ArrayBuffer(8);return new DataView(i).setFloat64(0,n,yr),{$float:oe(new Uint8Array(i))}}else return n;if(typeof n=="boolean"||typeof n=="string")return n;if(n instanceof ArrayBuffer)return{$bytes:oe(new Uint8Array(n))};if(Array.isArray(n))return n.map((i,a)=>Fe(i,t,e+`[${a}]`,!1));if(n instanceof Set)throw new Error(qt(e,"Set",[...n],t));if(n instanceof Map)throw new Error(qt(e,"Map",[...n],t));if(!Ne(n)){let i=n?.constructor?.name,a=i?`${i} `:"";throw new Error(qt(e,a,n,t))}let s={},o=Object.entries(n);o.sort(([i,a],[c,l])=>i===c?0:i<c?-1:1);for(let[i,a]of o)a!==void 0?(Gt(i),s[i]=Fe(a,t,e+`.${i}`,!1)):r&&(Gt(i),s[i]=qn(a,t,e+`.${i}`));return s}function qt(n,t,e,r){return n?`${t}${ae(e)} is not a supported Convex type (present at path ${n} in original object ${ae(r)}). To learn about Convex's supported types, see https://docs.convex.dev/using/types.`:`${t}${ae(e)} is not a supported Convex type.`}function qn(n,t,e){if(n===void 0)return{$undefined:null};if(t===void 0)throw new Error(`Programming error. Current value is ${ae(n)} but original value is undefined`);return Fe(n,t,e,!1)}function A(n){return Fe(n,n,"",!1)}var Bn=Object.defineProperty,Gn=(n,t,e)=>t in n?Bn(n,t,{enumerable:!0,configurable:!0,writable:!0,value:e}):n[t]=e,S=(n,t,e)=>Gn(n,typeof t!="symbol"?t+"":t,e),Vn="https://docs.convex.dev/error#undefined-validator";function we(n,t){let e=t!==void 0?` for field "${t}"`:"";throw new Error(`A validator is undefined${e} in ${n}. This is often caused by circular imports. See ${Vn} for details.`)}var L=class{constructor({isOptional:t}){S(this,"type"),S(this,"fieldPaths"),S(this,"isOptional"),S(this,"isConvexValidator"),this.isOptional=t,this.isConvexValidator=!0}},Ue=class n extends L{constructor({isOptional:t,tableName:e}){if(super({isOptional:t}),S(this,"tableName"),S(this,"kind","id"),typeof e!="string")throw new Error("v.id(tableName) requires a string");this.tableName=e}get json(){return{type:"id",tableName:this.tableName}}asOptional(){return new n({isOptional:"optional",tableName:this.tableName})}},Ee=class n extends L{constructor(){super(...arguments),S(this,"kind","float64")}get json(){return{type:"number"}}asOptional(){return new n({isOptional:"optional"})}},Se=class n extends L{constructor(){super(...arguments),S(this,"kind","int64")}get json(){return{type:"bigint"}}asOptional(){return new n({isOptional:"optional"})}},$e=class n extends L{constructor(){super(...arguments),S(this,"kind","boolean")}get json(){return{type:this.kind}}asOptional(){return new n({isOptional:"optional"})}},qe=class n extends L{constructor(){super(...arguments),S(this,"kind","bytes")}get json(){return{type:this.kind}}asOptional(){return new n({isOptional:"optional"})}},Be=class n extends L{constructor(){super(...arguments),S(this,"kind","string")}get json(){return{type:this.kind}}asOptional(){return new n({isOptional:"optional"})}},Ge=class n extends L{constructor(){super(...arguments),S(this,"kind","null")}get json(){return{type:this.kind}}asOptional(){return new n({isOptional:"optional"})}},Ve=class n extends L{constructor(){super(...arguments),S(this,"kind","any")}get json(){return{type:this.kind}}asOptional(){return new n({isOptional:"optional"})}},We=class n extends L{constructor({isOptional:t,fields:e}){super({isOptional:t}),S(this,"fields"),S(this,"kind","object"),globalThis.Object.entries(e).forEach(([r,s])=>{if(s===void 0&&we("v.object()",r),!s.isConvexValidator)throw new Error("v.object() entries must be validators")}),this.fields=e}get json(){return{type:this.kind,value:globalThis.Object.fromEntries(globalThis.Object.entries(this.fields).map(([t,e])=>[t,{fieldType:e.json,optional:e.isOptional==="optional"}]))}}asOptional(){return new n({isOptional:"optional",fields:this.fields})}omit(...t){let e={...this.fields};for(let r of t)delete e[r];return new n({isOptional:this.isOptional,fields:e})}pick(...t){let e={};for(let r of t)e[r]=this.fields[r];return new n({isOptional:this.isOptional,fields:e})}partial(){let t={};for(let[e,r]of globalThis.Object.entries(this.fields))t[e]=r.asOptional();return new n({isOptional:this.isOptional,fields:t})}extend(t){return new n({isOptional:this.isOptional,fields:{...this.fields,...t}})}},Qe=class n extends L{constructor({isOptional:t,value:e}){if(super({isOptional:t}),S(this,"value"),S(this,"kind","literal"),typeof e!="string"&&typeof e!="boolean"&&typeof e!="number"&&typeof e!="bigint")throw new Error("v.literal(value) must be a string, number, or boolean");this.value=e}get json(){return{type:this.kind,value:A(this.value)}}asOptional(){return new n({isOptional:"optional",value:this.value})}},He=class n extends L{constructor({isOptional:t,element:e}){super({isOptional:t}),S(this,"element"),S(this,"kind","array"),e===void 0&&we("v.array()"),this.element=e}get json(){return{type:this.kind,value:this.element.json}}asOptional(){return new n({isOptional:"optional",element:this.element})}},je=class n extends L{constructor({isOptional:t,key:e,value:r}){if(super({isOptional:t}),S(this,"key"),S(this,"value"),S(this,"kind","record"),e===void 0&&we("v.record()","key"),r===void 0&&we("v.record()","value"),e.isOptional==="optional")throw new Error("Record validator cannot have optional keys");if(r.isOptional==="optional")throw new Error("Record validator cannot have optional values");if(!e.isConvexValidator||!r.isConvexValidator)throw new Error("Key and value of v.record() but be validators");this.key=e,this.value=r}get json(){return{type:this.kind,keys:this.key.json,values:{fieldType:this.value.json,optional:!1}}}asOptional(){return new n({isOptional:"optional",key:this.key,value:this.value})}},Je=class n extends L{constructor({isOptional:t,members:e}){super({isOptional:t}),S(this,"members"),S(this,"kind","union"),e.forEach((r,s)=>{if(r===void 0&&we("v.union()",`member at index ${s}`),!r.isConvexValidator)throw new Error("All members of v.union() must be validators")}),this.members=e}get json(){return{type:this.kind,value:this.members.map(t=>t.json)}}asOptional(){return new n({isOptional:"optional",members:this.members})}};function Wt(n){return!!n.isConvexValidator}var g={id:n=>new Ue({isOptional:"required",tableName:n}),null:()=>new Ge({isOptional:"required"}),number:()=>new Ee({isOptional:"required"}),float64:()=>new Ee({isOptional:"required"}),bigint:()=>new Se({isOptional:"required"}),int64:()=>new Se({isOptional:"required"}),boolean:()=>new $e({isOptional:"required"}),string:()=>new Be({isOptional:"required"}),bytes:()=>new qe({isOptional:"required"}),literal:n=>new Qe({isOptional:"required",value:n}),array:n=>new He({isOptional:"required",element:n}),object:n=>new We({isOptional:"required",fields:n}),record:(n,t)=>new je({isOptional:"required",key:n,value:t}),union:(...n)=>new Je({isOptional:"required",members:n}),any:()=>new Ve({isOptional:"required"}),optional:n=>n.asOptional(),nullable:n=>g.union(n,g.null())};var Wn=Object.defineProperty,Qn=(n,t,e)=>t in n?Wn(n,t,{enumerable:!0,configurable:!0,writable:!0,value:e}):n[t]=e,Qt=(n,t,e)=>Qn(n,typeof t!="symbol"?t+"":t,e),vr,wr,Hn=Symbol.for("ConvexError"),j=class extends(wr=Error,vr=Hn,wr){constructor(t){super(typeof t=="string"?t:ae(t)),Qt(this,"name","ConvexError"),Qt(this,"data"),Qt(this,vr,!0),this.data=t}};var Er=()=>Array.from({length:4},()=>0),Ci=Er(),Ii=Er();var Jn=Object.defineProperty,Kn=(n,t,e)=>t in n?Jn(n,t,{enumerable:!0,configurable:!0,writable:!0,value:e}):n[t]=e,Sr=(n,t,e)=>Kn(n,typeof t!="symbol"?t+"":t,e),zn="color:rgb(0, 145, 255)";function Cr(n){switch(n){case"query":return"Q";case"mutation":return"M";case"action":return"A";case"any":return"?"}}var Ke=class{constructor(t){Sr(this,"_onLogLineFuncs"),Sr(this,"_verbose"),this._onLogLineFuncs={},this._verbose=t.verbose}addLogLineListener(t){let e=Math.random().toString(36).substring(2,15);for(let r=0;r<10&&this._onLogLineFuncs[e]!==void 0;r++)e=Math.random().toString(36).substring(2,15);return this._onLogLineFuncs[e]=t,()=>{delete this._onLogLineFuncs[e]}}logVerbose(...t){if(this._verbose)for(let e of Object.values(this._onLogLineFuncs))e("debug",`${new Date().toISOString()}`,...t)}log(...t){for(let e of Object.values(this._onLogLineFuncs))e("info",...t)}warn(...t){for(let e of Object.values(this._onLogLineFuncs))e("warn",...t)}error(...t){for(let e of Object.values(this._onLogLineFuncs))e("error",...t)}};function Ht(n){let t=new Ke(n);return t.addLogLineListener((e,...r)=>{switch(e){case"debug":console.debug(...r);break;case"info":console.log(...r);break;case"warn":console.warn(...r);break;case"error":console.error(...r);break;default:console.log(...r)}}),t}function jt(n){return new Ke(n)}function ce(n,t,e,r,s){let o=Cr(e);if(typeof s=="object"&&(s=`ConvexError ${JSON.stringify(s.errorData,null,2)}`),t==="info"){let i=s.match(/^\[.*?\] /);if(i===null){n.error(`[CONVEX ${o}(${r})] Could not parse console.log`);return}let a=s.slice(1,i[0].length-2),c=s.slice(i[0].length);n.log(`%c[CONVEX ${o}(${r})] [${a}]`,zn,c)}else n.error(`[CONVEX ${o}(${r})] ${s}`)}function Ir(n,t){let e=`[CONVEX FATAL ERROR] ${t}`;return n.error(e),new Error(e)}function Y(n,t,e){return`[CONVEX ${Cr(n)}(${t})] ${e.errorMessage}
|
|
2
|
+
Called by client`}function Ce(n,t){return t.data=n.errorData,t}function B(n){let t=n.split(":"),e,r;return t.length===1?(e=t[0],r="default"):(e=t.slice(0,t.length-1).join(":"),r=t[t.length-1]),e.endsWith(".js")&&(e=e.slice(0,-3)),`${e}:${r}`}function G(n,t){return JSON.stringify({udfPath:B(n),args:A(t)})}function Jt(n,t,e){let{initialNumItems:r,id:s}=e;return JSON.stringify({type:"paginated",udfPath:B(n),args:A(t),options:A({initialNumItems:r,id:s})})}function Pr(n){return JSON.parse(n).type==="paginated"}var Yn=Object.defineProperty,Zn=(n,t,e)=>t in n?Yn(n,t,{enumerable:!0,configurable:!0,writable:!0,value:e}):n[t]=e,V=(n,t,e)=>Zn(n,typeof t!="symbol"?t+"":t,e),ze=class{constructor(){V(this,"nextQueryId"),V(this,"querySetVersion"),V(this,"querySet"),V(this,"queryIdToToken"),V(this,"identityVersion"),V(this,"auth"),V(this,"outstandingQueriesOlderThanRestart"),V(this,"outstandingAuthOlderThanRestart"),V(this,"paused"),V(this,"pendingQuerySetModifications"),this.nextQueryId=0,this.querySetVersion=0,this.identityVersion=0,this.querySet=new Map,this.queryIdToToken=new Map,this.outstandingQueriesOlderThanRestart=new Set,this.outstandingAuthOlderThanRestart=!1,this.paused=!1,this.pendingQuerySetModifications=new Map}hasSyncedPastLastReconnect(){return this.outstandingQueriesOlderThanRestart.size===0&&!this.outstandingAuthOlderThanRestart}markAuthCompletion(){this.outstandingAuthOlderThanRestart=!1}subscribe(t,e,r,s){let o=B(t),i=G(o,e),a=this.querySet.get(i);if(a!==void 0)return a.numSubscribers+=1,{queryToken:i,modification:null,unsubscribe:()=>this.removeSubscriber(i)};{let c=this.nextQueryId++,l={id:c,canonicalizedUdfPath:o,args:e,numSubscribers:1,journal:r,componentPath:s};this.querySet.set(i,l),this.queryIdToToken.set(c,i);let d=this.querySetVersion,p=this.querySetVersion+1,y={type:"Add",queryId:c,udfPath:o,args:[A(e)],journal:r,componentPath:s};return this.paused?this.pendingQuerySetModifications.set(c,y):this.querySetVersion=p,{queryToken:i,modification:{type:"ModifyQuerySet",baseVersion:d,newVersion:p,modifications:[y]},unsubscribe:()=>this.removeSubscriber(i)}}}transition(t){for(let e of t.modifications)switch(e.type){case"QueryUpdated":case"QueryFailed":{this.outstandingQueriesOlderThanRestart.delete(e.queryId);let r=e.journal;if(r!==void 0){let s=this.queryIdToToken.get(e.queryId);s!==void 0&&(this.querySet.get(s).journal=r)}break}case"QueryRemoved":{this.outstandingQueriesOlderThanRestart.delete(e.queryId);break}default:throw new Error(`Invalid modification ${e.type}`)}}queryId(t,e){let r=B(t),s=G(r,e),o=this.querySet.get(s);return o!==void 0?o.id:null}isCurrentOrNewerAuthVersion(t){return t>=this.identityVersion}getAuth(){return this.auth}setAuth(t){this.auth={tokenType:"User",value:t};let e=this.identityVersion;return this.paused||(this.identityVersion=e+1),{type:"Authenticate",baseVersion:e,...this.auth}}setAdminAuth(t,e){let r={tokenType:"Admin",value:t,impersonating:e};this.auth=r;let s=this.identityVersion;return this.paused||(this.identityVersion=s+1),{type:"Authenticate",baseVersion:s,...r}}clearAuth(){this.auth=void 0,this.markAuthCompletion();let t=this.identityVersion;return this.paused||(this.identityVersion=t+1),{type:"Authenticate",tokenType:"None",baseVersion:t}}hasAuth(){return!!this.auth}isNewAuth(t){return this.auth?.value!==t}queryPath(t){let e=this.queryIdToToken.get(t);return e?this.querySet.get(e).canonicalizedUdfPath:null}queryArgs(t){let e=this.queryIdToToken.get(t);return e?this.querySet.get(e).args:null}queryToken(t){return this.queryIdToToken.get(t)??null}queryJournal(t){return this.querySet.get(t)?.journal}restart(){this.unpause(),this.outstandingQueriesOlderThanRestart.clear();let t=[];for(let s of this.querySet.values()){let o={type:"Add",queryId:s.id,udfPath:s.canonicalizedUdfPath,args:[A(s.args)],journal:s.journal,componentPath:s.componentPath};t.push(o),this.outstandingQueriesOlderThanRestart.add(s.id)}this.querySetVersion=1;let e={type:"ModifyQuerySet",baseVersion:0,newVersion:1,modifications:t};if(!this.auth)return this.identityVersion=0,[e,void 0];this.outstandingAuthOlderThanRestart=!0;let r={type:"Authenticate",baseVersion:0,...this.auth};return this.identityVersion=1,[e,r]}pause(){this.paused=!0}resume(){let t=this.pendingQuerySetModifications.size>0?{type:"ModifyQuerySet",baseVersion:this.querySetVersion,newVersion:++this.querySetVersion,modifications:Array.from(this.pendingQuerySetModifications.values())}:void 0,e=this.auth!==void 0?{type:"Authenticate",baseVersion:this.identityVersion++,...this.auth}:void 0;return this.unpause(),[t,e]}unpause(){this.paused=!1,this.pendingQuerySetModifications.clear()}removeSubscriber(t){let e=this.querySet.get(t);if(e.numSubscribers>1)return e.numSubscribers-=1,null;{this.querySet.delete(t),this.queryIdToToken.delete(e.id),this.outstandingQueriesOlderThanRestart.delete(e.id);let r=this.querySetVersion,s=this.querySetVersion+1,o={type:"Remove",queryId:e.id};return this.paused?this.pendingQuerySetModifications.has(e.id)?this.pendingQuerySetModifications.delete(e.id):this.pendingQuerySetModifications.set(e.id,o):this.querySetVersion=s,{type:"ModifyQuerySet",baseVersion:r,newVersion:s,modifications:[o]}}}};var Xn=Object.defineProperty,es=(n,t,e)=>t in n?Xn(n,t,{enumerable:!0,configurable:!0,writable:!0,value:e}):n[t]=e,Ye=(n,t,e)=>es(n,typeof t!="symbol"?t+"":t,e),Ze=class{constructor(t,e){this.logger=t,this.markConnectionStateDirty=e,Ye(this,"inflightRequests"),Ye(this,"requestsOlderThanRestart"),Ye(this,"inflightMutationsCount",0),Ye(this,"inflightActionsCount",0),this.inflightRequests=new Map,this.requestsOlderThanRestart=new Set}request(t,e){let r=new Promise(s=>{let o=e?"Requested":"NotSent";this.inflightRequests.set(t.requestId,{message:t,status:{status:o,requestedAt:new Date,onResult:s}}),t.type==="Mutation"?this.inflightMutationsCount++:t.type==="Action"&&this.inflightActionsCount++});return this.markConnectionStateDirty(),r}onResponse(t){let e=this.inflightRequests.get(t.requestId);if(e===void 0||e.status.status==="Completed")return null;let r=e.message.type==="Mutation"?"mutation":"action",s=e.message.udfPath;for(let c of t.logLines)ce(this.logger,"info",r,s,c);let o=e.status,i,a;if(t.success)i={success:!0,logLines:t.logLines,value:R(t.result)},a=()=>o.onResult(i);else{let c=t.result,{errorData:l}=t;ce(this.logger,"error",r,s,c),i={success:!1,errorMessage:c,errorData:l!==void 0?R(l):void 0,logLines:t.logLines},a=()=>o.onResult(i)}return t.type==="ActionResponse"||!t.success?(a(),this.inflightRequests.delete(t.requestId),this.requestsOlderThanRestart.delete(t.requestId),e.message.type==="Action"?this.inflightActionsCount--:e.message.type==="Mutation"&&this.inflightMutationsCount--,this.markConnectionStateDirty(),{requestId:t.requestId,result:i}):(e.status={status:"Completed",result:i,ts:t.ts,onResolve:a},null)}removeCompleted(t){let e=new Map;for(let[r,s]of this.inflightRequests.entries()){let o=s.status;o.status==="Completed"&&o.ts.lessThanOrEqual(t)&&(o.onResolve(),e.set(r,o.result),s.message.type==="Mutation"?this.inflightMutationsCount--:s.message.type==="Action"&&this.inflightActionsCount--,this.inflightRequests.delete(r),this.requestsOlderThanRestart.delete(r))}return e.size>0&&this.markConnectionStateDirty(),e}restart(){this.requestsOlderThanRestart=new Set(this.inflightRequests.keys());let t=[];for(let[e,r]of this.inflightRequests){if(r.status.status==="NotSent"){r.status.status="Requested",t.push(r.message);continue}if(r.message.type==="Mutation")t.push(r.message);else if(r.message.type==="Action"){if(this.inflightRequests.delete(e),this.requestsOlderThanRestart.delete(e),this.inflightActionsCount--,r.status.status==="Completed")throw new Error("Action should never be in 'Completed' state");r.status.onResult({success:!1,errorMessage:"Connection lost while action was in flight",logLines:[]})}}return this.markConnectionStateDirty(),t}resume(){let t=[];for(let[,e]of this.inflightRequests)if(e.status.status==="NotSent"){e.status.status="Requested",t.push(e.message);continue}return t}hasIncompleteRequests(){for(let t of this.inflightRequests.values())if(t.status.status==="Requested")return!0;return!1}hasInflightRequests(){return this.inflightRequests.size>0}hasSyncedPastLastReconnect(){return this.requestsOlderThanRestart.size===0}timeOfOldestInflightRequest(){if(this.inflightRequests.size===0)return null;let t=Date.now();for(let e of this.inflightRequests.values())e.status.status!=="Completed"&&e.status.requestedAt.getTime()<t&&(t=e.status.requestedAt.getTime());return new Date(t)}inflightMutations(){return this.inflightMutationsCount}inflightActions(){return this.inflightActionsCount}};var fe=Symbol.for("functionName");var Tr=Symbol.for("toReferencePath");function ts(n){return n[Tr]??null}function rs(n){return n.startsWith("function://")}function Z(n){let t;if(typeof n=="string")rs(n)?t={functionHandle:n}:t={name:n};else if(n[fe])t={name:n[fe]};else{let e=ts(n);if(!e)throw new Error(`${n} is not a functionReference`);t={reference:e}}return t}function O(n){let t=Z(n);if(t.name===void 0)throw t.functionHandle!==void 0?new Error(`Expected function reference like "api.file.func" or "internal.file.func", but received function handle ${t.functionHandle}`):t.reference!==void 0?new Error(`Expected function reference in the current component like "api.file.func" or "internal.file.func", but received reference ${t.reference}`):new Error(`Expected function reference like "api.file.func" or "internal.file.func", but received ${JSON.stringify(t)}`);if(typeof n=="string")return n;let e=n[fe];if(!e)throw new Error(`${n} is not a functionReference`);return e}function Ar(n=[]){let t={get(e,r){if(typeof r=="string"){let s=[...n,r];return Ar(s)}else if(r===fe){if(n.length<2){let i=["api",...n].join(".");throw new Error(`API path is expected to be of the form \`api.moduleName.functionName\`. Found: \`${i}\``)}let s=n.slice(0,-1).join("/"),o=n[n.length-1];return o==="default"?s:s+":"+o}else return r===Symbol.toStringTag?"FunctionReference":void 0}};return new Proxy({},t)}var Kt=Ar();var ns=Object.defineProperty,ss=(n,t,e)=>t in n?ns(n,t,{enumerable:!0,configurable:!0,writable:!0,value:e}):n[t]=e,Xe=(n,t,e)=>ss(n,typeof t!="symbol"?t+"":t,e),et=class n{constructor(t){Xe(this,"queryResults"),Xe(this,"modifiedQueries"),this.queryResults=t,this.modifiedQueries=[]}getQuery(t,...e){let r=_(e[0]),s=O(t),o=this.queryResults.get(G(s,r));if(o!==void 0)return n.queryValue(o.result)}getAllQueries(t){let e=[],r=O(t);for(let s of this.queryResults.values())s.udfPath===B(r)&&e.push({args:s.args,value:n.queryValue(s.result)});return e}setQuery(t,e,r){let s=_(e),o=O(t),i=G(o,s),a;r===void 0?a=void 0:a={success:!0,value:r,logLines:[]};let c={udfPath:o,args:s,result:a};this.queryResults.set(i,c),this.modifiedQueries.push(i)}static queryValue(t){if(t!==void 0)return t.success?t.value:void 0}},tt=class{constructor(){Xe(this,"queryResults"),Xe(this,"optimisticUpdates"),this.queryResults=new Map,this.optimisticUpdates=[]}ingestQueryResultsFromServer(t,e){this.optimisticUpdates=this.optimisticUpdates.filter(i=>!e.has(i.mutationId));let r=this.queryResults;this.queryResults=new Map(t);let s=new et(this.queryResults);for(let i of this.optimisticUpdates)i.update(s);let o=[];for(let[i,a]of this.queryResults){let c=r.get(i);(c===void 0||c.result!==a.result)&&o.push(i)}return o}applyOptimisticUpdate(t,e){this.optimisticUpdates.push({update:t,mutationId:e});let r=new et(this.queryResults);return t(r),r.modifiedQueries}rawQueryResult(t){let e=this.queryResults.get(t);if(e!==void 0)return e.result}queryResult(t){let e=this.queryResults.get(t);if(e===void 0)return;let r=e.result;if(r!==void 0){if(r.success)return r.value;throw r.errorData!==void 0?Ce(r,new j(Y("query",e.udfPath,r))):new Error(Y("query",e.udfPath,r))}}hasQueryResult(t){return this.queryResults.get(t)!==void 0}queryLogs(t){return this.queryResults.get(t)?.result?.logLines}};var is=Object.defineProperty,os=(n,t,e)=>t in n?is(n,t,{enumerable:!0,configurable:!0,writable:!0,value:e}):n[t]=e,zt=(n,t,e)=>os(n,typeof t!="symbol"?t+"":t,e),W=class n{constructor(t,e){zt(this,"low"),zt(this,"high"),zt(this,"__isUnsignedLong__"),this.low=t|0,this.high=e|0,this.__isUnsignedLong__=!0}static isLong(t){return(t&&t.__isUnsignedLong__)===!0}static fromBytesLE(t){return new n(t[0]|t[1]<<8|t[2]<<16|t[3]<<24,t[4]|t[5]<<8|t[6]<<16|t[7]<<24)}toBytesLE(){let t=this.high,e=this.low;return[e&255,e>>>8&255,e>>>16&255,e>>>24,t&255,t>>>8&255,t>>>16&255,t>>>24]}static fromNumber(t){return isNaN(t)||t<0?xr:t>=as?cs:new n(t%Ie|0,t/Ie|0)}toString(){return(BigInt(this.high)*BigInt(Ie)+BigInt(this.low)).toString()}equals(t){return n.isLong(t)||(t=n.fromValue(t)),this.high>>>31===1&&t.high>>>31===1?!1:this.high===t.high&&this.low===t.low}notEquals(t){return!this.equals(t)}comp(t){return n.isLong(t)||(t=n.fromValue(t)),this.equals(t)?0:t.high>>>0>this.high>>>0||t.high===this.high&&t.low>>>0>this.low>>>0?-1:1}lessThanOrEqual(t){return this.comp(t)<=0}static fromValue(t){return typeof t=="number"?n.fromNumber(t):new n(t.low,t.high)}},xr=new W(0,0),Mr=65536,Ie=Mr*Mr,as=Ie*Ie,cs=new W(-1,-1);var us=Object.defineProperty,ls=(n,t,e)=>t in n?us(n,t,{enumerable:!0,configurable:!0,writable:!0,value:e}):n[t]=e,rt=(n,t,e)=>ls(n,typeof t!="symbol"?t+"":t,e),Pe=class{constructor(t,e){rt(this,"version"),rt(this,"remoteQuerySet"),rt(this,"queryPath"),rt(this,"logger"),this.version={querySet:0,ts:W.fromNumber(0),identity:0},this.remoteQuerySet=new Map,this.queryPath=t,this.logger=e}transition(t){let e=t.startVersion;if(this.version.querySet!==e.querySet||this.version.ts.notEquals(e.ts)||this.version.identity!==e.identity)throw new Error(`Invalid start version: ${e.ts.toString()}:${e.querySet}:${e.identity}, transitioning from ${this.version.ts.toString()}:${this.version.querySet}:${this.version.identity}`);for(let r of t.modifications)switch(r.type){case"QueryUpdated":{let s=this.queryPath(r.queryId);if(s)for(let i of r.logLines)ce(this.logger,"info","query",s,i);let o=R(r.value??null);this.remoteQuerySet.set(r.queryId,{success:!0,value:o,logLines:r.logLines});break}case"QueryFailed":{let s=this.queryPath(r.queryId);if(s)for(let i of r.logLines)ce(this.logger,"info","query",s,i);let{errorData:o}=r;this.remoteQuerySet.set(r.queryId,{success:!1,errorMessage:r.errorMessage,errorData:o!==void 0?R(o):void 0,logLines:r.logLines});break}case"QueryRemoved":{this.remoteQuerySet.delete(r.queryId);break}default:throw new Error(`Invalid modification ${r.type}`)}this.version=t.endVersion}remoteQueryResults(){return this.remoteQuerySet}timestamp(){return this.version.ts}};function Yt(n){let t=he.toByteArray(n);return W.fromBytesLE(Array.from(t))}function ds(n){let t=new Uint8Array(n.toBytesLE());return he.fromByteArray(t)}function Zt(n){switch(n.type){case"FatalError":case"AuthError":case"ActionResponse":case"TransitionChunk":case"Ping":return{...n};case"MutationResponse":return n.success?{...n,ts:Yt(n.ts)}:{...n};case"Transition":return{...n,startVersion:{...n.startVersion,ts:Yt(n.startVersion.ts)},endVersion:{...n.endVersion,ts:Yt(n.endVersion.ts)}};default:}}function Rr(n){switch(n.type){case"Authenticate":case"ModifyQuerySet":case"Mutation":case"Action":case"Event":return{...n};case"Connect":return n.maxObservedTimestamp!==void 0?{...n,maxObservedTimestamp:ds(n.maxObservedTimestamp)}:{...n,maxObservedTimestamp:void 0};default:}}var hs=Object.defineProperty,ps=(n,t,e)=>t in n?hs(n,t,{enumerable:!0,configurable:!0,writable:!0,value:e}):n[t]=e,I=(n,t,e)=>ps(n,typeof t!="symbol"?t+"":t,e),fs=1e3,gs=1001,ms=1005,ys=4040,nt;function ge(){return nt===void 0&&(nt=Date.now()),typeof performance>"u"||!performance.now?Date.now():Math.round(nt+performance.now())}function _r(){return`t=${Math.round((ge()-nt)/100)/10}s`}var Lr={InternalServerError:{timeout:1e3},SubscriptionsWorkerFullError:{timeout:3e3},TooManyConcurrentRequests:{timeout:3e3},CommitterFullError:{timeout:3e3},AwsTooManyRequestsException:{timeout:3e3},ExecuteFullError:{timeout:3e3},SystemTimeoutError:{timeout:3e3},ExpiredInQueue:{timeout:3e3},VectorIndexesUnavailable:{timeout:1e3},SearchIndexesUnavailable:{timeout:1e3},TableSummariesUnavailable:{timeout:1e3},VectorIndexTooLarge:{timeout:3e3},SearchIndexTooLarge:{timeout:3e3},TooManyWritesInTimePeriod:{timeout:3e3}};function bs(n){if(n===void 0)return"Unknown";for(let t of Object.keys(Lr))if(n.startsWith(t))return t;return"Unknown"}var st=class{constructor(t,e,r,s,o,i){this.markConnectionStateDirty=o,this.debug=i,I(this,"socket"),I(this,"connectionCount"),I(this,"_hasEverConnected",!1),I(this,"lastCloseReason"),I(this,"transitionChunkBuffer",null),I(this,"defaultInitialBackoff"),I(this,"maxBackoff"),I(this,"retries"),I(this,"serverInactivityThreshold"),I(this,"reconnectDueToServerInactivityTimeout"),I(this,"scheduledReconnect",null),I(this,"networkOnlineHandler",null),I(this,"pendingNetworkRecoveryInfo",null),I(this,"uri"),I(this,"onOpen"),I(this,"onResume"),I(this,"onMessage"),I(this,"webSocketConstructor"),I(this,"logger"),I(this,"onServerDisconnectError"),this.webSocketConstructor=r,this.socket={state:"disconnected"},this.connectionCount=0,this.lastCloseReason="InitialConnect",this.defaultInitialBackoff=1e3,this.maxBackoff=16e3,this.retries=0,this.serverInactivityThreshold=6e4,this.reconnectDueToServerInactivityTimeout=null,this.uri=t,this.onOpen=e.onOpen,this.onResume=e.onResume,this.onMessage=e.onMessage,this.onServerDisconnectError=e.onServerDisconnectError,this.logger=s,this.setupNetworkListener(),this.connect()}setSocketState(t){this.socket=t,this._logVerbose(`socket state changed: ${this.socket.state}, paused: ${"paused"in this.socket?this.socket.paused:void 0}`),this.markConnectionStateDirty()}setupNetworkListener(){typeof window>"u"||typeof window.addEventListener!="function"||this.networkOnlineHandler===null&&(this.networkOnlineHandler=()=>{this._logVerbose("network online event detected"),this.tryReconnectImmediately()},window.addEventListener("online",this.networkOnlineHandler),this._logVerbose("network online event listener registered"))}cleanupNetworkListener(){this.networkOnlineHandler&&typeof window<"u"&&typeof window.removeEventListener=="function"&&(window.removeEventListener("online",this.networkOnlineHandler),this.networkOnlineHandler=null,this._logVerbose("network online event listener removed"))}assembleTransition(t){if(t.partNumber<0||t.partNumber>=t.totalParts||t.totalParts===0||this.transitionChunkBuffer&&(this.transitionChunkBuffer.totalParts!==t.totalParts||this.transitionChunkBuffer.transitionId!==t.transitionId))throw this.transitionChunkBuffer=null,new Error("Invalid TransitionChunk");if(this.transitionChunkBuffer===null&&(this.transitionChunkBuffer={chunks:[],totalParts:t.totalParts,transitionId:t.transitionId}),t.partNumber!==this.transitionChunkBuffer.chunks.length){let e=this.transitionChunkBuffer.chunks.length;throw this.transitionChunkBuffer=null,new Error(`TransitionChunk received out of order: expected part ${e}, got ${t.partNumber}`)}if(this.transitionChunkBuffer.chunks.push(t.chunk),this.transitionChunkBuffer.chunks.length===t.totalParts){let e=this.transitionChunkBuffer.chunks.join("");this.transitionChunkBuffer=null;let r=Zt(JSON.parse(e));if(r.type!=="Transition")throw new Error(`Expected Transition, got ${r.type} after assembling chunks`);return r}return null}connect(){if(this.socket.state==="terminated")return;if(this.socket.state!=="disconnected"&&this.socket.state!=="stopped")throw new Error("Didn't start connection from disconnected state: "+this.socket.state);let t=new this.webSocketConstructor(this.uri);this._logVerbose("constructed WebSocket"),this.setSocketState({state:"connecting",ws:t,paused:"no"}),this.resetServerInactivityTimeout(),t.onopen=()=>{if(this.logger.logVerbose("begin ws.onopen"),this.socket.state!=="connecting")throw new Error("onopen called with socket not in connecting state");if(this.setSocketState({state:"ready",ws:t,paused:this.socket.paused==="yes"?"uninitialized":"no"}),this.resetServerInactivityTimeout(),this.socket.paused==="no"&&(this._hasEverConnected=!0,this.onOpen({connectionCount:this.connectionCount,lastCloseReason:this.lastCloseReason,clientTs:ge()})),this.lastCloseReason!=="InitialConnect"&&(this.lastCloseReason?this.logger.log("WebSocket reconnected at",_r(),"after disconnect due to",this.lastCloseReason):this.logger.log("WebSocket reconnected at",_r())),this.connectionCount+=1,this.lastCloseReason=null,this.pendingNetworkRecoveryInfo!==null){let{timeSavedMs:e}=this.pendingNetworkRecoveryInfo;this.pendingNetworkRecoveryInfo=null,this.sendMessage({type:"Event",eventType:"NetworkRecoveryReconnect",event:{timeSavedMs:e}}),this.logger.log(`Network recovery reconnect saved ~${Math.round(e/1e3)}s of waiting`)}},t.onerror=e=>{this.transitionChunkBuffer=null;let r=e.message;r&&this.logger.log(`WebSocket error message: ${r}`)},t.onmessage=e=>{this.resetServerInactivityTimeout();let r=e.data.length,s=Zt(JSON.parse(e.data));if(this._logVerbose(`received ws message with type ${s.type}`),s.type==="Ping")return;if(s.type==="TransitionChunk"){let i=this.assembleTransition(s);if(!i)return;s=i,this._logVerbose(`assembled full ws message of type ${s.type}`)}this.transitionChunkBuffer!==null&&(this.transitionChunkBuffer=null,this.logger.log(`Received unexpected ${s.type} while buffering TransitionChunks`)),s.type==="Transition"&&this.reportLargeTransition({messageLength:r,transition:s}),this.onMessage(s).hasSyncedPastLastReconnect&&(this.retries=0,this.markConnectionStateDirty())},t.onclose=e=>{if(this._logVerbose("begin ws.onclose"),this.transitionChunkBuffer=null,this.lastCloseReason===null&&(this.lastCloseReason=e.reason||`closed with code ${e.code}`),e.code!==fs&&e.code!==gs&&e.code!==ms&&e.code!==ys){let s=`WebSocket closed with code ${e.code}`;e.reason&&(s+=`: ${e.reason}`),this.logger.log(s),this.onServerDisconnectError&&e.reason&&this.onServerDisconnectError(s)}let r=bs(e.reason);this.scheduleReconnect(r)}}socketState(){return this.socket.state}sendMessage(t){let e={type:t.type,...t.type==="Authenticate"&&t.tokenType==="User"?{value:`...${t.value.slice(-7)}`}:{}};if(this.socket.state==="ready"&&this.socket.paused==="no"){let r=Rr(t),s=JSON.stringify(r),o=!1;try{this.socket.ws.send(s),o=!0}catch(i){this.logger.log(`Failed to send message on WebSocket, reconnecting: ${i}`),this.closeAndReconnect("FailedToSendMessage")}return this._logVerbose(`${o?"sent":"failed to send"} message with type ${t.type}: ${JSON.stringify(e)}`),!0}return this._logVerbose(`message not sent (socket state: ${this.socket.state}, paused: ${"paused"in this.socket?this.socket.paused:void 0}): ${JSON.stringify(e)}`),!1}resetServerInactivityTimeout(){this.socket.state!=="terminated"&&(this.reconnectDueToServerInactivityTimeout!==null&&(clearTimeout(this.reconnectDueToServerInactivityTimeout),this.reconnectDueToServerInactivityTimeout=null),this.reconnectDueToServerInactivityTimeout=setTimeout(()=>{this.closeAndReconnect("InactiveServer")},this.serverInactivityThreshold))}scheduleReconnect(t){this.scheduledReconnect&&(clearTimeout(this.scheduledReconnect.timeout),this.scheduledReconnect=null),this.socket={state:"disconnected"};let e=this.nextBackoff(t);this.markConnectionStateDirty(),this.logger.log(`Attempting reconnect in ${Math.round(e)}ms`);let r=ge(),s=setTimeout(()=>{this.scheduledReconnect?.timeout===s&&(this.scheduledReconnect=null,this.connect())},e);this.scheduledReconnect={timeout:s,scheduledAt:r,backoffMs:e}}closeAndReconnect(t){switch(this._logVerbose(`begin closeAndReconnect with reason ${t}`),this.socket.state){case"disconnected":case"terminated":case"stopped":return;case"connecting":case"ready":{this.lastCloseReason=t,this.close(),this.scheduleReconnect("client");return}default:this.socket}}close(){switch(this.transitionChunkBuffer=null,this.socket.state){case"disconnected":case"terminated":case"stopped":return Promise.resolve();case"connecting":{let t=this.socket.ws;return t.onmessage=e=>{this._logVerbose("Ignoring message received after close")},new Promise(e=>{t.onclose=()=>{this._logVerbose("Closed after connecting"),e()},t.onopen=()=>{this._logVerbose("Opened after connecting"),t.close()}})}case"ready":{this._logVerbose("ws.close called");let t=this.socket.ws;t.onmessage=r=>{this._logVerbose("Ignoring message received after close")};let e=new Promise(r=>{t.onclose=()=>{r()}});return t.close(),e}default:return this.socket,Promise.resolve()}}terminate(){switch(this.reconnectDueToServerInactivityTimeout&&clearTimeout(this.reconnectDueToServerInactivityTimeout),this.scheduledReconnect&&(clearTimeout(this.scheduledReconnect.timeout),this.scheduledReconnect=null),this.cleanupNetworkListener(),this.socket.state){case"terminated":case"stopped":case"disconnected":case"connecting":case"ready":{let t=this.close();return this.setSocketState({state:"terminated"}),t}default:throw this.socket,new Error(`Invalid websocket state: ${this.socket.state}`)}}stop(){switch(this.socket.state){case"terminated":return Promise.resolve();case"connecting":case"stopped":case"disconnected":case"ready":{this.cleanupNetworkListener();let t=this.close();return this.socket={state:"stopped"},t}default:return this.socket,Promise.resolve()}}tryRestart(){switch(this.socket.state){case"stopped":break;case"terminated":case"connecting":case"ready":case"disconnected":this.logger.logVerbose("Restart called without stopping first");return;default:this.socket}this.setupNetworkListener(),this.connect()}pause(){switch(this.socket.state){case"disconnected":case"stopped":case"terminated":return;case"connecting":case"ready":{this.socket={...this.socket,paused:"yes"};return}default:{this.socket;return}}}tryReconnectImmediately(){if(this._logVerbose("tryReconnectImmediately called"),this.socket.state!=="disconnected"){this._logVerbose(`tryReconnectImmediately called but socket state is ${this.socket.state}, no action taken`);return}let t=null;if(this.scheduledReconnect){let e=ge()-this.scheduledReconnect.scheduledAt;t=Math.max(0,this.scheduledReconnect.backoffMs-e),this._logVerbose(`would have waited ${Math.round(t)}ms more (backoff was ${Math.round(this.scheduledReconnect.backoffMs)}ms, elapsed ${Math.round(e)}ms)`),clearTimeout(this.scheduledReconnect.timeout),this.scheduledReconnect=null,this._logVerbose("canceled scheduled reconnect")}this.logger.log("Network recovery detected, reconnecting immediately"),this.pendingNetworkRecoveryInfo=t!==null?{timeSavedMs:t}:null,this.connect()}resume(){switch(this.socket.state){case"connecting":this.socket={...this.socket,paused:"no"};return;case"ready":this.socket.paused==="uninitialized"?(this.socket={...this.socket,paused:"no"},this._hasEverConnected=!0,this.onOpen({connectionCount:this.connectionCount,lastCloseReason:this.lastCloseReason,clientTs:ge()})):this.socket.paused==="yes"&&(this.socket={...this.socket,paused:"no"},this.onResume());return;case"terminated":case"stopped":case"disconnected":return;default:this.socket}this.connect()}connectionState(){return{isConnected:this.socket.state==="ready",hasEverConnected:this._hasEverConnected,connectionCount:this.connectionCount,connectionRetries:this.retries}}_logVerbose(t){this.logger.logVerbose(t)}nextBackoff(t){let r=(t==="client"?100:t==="Unknown"?this.defaultInitialBackoff:Lr[t].timeout)*Math.pow(2,this.retries);this.retries+=1;let s=Math.min(r,this.maxBackoff),o=s*(Math.random()-.5);return s+o}reportLargeTransition({transition:t,messageLength:e}){if(t.clientClockSkew===void 0||t.serverTs===void 0)return;let r=ge()-t.clientClockSkew-t.serverTs/1e6,s=`${Math.round(r)}ms`,o=`${Math.round(e/1e4)/100}MB`,i=e/(r/1e3),a=`${Math.round(i/1e4)/100}MB per second`;this._logVerbose(`received ${o} transition in ${s} at ${a}`),e>2e7?this.logger.log(`received query results totaling more that 20MB (${o}) which will take a long time to download on slower connections`):r>2e4&&this.logger.log(`received query results totaling ${o} which took more than 20s to arrive (${s})`),this.debug&&this.sendMessage({type:"Event",eventType:"ClientReceivedTransition",event:{transitionTransitTime:r,messageLength:e}})}};function kr(){return vs()}function vs(){return"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,n=>{let t=Math.random()*16|0;return(n==="x"?t:t&3|8).toString(16)})}var ue=class extends Error{};ue.prototype.name="InvalidTokenError";function ws(n){return decodeURIComponent(atob(n).replace(/(.)/g,(t,e)=>{let r=e.charCodeAt(0).toString(16).toUpperCase();return r.length<2&&(r="0"+r),"%"+r}))}function Es(n){let t=n.replace(/-/g,"+").replace(/_/g,"/");switch(t.length%4){case 0:break;case 2:t+="==";break;case 3:t+="=";break;default:throw new Error("base64 string is not of the correct length")}try{return ws(t)}catch{return atob(t)}}function it(n,t){if(typeof n!="string")throw new ue("Invalid token specified: must be a string");t||(t={});let e=t.header===!0?0:1,r=n.split(".")[e];if(typeof r!="string")throw new ue(`Invalid token specified: missing part #${e+1}`);let s;try{s=Es(r)}catch(o){throw new ue(`Invalid token specified: invalid base64 for part #${e+1} (${o.message})`)}try{return JSON.parse(s)}catch(o){throw new ue(`Invalid token specified: invalid json for part #${e+1} (${o.message})`)}}var Ss=Object.defineProperty,Cs=(n,t,e)=>t in n?Ss(n,t,{enumerable:!0,configurable:!0,writable:!0,value:e}):n[t]=e,F=(n,t,e)=>Cs(n,typeof t!="symbol"?t+"":t,e),Is=480*60*60*1e3,Or=2,ot=class{constructor(t,e,r){F(this,"authState",{state:"noAuth"}),F(this,"configVersion",0),F(this,"syncState"),F(this,"authenticate"),F(this,"stopSocket"),F(this,"tryRestartSocket"),F(this,"pauseSocket"),F(this,"resumeSocket"),F(this,"clearAuth"),F(this,"logger"),F(this,"refreshTokenLeewaySeconds"),F(this,"tokenConfirmationAttempts",0),this.syncState=t,this.authenticate=e.authenticate,this.stopSocket=e.stopSocket,this.tryRestartSocket=e.tryRestartSocket,this.pauseSocket=e.pauseSocket,this.resumeSocket=e.resumeSocket,this.clearAuth=e.clearAuth,this.logger=r.logger,this.refreshTokenLeewaySeconds=r.refreshTokenLeewaySeconds}async setConfig(t,e){this.resetAuthState(),this._logVerbose("pausing WS for auth token fetch"),this.pauseSocket();let r=await this.fetchTokenAndGuardAgainstRace(t,{forceRefreshToken:!1});r.isFromOutdatedConfig||(r.value?(this.setAuthState({state:"waitingForServerConfirmationOfCachedToken",config:{fetchToken:t,onAuthChange:e},hasRetried:!1}),this.authenticate(r.value)):(this.setAuthState({state:"initialRefetch",config:{fetchToken:t,onAuthChange:e}}),await this.refetchToken()),this._logVerbose("resuming WS after auth token fetch"),this.resumeSocket())}onTransition(t){if(this.syncState.isCurrentOrNewerAuthVersion(t.endVersion.identity)&&!(t.endVersion.identity<=t.startVersion.identity)){if(this._logVerbose(`auth state is ${this.authState.state} when handling transition`),this.syncState.markAuthCompletion(),this.authState.state==="waitingForServerConfirmationOfCachedToken"){this._logVerbose("server confirmed auth token is valid"),this.refetchToken(),this.authState.config.onAuthChange(!0);return}this.authState.state==="waitingForServerConfirmationOfFreshToken"&&(this._logVerbose("server confirmed new auth token is valid"),this.scheduleTokenRefetch(this.authState.token),this.tokenConfirmationAttempts=0,this.authState.hadAuth||this.authState.config.onAuthChange(!0))}}onAuthError(t){if(t.authUpdateAttempted===!1&&(this.authState.state==="waitingForServerConfirmationOfFreshToken"||this.authState.state==="waitingForServerConfirmationOfCachedToken")){this._logVerbose("ignoring non-auth token expired error");return}let{baseVersion:e}=t;if(!this.syncState.isCurrentOrNewerAuthVersion(e+1)){this._logVerbose("ignoring auth error for previous auth attempt");return}this.tryToReauthenticate(t)}async tryToReauthenticate(t){if(this._logVerbose(`attempting to reauthenticate: ${t.error}`),this.authState.state==="noAuth"||this.authState.state==="waitingForServerConfirmationOfFreshToken"&&this.tokenConfirmationAttempts>=Or){this.logger.error(`Failed to authenticate: "${t.error}", check your server auth config`),this.syncState.hasAuth()&&this.syncState.clearAuth(),this.authState.state!=="noAuth"&&this.setAndReportAuthFailed(this.authState.config.onAuthChange);return}this.authState.state==="waitingForServerConfirmationOfFreshToken"&&(this.tokenConfirmationAttempts++,this._logVerbose(`retrying reauthentication, ${Or-this.tokenConfirmationAttempts} attempts remaining`)),await this.stopSocket();let e=await this.fetchTokenAndGuardAgainstRace(this.authState.config.fetchToken,{forceRefreshToken:!0});e.isFromOutdatedConfig||(e.value&&this.syncState.isNewAuth(e.value)?(this.authenticate(e.value),this.setAuthState({state:"waitingForServerConfirmationOfFreshToken",config:this.authState.config,token:e.value,hadAuth:this.authState.state==="notRefetching"||this.authState.state==="waitingForScheduledRefetch"})):(this._logVerbose("reauthentication failed, could not fetch a new token"),this.syncState.hasAuth()&&this.syncState.clearAuth(),this.setAndReportAuthFailed(this.authState.config.onAuthChange)),this.tryRestartSocket())}async refetchToken(){if(this.authState.state==="noAuth")return;this._logVerbose("refetching auth token");let t=await this.fetchTokenAndGuardAgainstRace(this.authState.config.fetchToken,{forceRefreshToken:!0});t.isFromOutdatedConfig||(t.value?this.syncState.isNewAuth(t.value)?(this.setAuthState({state:"waitingForServerConfirmationOfFreshToken",hadAuth:this.syncState.hasAuth(),token:t.value,config:this.authState.config}),this.authenticate(t.value)):this.setAuthState({state:"notRefetching",config:this.authState.config}):(this._logVerbose("refetching token failed"),this.syncState.hasAuth()&&this.clearAuth(),this.setAndReportAuthFailed(this.authState.config.onAuthChange)),this._logVerbose("restarting WS after auth token fetch (if currently stopped)"),this.tryRestartSocket())}scheduleTokenRefetch(t){if(this.authState.state==="noAuth")return;let e=this.decodeToken(t);if(!e){this.logger.error("Auth token is not a valid JWT, cannot refetch the token");return}let{iat:r,exp:s}=e;if(!r||!s){this.logger.error("Auth token does not have required fields, cannot refetch the token");return}let o=s-r;if(o<=2){this.logger.error("Auth token does not live long enough, cannot refetch the token");return}let i=Math.min(Is,(o-this.refreshTokenLeewaySeconds)*1e3);i<=0&&(this.logger.warn(`Refetching auth token immediately, configured leeway ${this.refreshTokenLeewaySeconds}s is larger than the token's lifetime ${o}s`),i=0);let a=setTimeout(()=>{this._logVerbose("running scheduled token refetch"),this.refetchToken()},i);this.setAuthState({state:"waitingForScheduledRefetch",refetchTokenTimeoutId:a,config:this.authState.config}),this._logVerbose(`scheduled preemptive auth token refetching in ${i}ms`)}async fetchTokenAndGuardAgainstRace(t,e){let r=++this.configVersion;this._logVerbose(`fetching token with config version ${r}`);let s=await t(e);return this.configVersion!==r?(this._logVerbose(`stale config version, expected ${r}, got ${this.configVersion}`),{isFromOutdatedConfig:!0}):{isFromOutdatedConfig:!1,value:s}}stop(){this.resetAuthState(),this.configVersion++,this._logVerbose(`config version bumped to ${this.configVersion}`)}setAndReportAuthFailed(t){t(!1),this.resetAuthState()}resetAuthState(){this.setAuthState({state:"noAuth"})}setAuthState(t){let e=t.state==="waitingForServerConfirmationOfFreshToken"?{hadAuth:t.hadAuth,state:t.state,token:`...${t.token.slice(-7)}`}:{state:t.state};switch(this._logVerbose(`setting auth state to ${JSON.stringify(e)}`),t.state){case"waitingForScheduledRefetch":case"notRefetching":case"noAuth":this.tokenConfirmationAttempts=0;break;case"waitingForServerConfirmationOfFreshToken":case"waitingForServerConfirmationOfCachedToken":case"initialRefetch":break;default:}this.authState.state==="waitingForScheduledRefetch"&&clearTimeout(this.authState.refetchTokenTimeoutId),this.authState=t}decodeToken(t){try{return it(t)}catch(e){return this._logVerbose(`Error decoding token: ${e instanceof Error?e.message:"Unknown error"}`),null}}_logVerbose(t){this.logger.logVerbose(`${t} [v${this.configVersion}]`)}};var Ps=["convexClientConstructed","convexWebSocketOpen","convexFirstMessageReceived"];function Dr(n,t){let e={sessionId:t};typeof performance>"u"||!performance.mark||performance.mark(n,{detail:e})}function Ts(n){let t=n.name.slice(6);return t=t.charAt(0).toLowerCase()+t.slice(1),{name:t,startTime:n.startTime}}function Nr(n){if(typeof performance>"u"||!performance.getEntriesByName)return[];let t=[];for(let e of Ps){let r=performance.getEntriesByName(e).filter(s=>s.entryType==="mark").filter(s=>s.detail.sessionId===n);t.push(...r)}return t.map(Ts)}var As=Object.defineProperty,xs=(n,t,e)=>t in n?As(n,t,{enumerable:!0,configurable:!0,writable:!0,value:e}):n[t]=e,P=(n,t,e)=>xs(n,typeof t!="symbol"?t+"":t,e),Te=class{constructor(t,e,r){if(P(this,"address"),P(this,"state"),P(this,"requestManager"),P(this,"webSocketManager"),P(this,"authenticationManager"),P(this,"remoteQuerySet"),P(this,"optimisticQueryResults"),P(this,"_transitionHandlerCounter",0),P(this,"_nextRequestId"),P(this,"_onTransitionFns",new Map),P(this,"_sessionId"),P(this,"firstMessageReceived",!1),P(this,"debug"),P(this,"logger"),P(this,"maxObservedTimestamp"),P(this,"connectionStateSubscribers",new Map),P(this,"nextConnectionStateSubscriberId",0),P(this,"_lastPublishedConnectionState"),P(this,"markConnectionStateDirty",()=>{Promise.resolve().then(()=>{let h=this.connectionState();if(JSON.stringify(h)!==JSON.stringify(this._lastPublishedConnectionState)){this._lastPublishedConnectionState=h;for(let m of this.connectionStateSubscribers.values())m(h)}})}),P(this,"mark",h=>{this.debug&&Dr(h,this.sessionId)}),typeof t=="object")throw new Error("Passing a ClientConfig object is no longer supported. Pass the URL of the Convex deployment as a string directly.");r?.skipConvexDeploymentUrlCheck!==!0&&ve(t),r={...r};let s=r.authRefreshTokenLeewaySeconds??10,o=r.webSocketConstructor;if(!o&&typeof WebSocket>"u")throw new Error("No WebSocket global variable defined! To use Convex in an environment without WebSocket try the HTTP client: https://docs.convex.dev/api/classes/browser.ConvexHttpClient");o=o||WebSocket,this.debug=r.reportDebugInfoToConvex??!1,this.address=t,this.logger=r.logger===!1?jt({verbose:r.verbose??!1}):r.logger!==!0&&r.logger?r.logger:Ht({verbose:r.verbose??!1});let i=t.search("://");if(i===-1)throw new Error("Provided address was not an absolute URL.");let a=t.substring(i+3),c=t.substring(0,i),l;if(c==="http")l="ws";else if(c==="https")l="wss";else throw new Error(`Unknown parent protocol ${c}`);let d=`${l}://${a}/api/${D}/sync`;this.state=new ze,this.remoteQuerySet=new Pe(h=>this.state.queryPath(h),this.logger),this.requestManager=new Ze(this.logger,this.markConnectionStateDirty);let p=()=>{this.webSocketManager.pause(),this.state.pause()};this.authenticationManager=new ot(this.state,{authenticate:h=>{let m=this.state.setAuth(h);return this.webSocketManager.sendMessage(m),m.baseVersion},stopSocket:()=>this.webSocketManager.stop(),tryRestartSocket:()=>this.webSocketManager.tryRestart(),pauseSocket:p,resumeSocket:()=>this.webSocketManager.resume(),clearAuth:()=>{this.clearAuth()}},{logger:this.logger,refreshTokenLeewaySeconds:s}),this.optimisticQueryResults=new tt,this.addOnTransitionHandler(h=>{e(h.queries.map(m=>m.token))}),this._nextRequestId=0,this._sessionId=kr();let{unsavedChangesWarning:y}=r;if(typeof window>"u"||typeof window.addEventListener>"u"){if(y===!0)throw new Error("unsavedChangesWarning requested, but window.addEventListener not found! Remove {unsavedChangesWarning: true} from Convex client options.")}else y!==!1&&window.addEventListener("beforeunload",h=>{if(this.requestManager.hasIncompleteRequests()){h.preventDefault();let m="Are you sure you want to leave? Your changes may not be saved.";return(h||window.event).returnValue=m,m}});this.webSocketManager=new st(d,{onOpen:h=>{this.mark("convexWebSocketOpen"),this.webSocketManager.sendMessage({...h,type:"Connect",sessionId:this._sessionId,maxObservedTimestamp:this.maxObservedTimestamp}),this.remoteQuerySet=new Pe(le=>this.state.queryPath(le),this.logger);let[m,M]=this.state.restart();M&&this.webSocketManager.sendMessage(M),this.webSocketManager.sendMessage(m);for(let le of this.requestManager.restart())this.webSocketManager.sendMessage(le)},onResume:()=>{let[h,m]=this.state.resume();m&&this.webSocketManager.sendMessage(m),h&&this.webSocketManager.sendMessage(h);for(let M of this.requestManager.resume())this.webSocketManager.sendMessage(M)},onMessage:h=>{switch(this.firstMessageReceived||(this.firstMessageReceived=!0,this.mark("convexFirstMessageReceived"),this.reportMarks()),h.type){case"Transition":{this.observedTimestamp(h.endVersion.ts),this.authenticationManager.onTransition(h),this.remoteQuerySet.transition(h),this.state.transition(h);let m=this.requestManager.removeCompleted(this.remoteQuerySet.timestamp());this.notifyOnQueryResultChanges(m);break}case"MutationResponse":{h.success&&this.observedTimestamp(h.ts);let m=this.requestManager.onResponse(h);m!==null&&this.notifyOnQueryResultChanges(new Map([[m.requestId,m.result]]));break}case"ActionResponse":{this.requestManager.onResponse(h);break}case"AuthError":{this.authenticationManager.onAuthError(h);break}case"FatalError":{let m=Ir(this.logger,h.error);throw this.webSocketManager.terminate(),m}default:}return{hasSyncedPastLastReconnect:this.hasSyncedPastLastReconnect()}},onServerDisconnectError:r.onServerDisconnectError},o,this.logger,this.markConnectionStateDirty,this.debug),this.mark("convexClientConstructed"),r.expectAuth&&p()}hasSyncedPastLastReconnect(){return this.requestManager.hasSyncedPastLastReconnect()&&this.state.hasSyncedPastLastReconnect()}observedTimestamp(t){(this.maxObservedTimestamp===void 0||this.maxObservedTimestamp.lessThanOrEqual(t))&&(this.maxObservedTimestamp=t)}getMaxObservedTimestamp(){return this.maxObservedTimestamp}notifyOnQueryResultChanges(t){let e=this.remoteQuerySet.remoteQueryResults(),r=new Map;for(let[o,i]of e){let a=this.state.queryToken(o);if(a!==null){let c={result:i,udfPath:this.state.queryPath(o),args:this.state.queryArgs(o)};r.set(a,c)}}let s=this.optimisticQueryResults.ingestQueryResultsFromServer(r,new Set(t.keys()));this.handleTransition({queries:s.map(o=>{let i=this.optimisticQueryResults.rawQueryResult(o);return{token:o,modification:{kind:"Updated",result:i}}}),reflectedMutations:Array.from(t).map(([o,i])=>({requestId:o,result:i})),timestamp:this.remoteQuerySet.timestamp()})}handleTransition(t){for(let e of this._onTransitionFns.values())e(t)}addOnTransitionHandler(t){let e=this._transitionHandlerCounter++;return this._onTransitionFns.set(e,t),()=>this._onTransitionFns.delete(e)}getCurrentAuthClaims(){let t=this.state.getAuth(),e={};if(t&&t.tokenType==="User")try{e=t?it(t.value):{}}catch{e={}}else return;return{token:t.value,decoded:e}}setAuth(t,e){this.authenticationManager.setConfig(t,e)}hasAuth(){return this.state.hasAuth()}setAdminAuth(t,e){let r=this.state.setAdminAuth(t,e);this.webSocketManager.sendMessage(r)}clearAuth(){let t=this.state.clearAuth();this.webSocketManager.sendMessage(t)}subscribe(t,e,r){let s=_(e),{modification:o,queryToken:i,unsubscribe:a}=this.state.subscribe(t,s,r?.journal,r?.componentPath);return o!==null&&this.webSocketManager.sendMessage(o),{queryToken:i,unsubscribe:()=>{let c=a();c&&this.webSocketManager.sendMessage(c)}}}localQueryResult(t,e){let r=_(e),s=G(t,r);return this.optimisticQueryResults.queryResult(s)}localQueryResultByToken(t){return this.optimisticQueryResults.queryResult(t)}hasLocalQueryResultByToken(t){return this.optimisticQueryResults.hasQueryResult(t)}localQueryLogs(t,e){let r=_(e),s=G(t,r);return this.optimisticQueryResults.queryLogs(s)}queryJournal(t,e){let r=_(e),s=G(t,r);return this.state.queryJournal(s)}connectionState(){let t=this.webSocketManager.connectionState();return{hasInflightRequests:this.requestManager.hasInflightRequests(),isWebSocketConnected:t.isConnected,hasEverConnected:t.hasEverConnected,connectionCount:t.connectionCount,connectionRetries:t.connectionRetries,timeOfOldestInflightRequest:this.requestManager.timeOfOldestInflightRequest(),inflightMutations:this.requestManager.inflightMutations(),inflightActions:this.requestManager.inflightActions()}}subscribeToConnectionState(t){let e=this.nextConnectionStateSubscriberId++;return this.connectionStateSubscribers.set(e,t),()=>{this.connectionStateSubscribers.delete(e)}}async mutation(t,e,r){let s=await this.mutationInternal(t,e,r);if(!s.success)throw s.errorData!==void 0?Ce(s,new j(Y("mutation",t,s))):new Error(Y("mutation",t,s));return s.value}async mutationInternal(t,e,r,s){let{mutationPromise:o}=this.enqueueMutation(t,e,r,s);return o}enqueueMutation(t,e,r,s){let o=_(e);this.tryReportLongDisconnect();let i=this.nextRequestId;if(this._nextRequestId++,r!==void 0){let d=r.optimisticUpdate;if(d!==void 0){let p=m=>{d(m,o)instanceof Promise&&this.logger.warn("Optimistic update handler returned a Promise. Optimistic updates should be synchronous.")},h=this.optimisticQueryResults.applyOptimisticUpdate(p,i).map(m=>{let M=this.localQueryResultByToken(m);return{token:m,modification:{kind:"Updated",result:M===void 0?void 0:{success:!0,value:M,logLines:[]}}}});this.handleTransition({queries:h,reflectedMutations:[],timestamp:this.remoteQuerySet.timestamp()})}}let a={type:"Mutation",requestId:i,udfPath:t,componentPath:s,args:[A(o)]},c=this.webSocketManager.sendMessage(a),l=this.requestManager.request(a,c);return{requestId:i,mutationPromise:l}}async action(t,e){let r=await this.actionInternal(t,e);if(!r.success)throw r.errorData!==void 0?Ce(r,new j(Y("action",t,r))):new Error(Y("action",t,r));return r.value}async actionInternal(t,e,r){let s=_(e),o=this.nextRequestId;this._nextRequestId++,this.tryReportLongDisconnect();let i={type:"Action",requestId:o,udfPath:t,componentPath:r,args:[A(s)]},a=this.webSocketManager.sendMessage(i);return this.requestManager.request(i,a)}async close(){return this.authenticationManager.stop(),this.webSocketManager.terminate()}get url(){return this.address}get nextRequestId(){return this._nextRequestId}get sessionId(){return this._sessionId}reportMarks(){if(this.debug){let t=Nr(this.sessionId);this.webSocketManager.sendMessage({type:"Event",eventType:"ClientConnect",event:t})}}tryReportLongDisconnect(){if(!this.debug)return;let t=this.connectionState().timeOfOldestInflightRequest;if(t===null||Date.now()-t.getTime()<=60*1e3)return;let e=`${this.address}/api/debug_event`;fetch(e,{method:"POST",headers:{"Content-Type":"application/json","Convex-Client":`npm-${D}`},body:JSON.stringify({event:"LongWebsocketDisconnect"})}).then(r=>{r.ok||this.logger.warn("Analytics request failed with response:",r.body)}).catch(r=>{this.logger.warn("Analytics response failed with error:",r)})}};function at(n){if(typeof n!="object"||n===null||!Array.isArray(n.page)||typeof n.isDone!="boolean"||typeof n.continueCursor!="string")throw new Error(`Not a valid paginated query result: ${n?.toString()}`);return n}var Ms=Object.defineProperty,Rs=(n,t,e)=>t in n?Ms(n,t,{enumerable:!0,configurable:!0,writable:!0,value:e}):n[t]=e,Fr=(n,t,e)=>Rs(n,typeof t!="symbol"?t+"":t,e),ct=class{constructor(t,e){this.client=t,this.onTransition=e,Fr(this,"paginatedQuerySet",new Map),Fr(this,"lastTransitionTs"),this.lastTransitionTs=W.fromNumber(0),this.client.addOnTransitionHandler(r=>this.onBaseTransition(r))}subscribe(t,e,r){let s=B(t),o=Jt(s,e,r),i=()=>this.removePaginatedQuerySubscriber(o),a=this.paginatedQuerySet.get(o);return a?(a.numSubscribers+=1,{paginatedQueryToken:o,unsubscribe:i}):(this.paginatedQuerySet.set(o,{token:o,canonicalizedUdfPath:s,args:e,numSubscribers:1,options:{initialNumItems:r.initialNumItems},nextPageKey:0,pageKeys:[],pageKeyToQuery:new Map,ongoingSplits:new Map,skip:!1,id:r.id}),this.addPageToPaginatedQuery(o,null,r.initialNumItems),{paginatedQueryToken:o,unsubscribe:i})}localQueryResult(t,e,r){let s=B(t),o=Jt(s,e,r);return this.localQueryResultByToken(o)}localQueryResultByToken(t){let e=this.paginatedQuerySet.get(t);if(!e)return;let r=this.activePageQueryTokens(e);if(r.length===0)return{results:[],status:"LoadingFirstPage",loadMore:c=>this.loadMoreOfPaginatedQuery(t,c)};let s=[],o=!1,i=!1;for(let c of r){let l=this.client.localQueryResultByToken(c);if(l===void 0){o=!0,i=!1;continue}let d=at(l);s=s.concat(d.page),i=!!d.isDone}let a;return o?a=s.length===0?"LoadingFirstPage":"LoadingMore":i?a="Exhausted":a="CanLoadMore",{results:s,status:a,loadMore:c=>this.loadMoreOfPaginatedQuery(t,c)}}onBaseTransition(t){let e=t.queries.map(i=>i.token),r=this.queriesContainingTokens(e),s=[];r.length>0&&(this.processPaginatedQuerySplits(r,i=>this.client.localQueryResultByToken(i)),s=r.map(i=>({token:i,modification:{kind:"Updated",result:this.localQueryResultByToken(i)}})));let o={...t,paginatedQueries:s};this.onTransition(o)}loadMoreOfPaginatedQuery(t,e){this.mustGetPaginatedQuery(t);let r=this.queryTokenForLastPageOfPaginatedQuery(t),s=this.client.localQueryResultByToken(r);if(!s)return!1;let o=at(s);if(o.isDone)return!1;this.addPageToPaginatedQuery(t,o.continueCursor,e);let i={timestamp:this.lastTransitionTs,reflectedMutations:[],queries:[],paginatedQueries:[{token:t,modification:{kind:"Updated",result:this.localQueryResultByToken(t)}}]};return this.onTransition(i),!0}queriesContainingTokens(t){if(t.length===0)return[];let e=[],r=new Set(t);for(let[s,o]of this.paginatedQuerySet)for(let i of this.allQueryTokens(o))if(r.has(i)){e.push(s);break}return e}processPaginatedQuerySplits(t,e){for(let r of t){let s=this.mustGetPaginatedQuery(r),{ongoingSplits:o,pageKeyToQuery:i,pageKeys:a}=s;for(let[c,[l,d]]of o)e(i.get(l).queryToken)!==void 0&&e(i.get(d).queryToken)!==void 0&&this.completePaginatedQuerySplit(s,c,l,d);for(let c of a){if(o.has(c))continue;let l=i.get(c).queryToken,d=e(l);if(!d)continue;let p=at(d);p.splitCursor&&(p.pageStatus==="SplitRecommended"||p.pageStatus==="SplitRequired"||p.page.length>s.options.initialNumItems*2)&&this.splitPaginatedQueryPage(s,c,p.splitCursor,p.continueCursor)}}}splitPaginatedQueryPage(t,e,r,s){let o=t.nextPageKey++,i=t.nextPageKey++,a={cursor:s,numItems:t.options.initialNumItems,id:t.id},c=this.client.subscribe(t.canonicalizedUdfPath,{...t.args,paginationOpts:{...a,cursor:null,endCursor:r}});t.pageKeyToQuery.set(o,c);let l=this.client.subscribe(t.canonicalizedUdfPath,{...t.args,paginationOpts:{...a,cursor:r,endCursor:s}});t.pageKeyToQuery.set(i,l),t.ongoingSplits.set(e,[o,i])}addPageToPaginatedQuery(t,e,r){let s=this.mustGetPaginatedQuery(t),o=s.nextPageKey++,i={cursor:e,numItems:r,id:s.id},a={...s.args,paginationOpts:i},c=this.client.subscribe(s.canonicalizedUdfPath,a);return s.pageKeys.push(o),s.pageKeyToQuery.set(o,c),c}removePaginatedQuerySubscriber(t){let e=this.paginatedQuerySet.get(t);if(e&&(e.numSubscribers-=1,!(e.numSubscribers>0))){for(let r of e.pageKeyToQuery.values())r.unsubscribe();this.paginatedQuerySet.delete(t)}}completePaginatedQuerySplit(t,e,r,s){let o=t.pageKeyToQuery.get(e);t.pageKeyToQuery.delete(e);let i=t.pageKeys.indexOf(e);t.pageKeys.splice(i,1,r,s),t.ongoingSplits.delete(e),o.unsubscribe()}activePageQueryTokens(t){return t.pageKeys.map(e=>t.pageKeyToQuery.get(e).queryToken)}allQueryTokens(t){return Array.from(t.pageKeyToQuery.values()).map(e=>e.queryToken)}queryTokenForLastPageOfPaginatedQuery(t){let e=this.mustGetPaginatedQuery(t),r=e.pageKeys[e.pageKeys.length-1];if(r===void 0)throw new Error(`No pages for paginated query ${t}`);return e.pageKeyToQuery.get(r).queryToken}mustGetPaginatedQuery(t){let e=this.paginatedQuerySet.get(t);if(!e)throw new Error("paginated query no longer exists for token "+t);return e}};var _s=Object.defineProperty,Ls=(n,t,e)=>t in n?_s(n,t,{enumerable:!0,configurable:!0,writable:!0,value:e}):n[t]=e,me=(n,t,e)=>Ls(n,typeof t!="symbol"?t+"":t,e),Ur;var Ae=class{constructor(t,e={}){me(this,"listeners"),me(this,"_client"),me(this,"_paginatedClient"),me(this,"callNewListenersWithCurrentValuesTimer"),me(this,"_closed"),me(this,"_disabled"),e.skipConvexDeploymentUrlCheck!==!0&&ve(t);let{disabled:r,...s}=e;this._closed=!1,this._disabled=!!r,Ur&&!("webSocketConstructor"in s)&&typeof WebSocket>"u"&&(s.webSocketConstructor=Ur),typeof window>"u"&&!("unsavedChangesWarning"in s)&&(s.unsavedChangesWarning=!1),this.disabled||(this._client=new Te(t,()=>{},s),this._paginatedClient=new ct(this._client,o=>this._transition(o))),this.listeners=new Set}get closed(){return this._closed}get client(){if(this._client)return this._client;throw new Error("ConvexClient is disabled")}get paginatedClient(){if(this._paginatedClient)return this._paginatedClient;throw new Error("ConvexClient is disabled")}get disabled(){return this._disabled}onUpdate(t,e,r,s){if(this.disabled)return this.createDisabledUnsubscribe();let{queryToken:o,unsubscribe:i}=this.client.subscribe(O(t),e),a={queryToken:o,callback:r,onError:s,unsubscribe:i,hasEverRun:!1,query:t,args:e,paginationOptions:void 0};this.listeners.add(a),this.queryResultReady(o)&&this.callNewListenersWithCurrentValuesTimer===void 0&&(this.callNewListenersWithCurrentValuesTimer=setTimeout(()=>this.callNewListenersWithCurrentValues(),0));let c={unsubscribe:()=>{this.closed||(this.listeners.delete(a),i())},getCurrentValue:()=>this.client.localQueryResultByToken(o),getQueryLogs:()=>this.client.localQueryLogs(o)},l=c.unsubscribe;return Object.assign(l,c),l}onPaginatedUpdate_experimental(t,e,r,s,o){if(this.disabled)return this.createDisabledUnsubscribe();let i={initialNumItems:r.initialNumItems,id:-1},{paginatedQueryToken:a,unsubscribe:c}=this.paginatedClient.subscribe(O(t),e,i),l={queryToken:a,callback:s,onError:o,unsubscribe:c,hasEverRun:!1,query:t,args:e,paginationOptions:i};this.listeners.add(l),this.paginatedClient.localQueryResultByToken(a)&&this.callNewListenersWithCurrentValuesTimer===void 0&&(this.callNewListenersWithCurrentValuesTimer=setTimeout(()=>this.callNewListenersWithCurrentValues(),0));let d={unsubscribe:()=>{this.closed||(this.listeners.delete(l),c())},getCurrentValue:()=>this.paginatedClient.localQueryResult(O(t),e,i),getQueryLogs:()=>[]},p=d.unsubscribe;return Object.assign(p,d),p}callNewListenersWithCurrentValues(){this.callNewListenersWithCurrentValuesTimer=void 0,this._transition({queries:[],paginatedQueries:[]},!0)}queryResultReady(t){return this.client.hasLocalQueryResultByToken(t)}createDisabledUnsubscribe(){let t=(()=>{});return Object.assign(t,{unsubscribe:t,getCurrentValue:()=>{},getQueryLogs:()=>{}}),t}async close(){if(!this.disabled)return this.listeners.clear(),this._closed=!0,this._paginatedClient&&(this._paginatedClient=void 0),this.client.close()}getAuth(){if(!this.disabled)return this.client.getCurrentAuthClaims()}setAuth(t,e){this.disabled||this.client.setAuth(t,e??(()=>{}))}setAdminAuth(t,e){if(this.closed)throw new Error("ConvexClient has already been closed.");this.disabled||this.client.setAdminAuth(t,e)}_transition({queries:t,paginatedQueries:e},r=!1){let s=[...t.map(o=>o.token),...e.map(o=>o.token)];for(let o of this.listeners){let{callback:i,queryToken:a,onError:c,hasEverRun:l}=o,d=Pr(a),p=d?!!this.paginatedClient.localQueryResultByToken(a):this.client.hasLocalQueryResultByToken(a);if(s.includes(a)||r&&!l&&p){o.hasEverRun=!0;let y;try{d?y=this.paginatedClient.localQueryResultByToken(a):y=this.client.localQueryResultByToken(a)}catch(h){if(!(h instanceof Error))throw h;c?c(h,"Second argument to onUpdate onError is reserved for later use"):Promise.reject(h);continue}i(y,"Second argument to onUpdate callback is reserved for later use")}}}async mutation(t,e,r){if(this.disabled)throw new Error("ConvexClient is disabled");return await this.client.mutation(O(t),e,r)}async action(t,e){if(this.disabled)throw new Error("ConvexClient is disabled");return await this.client.action(O(t),e)}async query(t,e){if(this.disabled)throw new Error("ConvexClient is disabled");let r=this.client.localQueryResult(O(t),e);return r!==void 0?Promise.resolve(r):new Promise((s,o)=>{let{unsubscribe:i}=this.onUpdate(t,e,a=>{i(),s(a)},a=>{i(),o(a)})})}connectionState(){if(this.disabled)throw new Error("ConvexClient is disabled");return this.client.connectionState()}subscribeToConnectionState(t){return this.disabled?()=>{}:this.client.subscribeToConnectionState(t)}};var er={GODOT:"GODOT",UNITY:"UNITY",UNREAL:"UNREAL",JSDOS:"JSDOS",RUFFLE:"RUFFLE",RENPY:"RENPY",CUSTOM:"CUSTOM"},$r=24,la={MAX_PLAYERS:100,EXPIRY_HOURS:$r,EXPIRY_MS:$r*60*60*1e3},ut={PUBLIC:0,FRIENDS_ONLY:1,PRIVATE:2},lt=500;var dt={ASC:0,DESC:1},ht={NUMERIC:0,TIME_SECONDS:1,TIME_MILLISECONDS:2,TIME_GAME_TICKS:3},xe={SCREENSHOT:0,VIDEO:1,COMMUNITY:2,GAME_MANAGED:3,OTHER:4},Me={PUBLIC:0,PRIVATE:2};var da={DEFAULT_LIMIT_BYTES:1024*1024*1024,UPLOADS_PER_MINUTE:30,UPLOADS_PER_HOUR:300},J={OFFER:"offer",ANSWER:"answer",ICE_CANDIDATE:"ice-candidate"};var E={PROGRESS_UPDATE:"ProgressUpdate",LOADING_COMPLETE:"LoadingComplete",TOGGLE_OVERLAY:"ToggleOverlay",TAKE_FOCUS:"TakeFocus",LOBBY_JOINED:"LobbyJoined",LOBBY_LEFT:"LobbyLeft",GET_LOBBY_INVITE_LINK:"GetLobbyInviteLink",GET_DEVICE_FINGERPRINT:"GetDeviceFingerprint",SET_FULLSCREEN:"SetFullscreen",TOGGLE_FULLSCREEN:"ToggleFullscreen",FULLSCREEN_CHANGED:"FullscreenChanged",SET_MUTE:"SetMute",TOGGLE_MUTE:"ToggleMute",MUTE_CHANGED:"MuteChanged",OVERLAY_CHANGED:"OverlayChanged",GAMEPLAY_JWT_READY:"GameplayJwtReady",END_SESSION:"EndSession",TRIGGER_PAYWALL:"TriggerPaywall"},tr={EMBED_CONFIGURE:"embed.configure",EMBED_CONFIGURE_ACK:"embed.configure:ack",EMBED_CREDS_REQUEST:"embed.creds-request",EMBED_CREDS_RESPONSE:"embed.creds-response"};var Re={RedirectUrl:"rdurl",EntrypointParams:"entrypointparams",Entrypoint:"entrypoint",Engine:"engine",EngineVersion:"engineversion",PlayKey:"pk",SdkConfig:"sdkconfig",Caller:"caller",GameSlug:"gameSlug"},qr={Wavedash:"wavedash"};var Xt=3e4,_e={CLIENT_INTERVAL_MS:Xt,CLIENT_REESTABLISH_THRESHOLD_MS:Xt*2.5,CLIENT_GRACE_MS:Xt/6};var iu=g.object({numItems:g.number(),cursor:g.union(g.string(),g.null()),endCursor:g.optional(g.union(g.string(),g.null())),id:g.optional(g.number()),maximumRowsRead:g.optional(g.number()),maximumBytesRead:g.optional(g.number())});var Ns=Symbol("var.requestId"),Fs=Symbol("var.ip"),Us=Symbol("var.userAgent"),$s=Symbol("var.now"),qs={[Ns]:"requestId",[Fs]:"ip",[Us]:"userAgent",[$s]:"now"};var Bs=Object.defineProperty,Gs=(n,t,e)=>t in n?Bs(n,t,{enumerable:!0,configurable:!0,writable:!0,value:e}):n[t]=e,H=(n,t,e)=>Gs(n,typeof t!="symbol"?t+"":t,e),pt=class{constructor(t){H(this,"indexes"),H(this,"stagedDbIndexes"),H(this,"searchIndexes"),H(this,"stagedSearchIndexes"),H(this,"vectorIndexes"),H(this,"stagedVectorIndexes"),H(this,"validator"),this.indexes=[],this.stagedDbIndexes=[],this.searchIndexes=[],this.stagedSearchIndexes=[],this.vectorIndexes=[],this.stagedVectorIndexes=[],this.validator=t}" indexes"(){return this.indexes}index(t,e){return Array.isArray(e)?this.indexes.push({indexDescriptor:t,fields:e}):e.staged?this.stagedDbIndexes.push({indexDescriptor:t,fields:e.fields}):this.indexes.push({indexDescriptor:t,fields:e.fields}),this}searchIndex(t,e){return e.staged?this.stagedSearchIndexes.push({indexDescriptor:t,searchField:e.searchField,filterFields:e.filterFields||[]}):this.searchIndexes.push({indexDescriptor:t,searchField:e.searchField,filterFields:e.filterFields||[]}),this}vectorIndex(t,e){return e.staged?this.stagedVectorIndexes.push({indexDescriptor:t,vectorField:e.vectorField,dimensions:e.dimensions,filterFields:e.filterFields||[]}):this.vectorIndexes.push({indexDescriptor:t,vectorField:e.vectorField,dimensions:e.dimensions,filterFields:e.filterFields||[]}),this}self(){return this}export(){let t=this.validator.json;if(typeof t!="object")throw new Error("Invalid validator: please make sure that the parameter of `defineTable` is valid (see https://docs.convex.dev/database/schemas)");return{indexes:this.indexes,stagedDbIndexes:this.stagedDbIndexes,searchIndexes:this.searchIndexes,stagedSearchIndexes:this.stagedSearchIndexes,vectorIndexes:this.vectorIndexes,stagedVectorIndexes:this.stagedVectorIndexes,documentType:t}}};function nr(n){return Wt(n)?new pt(n):new pt(g.object(n))}var sr=class{constructor(t,e){H(this,"tables"),H(this,"strictTableNameTypes"),H(this,"schemaValidation"),this.tables=t,this.schemaValidation=e?.schemaValidation===void 0?!0:e.schemaValidation}export(){return JSON.stringify({tables:Object.entries(this.tables).map(([t,e])=>{let{indexes:r,stagedDbIndexes:s,searchIndexes:o,stagedSearchIndexes:i,vectorIndexes:a,stagedVectorIndexes:c,documentType:l}=e.export();return{tableName:t,indexes:r,stagedDbIndexes:s,searchIndexes:o,stagedSearchIndexes:i,vectorIndexes:a,stagedVectorIndexes:c,documentType:l}}),schemaValidation:this.schemaValidation})}};function Br(n,t){return new sr(n,t)}var _u=Br({_scheduled_functions:nr({name:g.string(),args:g.array(g.any()),scheduledTime:g.float64(),completedTime:g.optional(g.float64()),state:g.union(g.object({kind:g.literal("pending")}),g.object({kind:g.literal("inProgress")}),g.object({kind:g.literal("success")}),g.object({kind:g.literal("failed"),error:g.string()}),g.object({kind:g.literal("canceled")}))}),_storage:nr({sha256:g.string(),size:g.float64(),contentType:g.optional(g.string())})});var f=Kt;var ye={KICKED:"KICKED",ERROR:"ERROR"},ke={JOINED:"JOINED",LEFT:"LEFT"},Gr={QUEUE_FULL:"QUEUE_FULL",PAYLOAD_TOO_LARGE:"PAYLOAD_TOO_LARGE",INVALID_PAYLOAD_SIZE:"INVALID_PAYLOAD_SIZE",INVALID_CHANNEL:"INVALID_CHANNEL",MALFORMED:"MALFORMED",PEER_NOT_READY:"PEER_NOT_READY"},ft={SMALL:64,MEDIUM:128,LARGE:256};var v={LOBBY_MESSAGE:"LobbyMessage",LOBBY_JOINED:"LobbyJoined",LOBBY_KICKED:"LobbyKicked",LOBBY_USERS_UPDATED:"LobbyUsersUpdated",LOBBY_DATA_UPDATED:"LobbyDataUpdated",LOBBY_INVITE:"LobbyInvite",P2P_CONNECTION_ESTABLISHED:"P2PConnectionEstablished",P2P_CONNECTION_FAILED:"P2PConnectionFailed",P2P_PEER_DISCONNECTED:"P2PPeerDisconnected",P2P_PEER_RECONNECTING:"P2PPeerReconnecting",P2P_PEER_RECONNECTED:"P2PPeerReconnected",P2P_PACKET_DROPPED:"P2PPacketDropped",STATS_STORED:"StatsStored",BACKEND_CONNECTED:"BackendConnected",BACKEND_DISCONNECTED:"BackendDisconnected",BACKEND_RECONNECTING:"BackendReconnecting",FULLSCREEN_CHANGED:"FullscreenChanged",MUTE_CHANGED:"MuteChanged"};var X={DEBUG:0,INFO:1,WARN:2,ERROR:3},ir=class{constructor(t=X.WARN){this.logLevel=t}setLogLevel(t){this.logLevel=t}debug(t,...e){this.logLevel<=X.DEBUG&&console.log(`[WavedashJS] ${t}`,...e)}info(t,...e){this.logLevel<=X.INFO&&console.log(`[WavedashJS] ${t}`,...e)}warn(t,...e){this.logLevel<=X.WARN&&console.warn(`[WavedashJS] ${t}`,...e)}error(t,...e){this.logLevel<=X.ERROR&&console.error(`[WavedashJS] ${t}`,...e)}},u=new ir;var or="";function Vr(n){or=n}function gt(){return or}function k(){return or!==""}var w=class{constructor(t){this.sdk=t}destroy(){}};var mt=class extends w{constructor(e){super(e);this._isMuted=!1;this.frames=new Set;this.iframeBindings=new WeakMap;this.iframeLoadHandlers=new Map;this.boundIframes=new Set;this.handleMute=e=>{this._isMuted!==e.isMuted&&(this._isMuted=e.isMuted,this.frames.forEach(r=>r.applyMute(this._isMuted)),this.sdk.gameEventManager.notifyGame(v.MUTE_CHANGED,{isMuted:this._isMuted}))};typeof window<"u"&&this.attachWindow(window),this.sdk.iframeMessenger.addEventListener(E.MUTE_CHANGED,this.handleMute)}isMuted(){return this._isMuted}async requestMute(e){return k()?(await this.sdk.iframeMessenger.requestFromParent(E.SET_MUTE,{muted:e})).success:(u.debug("requestMute() is disabled outside a Wavedash parent frame (e.g. `wavedash dev`)"),!1)}async toggleMute(){return k()?(await this.sdk.iframeMessenger.requestFromParent(E.TOGGLE_MUTE)).success:(u.debug("toggleMute() is disabled outside a Wavedash parent frame (e.g. `wavedash dev`)"),!1)}attachWindow(e){try{e.document}catch{return}let r=new yt(this,e);this.frames.add(r)}bindIframe(e){if(!this.boundIframes.has(e)){this.boundIframes.add(e);let r=()=>this.attachIframe(e);this.iframeLoadHandlers.set(e,r),e.addEventListener("load",r)}this.attachIframe(e)}unbindIframe(e){let r=this.iframeLoadHandlers.get(e);r&&(e.removeEventListener("load",r),this.iframeLoadHandlers.delete(e)),this.boundIframes.delete(e),this.teardownFrame(e)}attachIframe(e){let r=null,s=null;try{let a=e.contentWindow;a&&(s=a.document,r=a)}catch{}if(!r||!s){this.teardownFrame(e);return}let o=this.iframeBindings.get(e);if(o){if(o.doc===s)return;this.teardownFrame(e)}let i=new yt(this,r);this.frames.add(i),this.iframeBindings.set(e,{doc:s,shim:i}),this._isMuted&&i.applyMute(!0)}teardownFrame(e){let r=this.iframeBindings.get(e);r&&(this.frames.delete(r.shim),r.shim.uninstall(),this.iframeBindings.delete(e))}destroy(){this.sdk.iframeMessenger.removeEventListener(E.MUTE_CHANGED,this.handleMute),this.boundIframes.forEach(e=>{let r=this.iframeLoadHandlers.get(e);r&&e.removeEventListener("load",r)}),this.boundIframes.clear(),this.iframeLoadHandlers.clear(),this.frames.forEach(e=>e.uninstall()),this.frames.clear(),super.destroy()}},yt=class{constructor(t,e){this.contexts=new bt;this.contextGains=new WeakMap;this.elements=new bt;this.intendedMuted=new WeakMap;this.intendedUtteranceVolume=new WeakMap;this.boundChildren=new Set;this.originalAudioContext=null;this.originalWebKitAudioContext=null;this.originalAudio=null;this.originalMutedDescriptor=null;this.originalPlay=null;this.originalSpeak=null;this.originalUtteranceVolumeDescriptor=null;this.mutationObserver=null;this.manager=t,this.win=e,this.doc=e.document??null,this.installShims()}applyMute(t){let e=t?0:1;this.contexts.forEach(s=>{let o=this.contextGains.get(s);if(!o)return;let i=s.currentTime,a=o.gain;if(typeof a.cancelAndHoldAtTime=="function")a.cancelAndHoldAtTime(i);else{let c=a.value;a.cancelScheduledValues(i),a.setValueAtTime(c,i)}a.linearRampToValueAtTime(e,i+.05)});let r=this.originalMutedDescriptor?.set;r&&this.elements.forEach(s=>{let o=this.intendedMuted.get(s)??!1;r.call(s,t?!0:o)})}bindChild(t){this.boundChildren.add(t),this.manager.bindIframe(t)}unbindChild(t){this.boundChildren.delete(t),this.manager.unbindIframe(t)}trackElement(t){if(this.intendedMuted.has(t))return;let e=this.originalMutedDescriptor?.get,r=this.originalMutedDescriptor?.set,s=e?e.call(t):t.muted;this.intendedMuted.set(t,s),this.elements.add(t),this.manager.isMuted()&&!s&&r&&r.call(t,!0)}installShims(){let t=this.win,e=this.doc;t.AudioContext&&(this.originalAudioContext=t.AudioContext,t.AudioContext=this.shimAudioContextClass(t.AudioContext));let r=t;if(r.webkitAudioContext&&(this.originalWebKitAudioContext=r.webkitAudioContext,r.webkitAudioContext=this.shimAudioContextClass(r.webkitAudioContext)),t.Audio){let i=t.Audio;this.originalAudio=i,(a=>{let c=function(l){let d=new i(l);return a.trackElement(d),d};c.prototype=i.prototype,t.Audio=c})(this)}if(e){let i=t.HTMLMediaElement,a=t.HTMLIFrameElement,c=t.HTMLElement;e.querySelectorAll("audio, video").forEach(l=>{this.trackElement(l)}),e.querySelectorAll("iframe").forEach(l=>{this.bindChild(l)}),this.mutationObserver=new t.MutationObserver(l=>{for(let d of l)d.addedNodes.forEach(p=>{if(p instanceof i)this.trackElement(p);else if(p instanceof a)this.bindChild(p);else if(p instanceof c){let y=p;if(!y.firstElementChild)return;y.querySelectorAll("audio, video, iframe").forEach(h=>{h instanceof a?this.bindChild(h):this.trackElement(h)})}}),d.removedNodes.forEach(p=>{if(p instanceof a)this.unbindChild(p);else if(p instanceof c){let y=p;if(!y.firstElementChild)return;y.querySelectorAll("iframe").forEach(h=>{this.unbindChild(h)})}})}),this.mutationObserver.observe(e.documentElement,{childList:!0,subtree:!0})}this.originalMutedDescriptor=Object.getOwnPropertyDescriptor(t.HTMLMediaElement.prototype,"muted")??null;let s=this.originalMutedDescriptor;s?.get&&s?.set&&(i=>{Object.defineProperty(t.HTMLMediaElement.prototype,"muted",{configurable:!0,get(){let a=i.intendedMuted.get(this);return a!==void 0?a:s.get.call(this)},set(a){i.intendedMuted.set(this,a),i.elements.add(this),s.set.call(this,i.manager.isMuted()?!0:a)}})})(this);let o=t.HTMLMediaElement.prototype.play;this.originalPlay=o,(i=>{t.HTMLMediaElement.prototype.play=function(){return i.trackElement(this),o.call(this)}})(this),this.shimSpeechSynthesis()}shimSpeechSynthesis(){let t=this.win;if(!t.speechSynthesis||typeof t.SpeechSynthesisUtterance>"u")return;this.originalUtteranceVolumeDescriptor=Object.getOwnPropertyDescriptor(t.SpeechSynthesisUtterance.prototype,"volume")??null;let e=this.originalUtteranceVolumeDescriptor;e?.get&&e?.set&&(o=>{Object.defineProperty(t.SpeechSynthesisUtterance.prototype,"volume",{configurable:!0,get(){let i=o.intendedUtteranceVolume.get(this);return i!==void 0?i:e.get.call(this)},set(i){o.intendedUtteranceVolume.set(this,i),e.set.call(this,i)}})})(this);let r=t.speechSynthesis,s=r.speak;this.originalSpeak=s,(o=>{r.speak=function(i){if(o.manager.isMuted()){if(!o.intendedUtteranceVolume.has(i)){let a=e?.get?e.get.call(i):i.volume;o.intendedUtteranceVolume.set(i,a)}e?.set?e.set.call(i,0):i.volume=0}else{let a=o.intendedUtteranceVolume.get(i);a!==void 0&&(e?.set?e.set.call(i,a):i.volume=a,o.intendedUtteranceVolume.delete(i))}return s.call(r,i)}})(this)}shimAudioContextClass(t){return(e=>class extends t{constructor(r){super(r);let s=this.destination,o=this.createGain();o.connect(s),o.gain.value=e.manager.isMuted()?0:1,Object.defineProperty(o,"maxChannelCount",{configurable:!0,get:()=>s.maxChannelCount});for(let i of["channelCount","channelCountMode","channelInterpretation"]){let a=Object.getOwnPropertyDescriptor(e.win.AudioNode.prototype,i)?.set;Object.defineProperty(o,i,{configurable:!0,get:()=>s[i],set:c=>{s[i]=c;try{a?.call(o,c)}catch{}}})}Object.defineProperty(this,"destination",{configurable:!0,get(){return o}}),e.contexts.add(this),e.contextGains.set(this,o)}close(){return e.contextGains.delete(this),super.close()}})(this)}uninstall(){let t=this.win;try{this.mutationObserver&&(this.mutationObserver.disconnect(),this.mutationObserver=null)}catch{}this.boundChildren.forEach(r=>this.manager.unbindIframe(r)),this.boundChildren.clear();let e=r=>{try{r()}catch{}};e(()=>{this.originalAudioContext&&(t.AudioContext=this.originalAudioContext)}),e(()=>{let r=t;this.originalWebKitAudioContext&&r.webkitAudioContext&&(r.webkitAudioContext=this.originalWebKitAudioContext)}),e(()=>{this.originalAudio&&(t.Audio=this.originalAudio)}),e(()=>{this.originalSpeak&&t.speechSynthesis&&(t.speechSynthesis.speak=this.originalSpeak)}),e(()=>{this.originalUtteranceVolumeDescriptor&&typeof t.SpeechSynthesisUtterance<"u"&&Object.defineProperty(t.SpeechSynthesisUtterance.prototype,"volume",this.originalUtteranceVolumeDescriptor)}),e(()=>{this.originalPlay&&(t.HTMLMediaElement.prototype.play=this.originalPlay)}),e(()=>{this.originalMutedDescriptor&&Object.defineProperty(t.HTMLMediaElement.prototype,"muted",this.originalMutedDescriptor)}),this.contexts.clear(),this.contextGains=new WeakMap,this.elements.clear(),this.intendedMuted=new WeakMap,this.intendedUtteranceVolume=new WeakMap}},bt=class{constructor(){this.set=new Set}add(t){for(let e of this.set)if(e.deref()===t)return;this.set.add(new WeakRef(t))}forEach(t){for(let e of this.set){let r=e.deref();r===void 0?this.set.delete(e):t(r)}}clear(){this.set.clear()}};var Wr="/userfs",ee="FILE_DATA";async function Qr(n,t){return new Promise((e,r)=>{let s=indexedDB.open(Wr);s.onerror=()=>r(s.error),s.onupgradeneeded=o=>{let i=o.target.result;i.objectStoreNames.contains(ee)||i.createObjectStore(ee)},s.onsuccess=()=>{let o=s.result,i=o.transaction(ee,"readwrite"),a=i.objectStore(ee),c={contents:t,timestamp:Date.now(),mode:33206},l=a.put(c,n);l.onsuccess=()=>e(),l.onerror=()=>r(l.error),i.oncomplete=()=>o.close()}})}async function Hr(n){return new Promise((t,e)=>{let r=indexedDB.open(Wr);r.onerror=()=>e(r.error),r.onupgradeneeded=s=>{let o=s.target.result;o.objectStoreNames.contains(ee)||o.createObjectStore(ee)},r.onsuccess=()=>{let s=r.result,o=s.transaction(ee,"readonly"),a=o.objectStore(ee).get(n);a.onsuccess=()=>t(a.result),a.onerror=()=>e(a.error),o.oncomplete=()=>s.close()}})}function jr(n){if(n==null)throw new Error("File not found in IndexedDB");if("contents"in n&&n.contents!=null){let t=n.contents instanceof Uint8Array||n.contents instanceof Int8Array?n.contents:new Uint8Array(n.contents);return new Blob([t],{type:"application/octet-stream"})}if(n instanceof Blob)return n;if(n instanceof Uint8Array||n instanceof Int8Array)return new Blob([n],{type:"application/octet-stream"});if(n instanceof ArrayBuffer)return new Blob([n],{type:"application/octet-stream"});if("data"in n&&n.data instanceof ArrayBuffer)return new Blob([n.data],{type:"application/octet-stream"});if("blob"in n&&n.blob instanceof Blob)return n.blob;throw new Error("Unrecognized value shape from IndexedDB")}var Jr="userfs",Kr="/idbfs/wavedash",vt=class extends w{constructor(t){super(t)}toRemoteKey(t){let e=this.sdk.engineInstance?.unityPersistentDataPath,r=e?t.replace(e,Kr):t,s=r.startsWith("/")?r.slice(1):r;return`${this.sdk.gameCloudId}/${Jr}/${this.sdk.wavedashUser.id}/${s}`}toLocalPath(t){let e=`${this.sdk.gameCloudId}/${Jr}/${this.sdk.wavedashUser.id}/`,r=t.startsWith(e)?"/"+t.slice(e.length):t,s=this.sdk.engineInstance?.unityPersistentDataPath;return s?r.replace(Kr,s):r}async uploadRemoteFile(t){let e=await this.sdk.convexClient.mutation(f.sdk.remoteFileStorage.getUploadUrl,{path:this.toRemoteKey(t)});if(!await this.upload(e,t))throw new Error(`Failed to upload file: ${t}`);return t}async deleteRemoteFile(t){let e=this.getRemoteStorageUrl(t),r=await this.sdk.ensureGameplayJwt(),s=await fetch(e,{method:"DELETE",headers:{Authorization:`Bearer ${r}`}});if(!s.ok){let o=`Failed to delete remote file ${t}: ${s.status} (${s.statusText})`;throw u.error(o),new Error(o)}return t}async downloadRemoteFile(t){let e=this.getRemoteStorageUrl(t);return await this.download(e,t),t}async remoteFileExists(t){let e=this.getRemoteStorageUrl(t),r=await this.sdk.ensureGameplayJwt(),s=await fetch(e,{method:"HEAD",headers:{Authorization:`Bearer ${r}`}});if(s.status===404)return!1;if(s.ok)return!0;throw new Error(`${s.status} (${s.statusText})`)}async listRemoteDirectory(t){let e=this.getRemoteStorageUrl(t)+"?list=true",r=await this.sdk.ensureGameplayJwt(),s=await fetch(e,{method:"GET",headers:{Authorization:`Bearer ${r}`}});if(s.status===404)return[];if(!s.ok)throw new Error(`${s.status} (${s.statusText})`);return(await s.json()).files.filter(i=>!i.key.endsWith("/")).map(i=>({...i,key:this.toLocalPath(i.key)}))}async downloadRemoteDirectory(t){let r=(await this.listRemoteDirectory(t)).map(async i=>{let a=this.getRemoteStorageUrl(i.key);try{return await this.download(a,i.key),{fileName:i.name,success:!0}}catch(c){let l=c instanceof Error?c.message:String(c);return u.error(`Failed to download ${i.name}: ${l}`),{fileName:i.name,success:!1}}}),o=(await Promise.all(r)).filter(i=>!i.success);if(o.length>0)throw new Error(`Failed to download ${o.length} files: ${o.map(i=>i.fileName).join(", ")}`);return t}async writeLocalFile(t,e){if(u.debug(`Writing local file: ${t}`),this.sdk.engineInstance?.FS)return u.error(`${this.sdk.engineInstance.type} engine detected, use engine's builtin file access to save files.`),!1;try{return await Qr(t,e),!0}catch(r){return u.error(`Failed to write local file: ${r}`),!1}}async readLocalFile(t){if(u.debug(`Reading local file: ${t}`),this.sdk.engineInstance?.FS)return u.error(`${this.sdk.engineInstance.type} engine detected, use engine's builtin file access to read files.`),null;try{let e=await this.readLocalFileBlob(t);if(!e)return null;let r=await e.arrayBuffer();return new Uint8Array(r)}catch(e){return u.error(`Failed to read local file: ${e}`),null}}async upload(t,e){if(u.debug(`Uploading ${e} to: ${t}`),this.sdk.engineInstance&&!this.sdk.engineInstance.FS)return u.error("Engine instance is missing the Emscripten FS API"),!1;let r=!1;return this.sdk.engineInstance?r=await this.uploadFromFS(t,e):r=await this.uploadFromIndexedDb(t,e),r}async download(t,e){if(u.debug(`Downloading ${e} from: ${t}`),this.sdk.engineInstance&&!this.sdk.engineInstance.FS)throw new Error("Engine instance is missing the Emscripten FS API");let r=await this.sdk.ensureGameplayJwt(),s=await fetch(t,{method:"GET",headers:{Authorization:`Bearer ${r}`}});if(!s.ok)throw new Error(`${s.status} (${s.statusText})`);let i=await(await s.blob()).arrayBuffer(),a=new Uint8Array(i);if(this.sdk.engineInstance){let c=e.substring(0,e.lastIndexOf("/"));if(c)try{this.sdk.engineInstance.FS.mkdirTree(c)}catch{}try{this.sdk.engineInstance.FS.writeFile(e,a)}catch(l){let d=l instanceof Error?l.message:String(l);throw new Error(`Failed to save file ${e} to engine FS: ${d}`)}}else if(!await this.writeLocalFile(e,a))throw new Error(`Failed to save file ${e} to local IndexedDB storage`);u.debug(`Successfully saved to: ${e}`)}getRemoteStorageOrigin(){if(this.remoteStorageOrigin)return this.remoteStorageOrigin;if(this.sdk.config?.remoteStorageOrigin)return this.remoteStorageOrigin=this.sdk.config.remoteStorageOrigin,this.remoteStorageOrigin;if(this.sdk.ugcHost)return this.remoteStorageOrigin=this.sdk.ugcHost.startsWith("http")?this.sdk.ugcHost:`https://${this.sdk.ugcHost}`,this.remoteStorageOrigin;if(typeof window<"u"&&window.location){let e=window.location.hostname.split(".");return this.remoteStorageOrigin=`${window.location.protocol}//ugc.`+e.slice(2).join("."),this.remoteStorageOrigin}throw new Error("Remote storage origin cannot be determined.")}getRemoteStorageUrl(t){return`${this.getRemoteStorageOrigin()}/${this.toRemoteKey(t)}`}async uploadFromIndexedDb(t,e){try{let r=await this.readLocalFileBlob(e);return r?(await fetch(t,{method:"PUT",body:r})).ok:(u.error(`File not found in IndexedDB: ${e}`),!1)}catch(r){return u.error(`Error uploading from IndexedDB: ${r}`),!1}}async uploadFromFS(t,e){try{if(!this.sdk.engineInstance.FS.analyzePath(e).exists)throw new Error(`File not found in FS: ${e}`);let s=this.sdk.engineInstance.FS.readFile(e),o=new Blob([s],{type:"application/octet-stream"});return(await fetch(t,{method:"PUT",body:o})).ok}catch(r){let s=r instanceof Error?r.message:String(r);return u.error(`Error uploading from FS: ${s}`),!1}}async readLocalFileBlob(t){if(u.debug(`Reading local file (blob): ${t}`),this.sdk.engineInstance?.FS)return u.error(`${this.sdk.engineInstance.type} engine detected, use engine's builtin file access to read files.`),null;try{let e=await Hr(t);return e?jr(e):null}catch(e){return u.error(`Failed to read local file blob: ${e}`),null}}};function zr(n,t,e){if(n.startsWith("http://")||n.startsWith("https://"))return n;let r=e?Object.entries(e).filter(([,s])=>s!==void 0).map(([s,o])=>s==="background"?`${s}=${encodeURIComponent(o)}`:`${s}=${o}`).join(","):"";return`https://${t}/cdn-cgi/image/${r}/${n}`}var wt=class extends w{constructor(e){super(e);this.userCache=new Map;this.leaderboardPageUserCache=new Map}getUserAvatarUrl(e,r=ft.MEDIUM){let s=this.userCache.get(e)??this.leaderboardPageUserCache.get(e);return s?.avatarR2Key?zr(s.avatarR2Key,this.sdk.uploadsHost,{width:r,height:r,fit:"cover",quality:"high",sharpen:1}):null}getUsername(e){return this.userCache.get(e)?.username??this.leaderboardPageUserCache.get(e)?.username??null}async listFriends(){let e=await this.sdk.convexClient.query(f.sdk.friends.listFriends,{});return this.cacheUsers(e),e}cacheUsers(e){for(let r of e)this.userCache.set(r.userId,{username:r.username,avatarR2Key:r.avatarUrl??r.userAvatarUrl})}cacheLeaderboardPage(e){this.leaderboardPageUserCache.clear();for(let r of e)this.leaderboardPageUserCache.set(r.userId,{username:r.username,avatarR2Key:r.userAvatarUrl})}};var Et=class extends w{constructor(e){super(e);this._isFullscreen=!1;this.listeners=new Set;k()&&(this.sdk.iframeMessenger.addEventListener(E.FULLSCREEN_CHANGED,r=>{this.sdk.gameEventManager.notifyGame(v.FULLSCREEN_CHANGED,{isFullscreen:r.isFullscreen}),this.setState(r.isFullscreen)}),this.installCompatShims())}isFullscreen(){return this._isFullscreen}async requestFullscreen(e){return k()?(await this.sdk.iframeMessenger.requestFromParent(E.SET_FULLSCREEN,{fullscreen:e})).success:(u.debug("requestFullscreen() is disabled outside a Wavedash parent frame (e.g. `wavedash dev`)"),!1)}async toggleFullscreen(){return k()?(await this.sdk.iframeMessenger.requestFromParent(E.TOGGLE_FULLSCREEN)).success:(u.debug("toggleFullscreen() is disabled outside a Wavedash parent frame (e.g. `wavedash dev`)"),!1)}subscribe(e){return this.listeners.add(e),()=>this.listeners.delete(e)}setState(e){if(this._isFullscreen!==e){this._isFullscreen=e;for(let r of this.listeners)r(e)}}installCompatShims(){if(typeof document>"u")return;let e=()=>this._isFullscreen?document.body:null;Object.defineProperty(document,"fullscreenElement",{configurable:!0,get:e}),Object.defineProperty(document,"webkitFullscreenElement",{configurable:!0,get:e});let r=async()=>{if(this._isFullscreen)return;if(!await this.requestFullscreen(!0))throw new Error("Fullscreen request was denied")},s=async()=>{if(!this._isFullscreen)return;if(!await this.requestFullscreen(!1))throw new Error("Exit fullscreen request was denied")};Element.prototype.requestFullscreen=function(){return r()},Element.prototype.webkitRequestFullscreen=function(){return r()},Document.prototype.exitFullscreen=function(){return s()},Document.prototype.webkitExitFullscreen=function(){return s()},this.subscribe(()=>{document.dispatchEvent(new Event("fullscreenchange",{bubbles:!0}))})}};var St=class extends w{constructor(e){super(e);this.eventQueue=[]}notifyGame(e,r){if(!this.sdk.eventsReady){this.eventQueue.push({event:e,payload:r}),u.debug(`Queued event: ${e}`);return}this.sdk.engineInstance?this.sendGameEvent(e,r):this.sdk.dispatchEvent(new CustomEvent(e,{detail:r}))}sendGameEvent(e,r){let s=typeof r=="object"?JSON.stringify(r):r;this.sdk.engineInstance?.SendMessage?this.sdk.engineInstance.SendMessage(this.sdk.engineCallbackReceiver,e,s):u.error("Engine instance not set. Dropping event:",e)}flushEventQueue(){let e=this.eventQueue;this.eventQueue=[];for(let r of e)this.notifyGame(r.event,r.payload)}};var te={passive:!0,capture:!0},Ct=class extends w{constructor(e){super(e);this.deviceFingerprint=void 0;this.testConnectionInterval=null;this.heartbeatInterval=null;this.gamepadPollInterval=null;this.inactivityTimeout=null;this.isConnected=!1;this.sentDisconnectedEvent=!1;this.disconnectedAt=null;this.lastHeartbeatTime=0;this.lastInputResetAt=0;this.heartbeatInFlight=!1;this.isFirstTick=!0;this.TEST_CONNECTION_INTERVAL_MS=1e3;this.DISCONNECTED_TIMEOUT_MS=9e4;this.INACTIVITY_TIMEOUT_MS=1800*1e3;this.INPUT_THROTTLE_MS=1e3;this.GAMEPAD_POLL_INTERVAL_MS=1e3;this.GAMEPAD_AXIS_DEADZONE=.2;this.cachedPresenceData={};this.handleVisibilityChange=()=>{document.visibilityState==="visible"?this.start():this.stop()};this.handleUserInput=()=>{let e=Date.now();e-this.lastInputResetAt<this.INPUT_THROTTLE_MS||(this.lastInputResetAt=e,this.start())};this.isConnected=this.sdk.convexClient.client.connectionState().isWebSocketConnected,document.addEventListener("visibilitychange",this.handleVisibilityChange),window.addEventListener("keydown",this.handleUserInput,te),window.addEventListener("pointerdown",this.handleUserInput,te),window.addEventListener("pointermove",this.handleUserInput,te),window.addEventListener("wheel",this.handleUserInput,te),this.gamepadPollInterval=setInterval(()=>{this.pollGamepads()},this.GAMEPAD_POLL_INTERVAL_MS),this.deviceFingerprintReady=k()?this.sdk.iframeMessenger.requestFromParent(E.GET_DEVICE_FINGERPRINT).then(r=>{this.deviceFingerprint=r}).catch(()=>{}):Promise.resolve()}start(){this.sdk.gameLoaded&&document.visibilityState==="visible"&&(this.inactivityTimeout!==null&&clearTimeout(this.inactivityTimeout),this.inactivityTimeout=setTimeout(()=>{this.stop()},this.INACTIVITY_TIMEOUT_MS),this.heartbeatInterval===null&&(this.isFirstTick?this.deviceFingerprintReady.then(()=>{!this.sdk.gameLoaded||!this.isFirstTick||this.tickHeartbeat()}):this.tickHeartbeat(),this.heartbeatInterval=setInterval(()=>{this.tickHeartbeat()},_e.CLIENT_INTERVAL_MS),this.testConnectionInterval=setInterval(()=>{this.testConnection()},this.TEST_CONNECTION_INTERVAL_MS)))}stop(){this.inactivityTimeout!==null&&(clearTimeout(this.inactivityTimeout),this.inactivityTimeout=null),this.heartbeatInterval!==null&&(clearInterval(this.heartbeatInterval),this.heartbeatInterval=null),this.testConnectionInterval!==null&&(clearInterval(this.testConnectionInterval),this.testConnectionInterval=null)}async updateUserPresence(e){try{return this.cachedPresenceData=e,await this.sdk.convexClient.mutation(f.sdk.presence.heartbeat,{data:e,deviceFingerprint:this.deviceFingerprint}),!0}catch(r){return u.error(`Error updating presence: ${r}`),!1}}isCurrentlyConnected(){return this.isConnected}destroy(){this.stop(),this.gamepadPollInterval!==null&&(clearInterval(this.gamepadPollInterval),this.gamepadPollInterval=null),document.removeEventListener("visibilitychange",this.handleVisibilityChange),window.removeEventListener("keydown",this.handleUserInput,te),window.removeEventListener("pointerdown",this.handleUserInput,te),window.removeEventListener("pointermove",this.handleUserInput,te),window.removeEventListener("wheel",this.handleUserInput,te)}tickHeartbeat(){let e=Date.now()-this.lastHeartbeatTime,r=this.isFirstTick||e>=_e.CLIENT_REESTABLISH_THRESHOLD_MS;this.isFirstTick=!1,r?this.sendHeartbeat(!0):e>=_e.CLIENT_INTERVAL_MS-_e.CLIENT_GRACE_MS&&this.sendHeartbeat(!1)}sendHeartbeat(e){!e&&this.heartbeatInFlight||(this.heartbeatInFlight=!0,this.sdk.convexClient.mutation(f.sdk.presence.heartbeat,{...e?{data:this.cachedPresenceData,deviceFingerprint:this.deviceFingerprint}:{}}).then(r=>{r&&(this.lastHeartbeatTime=Date.now())}).catch(r=>{u.error(`Heartbeat failed: ${r}`)}).finally(()=>{this.heartbeatInFlight=!1}))}pollGamepads(){if(typeof navigator>"u"||!navigator.getGamepads)return;let e=navigator.getGamepads();for(let r of e)if(r){if(r.buttons.some(s=>s.pressed)){this.start();return}if(r.axes.some(s=>Math.abs(s)>this.GAMEPAD_AXIS_DEADZONE)){this.start();return}}}testConnection(){try{let e=this.isConnected,r=this.sdk.convexClient.client.connectionState();this.isConnected=navigator.onLine&&r.isWebSocketConnected;let s={isConnected:this.isConnected,hasEverConnected:r.hasEverConnected,connectionCount:r.connectionCount,connectionRetries:r.connectionRetries};this.isConnected&&!e?(this.disconnectedAt=null,this.sentDisconnectedEvent=!1,this.sdk.gameEventManager.notifyGame(v.BACKEND_CONNECTED,s)):!this.isConnected&&e?(this.disconnectedAt=Date.now(),u.warn("Backend disconnected - attempting to reconnect..."),this.sdk.gameEventManager.notifyGame(v.BACKEND_RECONNECTING,s)):!this.isConnected&&!e?this.disconnectedAt&&!this.sentDisconnectedEvent&&Date.now()-this.disconnectedAt>this.DISCONNECTED_TIMEOUT_MS&&(this.sdk.gameEventManager.notifyGame(v.BACKEND_DISCONNECTED,s),this.sentDisconnectedEvent=!0):this.isConnected&&e&&(this.disconnectedAt=null,this.sentDisconnectedEvent=!1)}catch(e){u.error("Error testing connection:",e)}}};var It=class extends w{constructor(e){super(e);this.leaderboardCache=new Map}async getLeaderboard(e){let r=await this.sdk.convexClient.query(f.sdk.leaderboards.getLeaderboard,{name:e});return this.leaderboardCache.set(r.id,r),r}async getOrCreateLeaderboard(e,r,s){let o=await this.sdk.convexClient.mutation(f.sdk.leaderboards.getOrCreateLeaderboard,{name:e,sortOrder:r,displayType:s});return this.leaderboardCache.set(o.id,o),o}getLeaderboardEntryCount(e){let r=this.leaderboardCache.get(e);return r?r.totalEntries:-1}async getMyLeaderboardEntries(e){let r=await this.sdk.convexClient.query(f.sdk.leaderboards.getMyLeaderboardEntry,{leaderboardId:e});r&&r.totalEntries&&this.updateCachedTotalEntries(e,r.totalEntries);let s=r.entry?{...r.entry,userId:this.sdk.wavedashUser.id,username:this.sdk.wavedashUser.username,userAvatarUrl:this.sdk.wavedashUser.avatarUrl}:null;return s?[s]:[]}async listLeaderboardEntriesAroundUser(e,r,s,o=!1){let i=await this.sdk.convexClient.query(f.sdk.leaderboards.listEntriesAroundUser,{leaderboardId:e,countAhead:r,countBehind:s,friendsOnly:o});return i&&i.totalEntries&&this.updateCachedTotalEntries(e,i.totalEntries),this.sdk.friendsManager.cacheLeaderboardPage(i.entries),i.entries}async listLeaderboardEntries(e,r,s,o=!1){let i=await this.sdk.convexClient.query(f.sdk.leaderboards.listEntries,{leaderboardId:e,offset:r,limit:s,friendsOnly:o});return i&&i.totalEntries&&this.updateCachedTotalEntries(e,i.totalEntries),this.sdk.friendsManager.cacheLeaderboardPage(i.entries),i.entries}async uploadLeaderboardScore(e,r,s,o){let i=await this.sdk.convexClient.mutation(f.sdk.leaderboards.upsertLeaderboardEntry,{leaderboardId:e,score:r,keepBest:s,ugcId:o});return i&&i.totalEntries&&this.updateCachedTotalEntries(e,i.totalEntries),{...i.entry,submittedScore:i.submission.score,submittedRank:i.submission.globalRank,userId:this.sdk.wavedashUser.id,username:this.sdk.wavedashUser.username,userAvatarUrl:this.sdk.wavedashUser.avatarUrl}}updateCachedTotalEntries(e,r){let s=this.leaderboardCache.get(e);s&&typeof r=="number"&&this.leaderboardCache.set(e,{...s,totalEntries:r})}};var tn=hr(cr(),1);var At=class At extends w{constructor(e){super(e);this.unsubscribeLobbyMessages=null;this.unsubscribeLobbyUsers=null;this.unsubscribeLobbyData=null;this.lobbyId=null;this.lobbyUsers=[];this.lobbyHostId=null;this.lobbyMetadata={};this.pendingMetadataUpdates={};this.recentMessageIds=[];this.maybeBeingDeletedLobbyIds=new Set;this.resetMaybeBeingDeletedLobbyIdTimeouts=new Map;this.inFlightMetadataUpdate=null;this.cachedLobbies={};this.unsubscribeLobbyInvites=null;this.seenInviteIds=new Set;this.p2pUpdateQueue=Promise.resolve();this.throttledSetMetadata=(0,tn.default)(()=>this.setMetadata(),At.METADATA_UPDATE_THROTTLE_MS,{leading:!1,trailing:!0});this.processUserUpdates=e=>{this.sdk.friendsManager.cacheUsers(e);let r=this.lobbyUsers,s=new Set(r.map(i=>i.userId)),o=new Set(e.map(i=>i.userId));this.lobbyUsers=e;for(let i of e)i.isHost&&(this.lobbyHostId=i.userId),s.has(i.userId)||this.sdk.gameEventManager.notifyGame(v.LOBBY_USERS_UPDATED,{...i,changeType:ke.JOINED});for(let i of r)o.has(i.userId)||(i.userId===this.sdk.getUserId()&&u.warn("USER WAS KICKED FROM LOBBY! Received notification for myself leaving."),this.sdk.gameEventManager.notifyGame(v.LOBBY_USERS_UPDATED,{...i,isHost:!1,changeType:ke.LEFT}));this.lobbyId&&(this.p2pUpdateQueue=this.p2pUpdateQueue.then(()=>this.updateP2PConnections(e)).catch(i=>{u.error("Error in queued P2P update:",i)}))};this.processMessageUpdates=e=>{for(let r of e)this.recentMessageIds.includes(r.messageId)||(this.recentMessageIds.push(r.messageId),this.sdk.gameEventManager.notifyGame(v.LOBBY_MESSAGE,r));this.recentMessageIds=e.map(r=>r.messageId)};this.processInviteUpdates=e=>{for(let r of e)this.seenInviteIds.has(r.notificationId)||(this.seenInviteIds.add(r.notificationId),this.sdk.gameEventManager.notifyGame(v.LOBBY_INVITE,r));this.seenInviteIds=new Set(e.map(r=>r.notificationId))};this.unsubscribeLobbyInvites=this.sdk.convexClient.onUpdate(f.sdk.gameLobby.getLobbyInvites,{},this.processInviteUpdates,r=>{u.error(`Lobby invites subscription error: ${r}`)})}async createLobby(e,r){let s=await this.sdk.convexClient.mutation(f.sdk.gameLobby.createAndJoinLobby,{visibility:e,maxPlayers:r});return this.handleLobbyJoin(s),s.lobbyId}async joinLobby(e){let r=await this.sdk.convexClient.mutation(f.sdk.gameLobby.joinLobby,{lobbyId:e});return this.handleLobbyJoin(r),!0}getLobbyUsers(e){return this.lobbyId!==e?(u.error("Must be a member of the lobby to access user list"),[]):this.lobbyUsers}getHostId(e){return this.lobbyId!==e?(u.error("Must be a member of the lobby to access the host ID"),null):this.lobbyHostId}getLobbyData(e,r){return this.lobbyId===e?this.lobbyMetadata[r]??null:this.cachedLobbies[e]?this.cachedLobbies[e].metadata[r]??null:null}deleteLobbyData(e,r){return this.setLobbyData(e,r,null)}setLobbyData(e,r,s){return this.lobbyId!==e||this.lobbyHostId!==this.sdk.getUserId()?!1:(this.lobbyMetadata[r]===s||(s===null?delete this.lobbyMetadata[r]:this.lobbyMetadata[r]=s,this.pendingMetadataUpdates[r]=s,this.throttledSetMetadata()),!0)}getLobbyMaxPlayers(e){return this.cachedLobbies[e]?this.cachedLobbies[e].maxPlayers:0}getNumLobbyUsers(e){return this.lobbyId===e?this.lobbyUsers.length:this.cachedLobbies[e]?this.cachedLobbies[e].playerCount:0}async leaveLobby(e){return this.cleanupLobbyState(),await this.sdk.convexClient.mutation(f.sdk.gameLobby.leaveLobby,{lobbyId:e}),this.sdk.iframeMessenger.postToParent(E.LOBBY_LEFT,{lobbyId:e}),e}async listAvailableLobbies(e=!1){let r=e?{friendsOnly:e}:void 0,o=(await this.sdk.convexClient.query(f.sdk.gameLobby.listAvailable,{filters:r})).filter(i=>!this.maybeBeingDeletedLobbyIds.has(i.lobbyId));for(let i of o)this.cachedLobbies[i.lobbyId]=i;return o}sendLobbyMessage(e,r){let s={lobbyId:e,message:r};if(r.length===0)return u.error("Message cannot be empty"),!1;if(r.length>lt)return u.error(`Message cannot be longer than ${lt} characters`),!1;try{this.sdk.convexClient.mutation(f.sdk.gameLobby.sendMessage,s)}catch(o){return u.error(`Error sending lobby message: ${o}`),!1}return!0}async inviteUserToLobby(e,r){return await this.sdk.convexClient.mutation(f.sdk.gameLobby.inviteToLobby,{lobbyId:e,targetUserId:r}),!0}async getLobbyInviteLink(e=!1){if(!this.lobbyId)throw new Error("User is not in a lobby");if(!k())throw new Error("Lobby invite links are not available outside a Wavedash parent frame (e.g. `wavedash dev`)");let r=await this.sdk.iframeMessenger.requestFromParent(E.GET_LOBBY_INVITE_LINK,{lobbyId:this.lobbyId,copyToClipboard:e});if(!r)throw new Error("Parent could not generate invite link");return r}handleLobbyJoin(e){this.cleanupLobbyState(),this.lobbyId=e.lobbyId,this.lobbyHostId=e.hostId,this.lobbyUsers=e.users,this.lobbyMetadata=e.metadata,this.sdk.friendsManager.cacheUsers(e.users);let r=s=>{u.error(`Lobby subscription error: ${s.message}`),s.message.includes("not a member")?this.handleLobbyKicked(ye.KICKED):this.handleLobbyKicked(ye.ERROR)};this.unsubscribeLobbyMessages=this.sdk.convexClient.onUpdate(f.sdk.gameLobby.lobbyMessages,{lobbyId:e.lobbyId},this.processMessageUpdates,r),this.unsubscribeLobbyData=this.sdk.convexClient.onUpdate(f.sdk.gameLobby.getLobbyMetadata,{lobbyId:e.lobbyId},s=>{this.lobbyMetadata=s,this.sdk.gameEventManager.notifyGame(v.LOBBY_DATA_UPDATED,s)},r),this.unsubscribeLobbyUsers=this.sdk.convexClient.onUpdate(f.sdk.gameLobby.lobbyUsers,{lobbyId:e.lobbyId},this.processUserUpdates,r),e.users.length>1&&(this.p2pUpdateQueue=this.updateP2PConnections(e.users).catch(s=>{u.error("Error initializing P2P on join:",s)})),this.sdk.iframeMessenger.postToParent(E.LOBBY_JOINED,{lobbyId:e.lobbyId}),this.sdk.gameEventManager.notifyGame(v.LOBBY_JOINED,{lobbyId:e.lobbyId,hostId:e.hostId,users:e.users,metadata:e.metadata}),u.debug("Subscribed to lobby:",e.lobbyId)}handleLobbyKicked(e=ye.KICKED){let r=this.lobbyId;r&&(u.warn(`User was removed from lobby: ${r} (reason: ${e})`),this.cleanupLobbyState(),this.sdk.iframeMessenger.postToParent(E.LOBBY_LEFT,{lobbyId:r}),this.sdk.gameEventManager.notifyGame(v.LOBBY_KICKED,{lobbyId:r,reason:e}))}cleanupLobbyState(){let e=this.lobbyId;if(this.lobbyId=null,this.throttledSetMetadata.cancel(),this.pendingMetadataUpdates={},this.unsubscribeLobbyMessages&&(this.unsubscribeLobbyMessages(),this.unsubscribeLobbyMessages=null),this.unsubscribeLobbyUsers&&(this.unsubscribeLobbyUsers(),this.unsubscribeLobbyUsers=null),this.unsubscribeLobbyData&&(this.unsubscribeLobbyData(),this.unsubscribeLobbyData=null),this.sdk.p2pManager.disconnectP2P(),e&&this.lobbyUsers.length===1){let r=this.resetMaybeBeingDeletedLobbyIdTimeouts.get(e);r&&clearTimeout(r),this.maybeBeingDeletedLobbyIds.add(e);let s=setTimeout(()=>{this.maybeBeingDeletedLobbyIds.delete(e),this.resetMaybeBeingDeletedLobbyIdTimeouts.delete(e)},500);this.resetMaybeBeingDeletedLobbyIdTimeouts.set(e,s)}this.lobbyUsers=[],this.lobbyHostId=null,this.lobbyMetadata={},this.recentMessageIds=[],this.p2pUpdateQueue=Promise.resolve()}unsubscribeFromCurrentLobby(){this.cleanupLobbyState()}destroy(){this.cleanupLobbyState(),this.unsubscribeLobbyInvites&&(this.unsubscribeLobbyInvites(),this.unsubscribeLobbyInvites=null);for(let e of this.resetMaybeBeingDeletedLobbyIdTimeouts.values())clearTimeout(e);this.resetMaybeBeingDeletedLobbyIdTimeouts.clear(),this.maybeBeingDeletedLobbyIds.clear(),this.seenInviteIds.clear(),this.cachedLobbies={}}setMetadata(){if(this.inFlightMetadataUpdate!==null||this.lobbyId===null||Object.keys(this.pendingMetadataUpdates).length===0)return;let e=this.pendingMetadataUpdates;this.pendingMetadataUpdates={},this.inFlightMetadataUpdate=this.sdk.convexClient.mutation(f.sdk.gameLobby.setLobbyMetadata,{lobbyId:this.lobbyId,updates:e}).catch(r=>{u.error("Error updating lobby metadata:",r)}).finally(()=>{this.inFlightMetadataUpdate=null,Object.keys(this.pendingMetadataUpdates).length>0&&this.throttledSetMetadata()})}async updateP2PConnections(e){if(this.lobbyId)try{if(e.length<=1){this.sdk.p2pManager.disconnectP2P(),u.debug("Only one user in lobby, P2P connections disconnected");return}let r=e.map(s=>({id:s.userId,username:s.username,avatarUrl:s.userAvatarUrl}));await this.sdk.p2pManager.initializeP2PForCurrentLobby(this.lobbyId,r),u.debug(`P2P connections updated for lobby ${this.lobbyId} with ${r.length} users`)}catch(r){u.error("Error updating P2P connections:",r)}}};At.METADATA_UPDATE_THROTTLE_MS=150;var Tt=At;function rn(){if(typeof document>"u")return;let n=document.getElementsByClassName("game-focus-target");if(n.length>0){n[0].focus();return}document.querySelector("canvas, input, button, [tabindex]:not([tabindex='-1'])")?.focus()}var on=typeof Element<"u"&&typeof document<"u",nn=on?Element.prototype.requestPointerLock:void 0,sn=0;function xt(){if(!on||!nn)return()=>{};++sn===1&&(Element.prototype.requestPointerLock=function(){return Promise.resolve()}),document.exitPointerLock();let n=!1;return()=>{n||(n=!0,--sn===0&&(Element.prototype.requestPointerLock=nn))}}var Mt=class extends w{constructor(e){super(e);this.handleKeyDown=e=>{e.key==="Tab"&&e.shiftKey&&(e.preventDefault(),this.toggleOverlay())};k()&&(this.sdk.iframeMessenger.addEventListener(E.TAKE_FOCUS,rn),this.sdk.iframeMessenger.addEventListener(E.OVERLAY_CHANGED,({isOpen:r})=>this.setOpen(r)),typeof window<"u"&&window.addEventListener("keydown",this.handleKeyDown))}setOpen(e){e?this.restorePointerLock??(this.restorePointerLock=xt()):(this.restorePointerLock?.(),this.restorePointerLock=void 0)}toggleOverlay(){this.sdk.iframeMessenger.postToParent(E.TOGGLE_OVERLAY,{})}destroy(){this.restorePointerLock?.(),this.restorePointerLock=void 0,typeof window<"u"&&window.removeEventListener("keydown",this.handleKeyDown)}};var an={enableReliableChannel:!0,enableUnreliableChannel:!0,messageSize:2048,maxIncomingMessages:1024},K=class K extends w{constructor(e){super(e);this.currentConnection=null;this.peerConnections=new Map;this.reliableChannels=new Map;this.unreliableChannels=new Map;this.pendingIceCandidates=new Map;this.iceRestartAttempts=new Map;this.iceRestartInProgress=new Set;this.MAX_ICE_RESTART_ATTEMPTS=3;this.reconnectingPeers=new Set;this.establishedPeers=new Set;this.packetDropTrackers=new Map;this.PACKET_DROP_WINDOW_MS=500;this.turnCredentials=null;this.turnCredentialsInitPromise=null;this.unsubscribeFromSignalingMessages=null;this.processedSignalingMessages=new Set;this.pendingProcessedMessageIds=new Set;this.initializationInProgress=null;this.initializationLobbyId=null;this.signalingSubscriptionReady=null;this.signalingSubscriptionReadyResolver=null;this.channelQueues=new Map;this.MESSAGE_SLOT_HEADER_SIZE=4;this.MAX_CHANNELS=8;this.USERID_SIZE=32;this.CHANNEL_SIZE=4;this.DATALENGTH_SIZE=4;this.CHANNEL_OFFSET=this.USERID_SIZE;this.DATALENGTH_OFFSET=this.USERID_SIZE+this.CHANNEL_SIZE;this.PAYLOAD_OFFSET=this.USERID_SIZE+this.CHANNEL_SIZE+this.DATALENGTH_SIZE;this.WIRE_CHANNEL_SIZE=1;this.WIRE_CHANNEL_OFFSET=0;this.WIRE_PAYLOAD_OFFSET=this.WIRE_CHANNEL_SIZE;this.textEncoder=new TextEncoder;this.textDecoder=new TextDecoder;this.initialized=!1;this.config={...an}}destroy(){this.disconnectP2P()}ensureInitialized(){this.initialized||this.init()}init(e){if(this.initialized&&!e)return;this.config={...an,...e};let r=this.MESSAGE_SLOT_HEADER_SIZE+this.PAYLOAD_OFFSET+1,s=this.config.messageSize,o=this.config.maxIncomingMessages;if(s<r)throw new Error(`P2P messageSize must be at least ${r} bytes (got ${s})`);if(s>K.MAX_MESSAGE_SIZE&&console.warn(`P2P messageSize ${s} exceeds max ${K.MAX_MESSAGE_SIZE}, clamping to ${K.MAX_MESSAGE_SIZE}`),o<1)throw new Error(`P2P maxIncomingMessages must be at least 1 (got ${o})`);this.MESSAGE_SIZE=Math.min(s,K.MAX_MESSAGE_SIZE),this.QUEUE_SIZE=o,this.MAX_PAYLOAD_SIZE=this.MESSAGE_SIZE-this.MESSAGE_SLOT_HEADER_SIZE-this.PAYLOAD_OFFSET,this.outgoingMessageBuffer=new Uint8Array(this.MAX_PAYLOAD_SIZE);let i=this.MESSAGE_SIZE*this.QUEUE_SIZE*this.MAX_CHANNELS;i>K.MEMORY_WARNING_THRESHOLD_BYTES&&console.warn(`P2P ring buffer memory could reach ${(i/1024/1024).toFixed(1)}MB if all ${this.MAX_CHANNELS} channels are used (messageSize=${this.MESSAGE_SIZE} x maxIncomingMessages=${this.QUEUE_SIZE} per channel). Consider reducing maxIncomingMessages if memory is a concern.`),this.initialized=!0}async initializeP2PForCurrentLobby(e,r){if(this.ensureInitialized(),this.currentConnection&&this.currentConnection.lobbyId===e)return this.updateP2PConnection(r);if(this.initializationInProgress&&this.initializationLobbyId===e&&(u.debug("P2P initialization already in progress, waiting..."),await this.initializationInProgress,this.currentConnection))return this.updateP2PConnection(r);this.initializationLobbyId=e,this.initializationInProgress=this.doInitializeP2P(e,r);try{return await this.initializationInProgress}finally{this.initializationInProgress=null,this.initializationLobbyId=null}}async doInitializeP2P(e,r){let s={lobbyId:e,peers:{}};return r.forEach(o=>{o.id!==this.sdk.getUserId()&&(s.peers[o.id]={userId:o.id,username:o.username})}),this.currentConnection=s,await this.establishWebRTCConnections(s),s}async getIceServers(){return this.turnCredentials&&this.turnCredentials.expiresAt>Date.now()+36e5?this.turnCredentials.iceServers:this.turnCredentialsInitPromise?(await this.turnCredentialsInitPromise,this.turnCredentials?.iceServers??null):(this.turnCredentialsInitPromise=(async()=>{try{this.turnCredentials=await this.sdk.convexClient.action(f.sdk.turnCredentials.getOrCreate,{})}finally{this.turnCredentialsInitPromise=null}})(),await this.turnCredentialsInitPromise,this.turnCredentials?.iceServers??null)}async updateP2PConnection(e){if(!this.currentConnection)throw new Error("No existing P2P connection to update");u.debug("Updating P2P connection with new member list"),new Set(Object.keys(this.currentConnection.peers)).add(this.sdk.getUserId());let s=new Set(e.map(i=>i.id)),o=[];for(let i of e){if(i.id===this.sdk.getUserId())continue;let a=this.currentConnection.peers[i.id];a?!a.username&&i.username&&(a.username=i.username):(u.debug(`Adding new peer: ${i.username} (${i.id})`),this.currentConnection.peers[i.id]={userId:i.id,username:i.username},o.push(i.id))}if(o.length>0){let i=this.sdk.getUserId(),a=o.map(l=>{let d=i<l;return u.debug(`Creating connection to new peer ${l}, shouldCreateChannels: ${d}`),this.createPeerConnection(l,this.currentConnection,d)});await Promise.all(a);let c=o.filter(l=>i<l);if(c.length>0){let l=c.map(d=>(u.debug(`Initiating offer to new peer ${d} (lower userId rule)`),this.createOfferToPeer(d)));await Promise.all(l),u.debug(`Initiated ${l.length} offers to new peers`)}}for(let i of Object.keys(this.currentConnection.peers))if(!s.has(i)){let a=this.currentConnection.peers[i];u.debug(`Peer left: ${a.username} (${i})`);let c=this.peerConnections.get(i);c&&(c.close(),this.peerConnections.delete(i)),this.reliableChannels.delete(i),this.unreliableChannels.delete(i),this.pendingIceCandidates.delete(i),this.iceRestartAttempts.delete(i),this.iceRestartInProgress.delete(i),this.reconnectingPeers.delete(i),this.establishedPeers.delete(i),delete this.currentConnection.peers[i]}return this.currentConnection}async establishWebRTCConnections(e){this.subscribeToSignalingMessages(e),this.signalingSubscriptionReady&&(await this.signalingSubscriptionReady,u.debug("Signaling subscription confirmed ready")),await this.establishPeerConnections(e)}subscribeToSignalingMessages(e){this.signalingSubscriptionReady=new Promise(s=>{this.signalingSubscriptionReadyResolver=s});let r=!1;this.unsubscribeFromSignalingMessages=this.sdk.convexClient.onUpdate(f.sdk.p2pSignaling.getSignalingMessages,{lobbyId:e.lobbyId},s=>{r||(r=!0,this.signalingSubscriptionReadyResolver?.(),this.signalingSubscriptionReadyResolver=null),s&&this.processSignalingMessages(s,e)})}stopSignalingMessageSubscription(){this.unsubscribeFromSignalingMessages!==null&&(this.unsubscribeFromSignalingMessages(),this.unsubscribeFromSignalingMessages=null)}async processSignalingMessages(e,r){if(e.length===0)return;let s=[],o=[];for(let i of e)!this.processedSignalingMessages.has(i._id)&&!this.pendingProcessedMessageIds.has(i._id)&&o.push(i),s.push(i._id);for(let i of o){this.pendingProcessedMessageIds.add(i._id);try{await this.handleSignalingMessage(i,r),this.processedSignalingMessages.add(i._id)}catch(a){u.error("Error handling signaling message:",a)}}if(s.length>0)try{await this.sdk.convexClient.mutation(f.sdk.p2pSignaling.markSignalingMessagesProcessed,{messageIds:s});for(let i of s)this.pendingProcessedMessageIds.delete(i)}catch(i){u.error("Failed to mark signaling messages as processed:",i);for(let a of s)this.pendingProcessedMessageIds.delete(a)}}async handleSignalingMessage(e,r){if(e.fromUserId===this.sdk.getUserId())return;let s=e.fromUserId;if(!this.peerConnections.has(s))if(e.messageType===J.OFFER){if(u.debug(`Received offer from ${s} before peer connection exists, creating on-demand`),r.peers[s]||(r.peers[s]={userId:s,username:""}),!await this.createPeerConnection(s,r,!1)){u.error(`Failed to create on-demand peer connection for ${s}`);return}}else{u.warn(`No peer connection for user ${s}, dropping ${e.messageType} message`);return}let o=this.peerConnections.get(s);switch(e.messageType){case J.OFFER:{this.iceRestartInProgress.delete(s),u.debug(`Processing offer from peer ${s}:`),await o.setRemoteDescription(new RTCSessionDescription(e.data)),await this.flushPendingIceCandidates(s,o);let i=await o.createAnswer();await o.setLocalDescription(i),u.debug(" Answer created, waiting for ondatachannel events...");let a={type:i.type,sdp:i.sdp};await this.sendSignalingMessage(s,{type:J.ANSWER,data:a});break}case J.ANSWER:await o.setRemoteDescription(new RTCSessionDescription(e.data)),await this.flushPendingIceCandidates(s,o);break;case J.ICE_CANDIDATE:{let i=e.data;if(o.remoteDescription)await o.addIceCandidate(new RTCIceCandidate(i));else{let a=this.pendingIceCandidates.get(s)||[];a.push(i),this.pendingIceCandidates.set(s,a),u.debug(`Buffered ICE candidate for ${s} (remote description not yet set, ${a.length} buffered)`)}break}default:u.warn("Unknown signaling message type:",e.messageType)}}async flushPendingIceCandidates(e,r){let s=this.pendingIceCandidates.get(e);if(s&&s.length>0){for(let o of s)try{await r.addIceCandidate(new RTCIceCandidate(o))}catch(i){u.warn(`Failed to add buffered ICE candidate for ${e}:`,i)}this.pendingIceCandidates.delete(e)}}async establishPeerConnections(e){u.debug("Establishing WebRTC connections to peers...");let r=this.sdk.getUserId(),s=[];Object.entries(e.peers).forEach(([i,a])=>{let c=r<i;u.debug(`Creating connection to peer ${i} (${a.username}), shouldCreateChannels: ${c}`),s.push(this.createPeerConnection(i,e,c))}),await Promise.all(s);let o=Object.keys(e.peers).filter(i=>r<i);if(o.length>0){let i=o.map(a=>(u.debug(`Initiating offer to peer ${a} (lower userId rule)`),this.createOfferToPeer(a)));await Promise.all(i),u.debug(`Created ${s.length} peer connections and initiated ${i.length} offers`)}else u.debug(`Created ${s.length} peer connections, no offers to initiate`)}async createOfferToPeer(e){let r=this.peerConnections.get(e);if(!r)throw new Error(`No peer connection for user ${e}`);let s=this.reliableChannels.get(e),o=this.unreliableChannels.get(e);u.debug(`Creating offer to peer ${e}:`),u.debug(` Reliable channel state: ${s?.readyState||"none"}`),u.debug(` Unreliable channel state: ${o?.readyState||"none"}`);let i=await r.createOffer();await r.setLocalDescription(i);let a={type:i.type,sdp:i.sdp};await this.sendSignalingMessage(e,{type:J.OFFER,data:a})}async createPeerConnection(e,r,s=!1){let o=await this.getIceServers();if(!o)return u.error(`No ICE servers available for peer ${e}`),this.sdk.gameEventManager.notifyGame(v.P2P_CONNECTION_FAILED,{userId:e,username:r.peers[e]?.username||"",error:"No ICE servers available"}),!1;let i=new RTCPeerConnection({iceServers:o,iceCandidatePoolSize:0,bundlePolicy:"max-bundle",rtcpMuxPolicy:"require"});if(s){if(u.debug(`Creating data channels for peer ${e}`),this.config.enableReliableChannel){let a=i.createDataChannel("reliable",{ordered:!0,maxRetransmits:void 0});this.reliableChannels.set(e,a),this.setupDataChannelHandlers(a,e,"reliable")}if(this.config.enableUnreliableChannel){let a=i.createDataChannel("unreliable",{ordered:!1,maxRetransmits:0});this.unreliableChannels.set(e,a),this.setupDataChannelHandlers(a,e,"unreliable")}}else u.debug(`Will receive data channels from peer ${e} via ondatachannel`);return i.onicecandidate=a=>{if(a.candidate){let c=a.candidate.candidate.includes("typ host")?"host":a.candidate.candidate.includes("typ srflx")?"srflx (STUN)":a.candidate.candidate.includes("typ relay")?"relay (TURN)":"unknown";u.debug(`Peer ${e} gathered ICE candidate: ${c}`),u.debug(` Candidate: ${a.candidate.candidate}`);let l={candidate:a.candidate.candidate,sdpMid:a.candidate.sdpMid,sdpMLineIndex:a.candidate.sdpMLineIndex,usernameFragment:a.candidate.usernameFragment};this.sendSignalingMessage(e,{type:J.ICE_CANDIDATE,data:l})}},i.ondatachannel=a=>{let c=a.channel;u.debug(`Received ${c.label} data channel from peer ${e}`),c.label==="reliable"?this.reliableChannels.set(e,c):c.label==="unreliable"&&this.unreliableChannels.set(e,c),this.setupDataChannelHandlers(c,e,c.label)},i.onconnectionstatechange=()=>{u.debug(`Peer ${e} connection state: ${i.connectionState}`),i.connectionState==="connected"&&u.debug(` Peer ${e} fully connected, expecting ondatachannel events now...`)},i.oniceconnectionstatechange=()=>{if(u.debug(`Peer ${e} ICE connection state: ${i.iceConnectionState}`),i.iceConnectionState==="connected"){if(u.debug(` ICE connected to peer ${e}, data channels should be available...`),this.iceRestartAttempts.delete(e),this.iceRestartInProgress.delete(e),this.reconnectingPeers.delete(e)){let a=this.currentConnection?.peers[e];a&&this.sdk.gameEventManager.notifyGame(v.P2P_PEER_RECONNECTED,{userId:a.userId,username:a.username})}}else if(i.iceConnectionState==="failed"){if(u.debug(`ICE connection to peer ${e} failed, will retry in 500ms...`),!this.reconnectingPeers.has(e)){this.reconnectingPeers.add(e);let a=this.currentConnection?.peers[e];a&&this.sdk.gameEventManager.notifyGame(v.P2P_PEER_RECONNECTING,{userId:a.userId,username:a.username})}setTimeout(()=>{i.iceConnectionState==="failed"&&(u.warn(`ICE connection to peer ${e} still failed after delay, attempting ICE restart...`),this.attemptIceRestart(e,i))},500)}else i.iceConnectionState==="disconnected"&&u.debug(`ICE connection to peer ${e} disconnected, may recover...`)},i.onicegatheringstatechange=()=>{u.debug(`Peer ${e} ICE gathering state: ${i.iceGatheringState}`)},this.peerConnections.set(e,i),!0}async attemptIceRestart(e,r){if(this.sdk.getUserId()>e){u.debug(`Waiting for peer ${e} to initiate ICE restart (they have lower userId)`);return}if(this.iceRestartInProgress.has(e)){u.debug(`ICE restart already in progress for peer ${e}, skipping`);return}let o=this.iceRestartAttempts.get(e)||0;if(o>=this.MAX_ICE_RESTART_ATTEMPTS){u.error(`Max ICE restart attempts (${this.MAX_ICE_RESTART_ATTEMPTS}) reached for peer ${e}, giving up`),this.reconnectingPeers.delete(e),this.establishedPeers.delete(e);let i=this.currentConnection?.peers[e];i&&this.sdk.gameEventManager.notifyGame(v.P2P_CONNECTION_FAILED,{userId:i.userId,username:i.username,error:"ICE restart failed after maximum attempts"}),r.close();return}this.iceRestartAttempts.set(e,o+1),this.iceRestartInProgress.add(e),u.debug(`ICE restart attempt ${o+1}/${this.MAX_ICE_RESTART_ATTEMPTS} for peer ${e}`);try{r.restartIce();let i=await r.createOffer({iceRestart:!0});await r.setLocalDescription(i);let a={type:i.type,sdp:i.sdp};await this.sendSignalingMessage(e,{type:J.OFFER,data:a}),u.debug(`ICE restart offer sent to peer ${e}`)}catch(i){u.error(`Failed to initiate ICE restart for peer ${e}:`,i)}}setupDataChannelHandlers(e,r,s){e.onopen=()=>{if(u.debug(`${s} data channel opened with peer ${r}`),this.isPeerReady(r)&&!this.establishedPeers.has(r)){this.establishedPeers.add(r);let o=this.currentConnection?.peers[r];o&&this.sdk.gameEventManager.notifyGame(v.P2P_CONNECTION_ESTABLISHED,{userId:o.userId,username:o.username})}},e.onmessage=o=>{this.enqueueMessage(o.data,r)},e.onerror=o=>{u.error(`Data channel error with peer ${r}:`,o);let i=this.currentConnection?.peers[r];i&&this.sdk.gameEventManager.notifyGame(v.P2P_CONNECTION_FAILED,{userId:i.userId,username:i.username,error:o.toString()})},e.onclose=()=>{u.debug(`${s} data channel closed with peer ${r}`),this.establishedPeers.delete(r),this.reconnectingPeers.delete(r);let o=this.currentConnection?.peers[r];o&&this.sdk.gameEventManager.notifyGame(v.P2P_PEER_DISCONNECTED,{userId:o.userId,username:o.username})}}sendP2PMessage(e,r=0,s=!0,o,i=o.length){this.ensureInitialized();try{if(!this.currentConnection)return u.error("P2P send called before P2P is initialized, dropping message."),this.reportPacketDrop(r,"SEND","PEER_NOT_READY"),!1;if(!o)return u.error("P2P send called with missing payload, dropping message."),this.reportPacketDrop(r,"SEND","INVALID_PAYLOAD_SIZE"),!1;if(!Number.isInteger(r)||r<0||r>=this.MAX_CHANNELS)return u.error(`P2P appChannel must be an integer in [0, ${this.MAX_CHANNELS}), received ${r}, dropping message.`),this.reportPacketDrop(-1,"SEND","INVALID_CHANNEL"),!1;if(i<=0)return u.error(`P2P payloadSize must be greater than 0, received ${i}, dropping message.`),this.reportPacketDrop(r,"SEND","INVALID_PAYLOAD_SIZE"),!1;if(i>this.MAX_PAYLOAD_SIZE)return u.error(`P2P payload too large: ${i} bytes exceeds max ${this.MAX_PAYLOAD_SIZE} bytes, dropping message.`),this.reportPacketDrop(r,"SEND","PAYLOAD_TOO_LARGE"),!1;if(i>o.length)return u.error(`payloadSize is greater than payload buffer length: ${i} > ${o.length}, dropping message.`),this.reportPacketDrop(r,"SEND","INVALID_PAYLOAD_SIZE"),!1;let a=i<o.length?o.subarray(0,i):o,c=this.encodeWireMessage(r,a),l=s?this.reliableChannels:this.unreliableChannels;if(e===void 0)l.forEach((d,p)=>{if(d.readyState==="open")try{d.send(c)}catch(y){u.error(`P2P broadcast to peer ${p} failed:`,y)}});else{let d=l.get(e);if(!d||d.readyState!=="open")return u.error(`P2P no open channel to peer ${e}, dropping message.`),this.reportPacketDrop(r,"SEND","PEER_NOT_READY"),!1;try{d.send(c)}catch(p){return u.error(`P2P send to peer ${e} failed, dropping message:`,p),this.reportPacketDrop(r,"SEND","PEER_NOT_READY"),!1}}return!0}catch(a){return u.error("Error sending P2P message:",a),!1}}async sendSignalingMessage(e,r){if(!this.currentConnection)throw new Error("No active P2P connection for signaling");try{await this.sdk.convexClient.mutation(f.sdk.p2pSignaling.sendSignalingMessage,{lobbyId:this.currentConnection.lobbyId,toUserId:e,messageType:r.type,data:r.data}),u.debug("Sent signaling message:",r.type)}catch(s){throw u.error("Failed to send signaling message:",s),s}}disconnectP2P(){this.currentConnection&&(this.stopSignalingMessageSubscription(),Object.entries(this.currentConnection.peers).forEach(([e,r])=>{let s=this.peerConnections.get(e);s&&(s.close(),this.peerConnections.delete(e)),this.reliableChannels.delete(e),this.unreliableChannels.delete(e)}),this.currentConnection=null,this.processedSignalingMessages.clear(),this.pendingProcessedMessageIds.clear(),this.pendingIceCandidates.clear(),this.iceRestartAttempts.clear(),this.iceRestartInProgress.clear(),this.reconnectingPeers.clear(),this.establishedPeers.clear(),this.clearPacketDropTrackers(),this.initializationInProgress=null,this.initializationLobbyId=null,this.signalingSubscriptionReady=null,this.signalingSubscriptionReadyResolver=null)}isPeerReady(e){if(!this.currentConnection)return!1;let r=this.reliableChannels.get(e),s=this.unreliableChannels.get(e),o=!this.config.enableReliableChannel||r?.readyState==="open",i=!this.config.enableUnreliableChannel||s?.readyState==="open";return o&&i}isBroadcastReady(){return this.currentConnection?this.reliableChannels.size>0&&this.unreliableChannels.size>0:!1}getPeerStatuses(){if(!this.currentConnection)return{};let e={};for(let r of Object.keys(this.currentConnection.peers)){let s=this.reliableChannels.get(r),o=this.unreliableChannels.get(r);e[r]={reliable:s?.readyState,unreliable:o?.readyState,ready:this.isPeerReady(r)}}return e}createChannelQueue(e){let r=this.MESSAGE_SIZE*this.QUEUE_SIZE,s=new ArrayBuffer(r),o=new Uint8Array(s);this.channelQueues.set(e,{buffer:s,writeIndex:0,readIndex:0,messageCount:0,incomingDataView:o}),u.debug(`Allocated P2P ring buffer for channel ${e} (${(r/1024/1024).toFixed(1)}MB)`)}reportPacketDrop(e,r,s){let o=`${r}:${e}:${s}`,i=this.packetDropTrackers.get(o);if(i||(i={channel:e,direction:r,reason:s,pendingCount:0,windowTimer:null,droppedTotal:0},this.packetDropTrackers.set(o,i)),i.droppedTotal+=1,i.windowTimer===null){this.emitPacketDropped(i,1),i.windowTimer=setTimeout(()=>this.flushPacketDropWindow(o),this.PACKET_DROP_WINDOW_MS);return}i.pendingCount+=1}flushPacketDropWindow(e){let r=this.packetDropTrackers.get(e);if(r)if(r.pendingCount>0){let s=r.pendingCount;r.pendingCount=0,this.emitPacketDropped(r,s),r.windowTimer=setTimeout(()=>this.flushPacketDropWindow(e),this.PACKET_DROP_WINDOW_MS)}else r.windowTimer=null}emitPacketDropped(e,r){this.sdk.gameEventManager.notifyGame(v.P2P_PACKET_DROPPED,{channel:e.channel,direction:e.direction,reason:e.reason,droppedCount:r,droppedTotal:e.droppedTotal})}clearPacketDropTrackers(){for(let e of this.packetDropTrackers.values())e.windowTimer!==null&&clearTimeout(e.windowTimer);this.packetDropTrackers.clear()}enqueueMessage(e,r){try{if(e.byteLength<this.WIRE_PAYLOAD_OFFSET){u.warn("Binary message too short to extract channel"),this.reportPacketDrop(-1,"RECEIVE","MALFORMED");return}let s=new Uint8Array(e),o=s[this.WIRE_CHANNEL_OFFSET];if(!this.channelQueues.has(o)){if(o>=this.MAX_CHANNELS){u.warn(`Channel ${o} exceeds max channels (${this.MAX_CHANNELS}), dropping message`),this.reportPacketDrop(o,"RECEIVE","INVALID_CHANNEL");return}this.createChannelQueue(o)}let i=this.channelQueues.get(o);if(i.messageCount>=this.QUEUE_SIZE){u.warn(`P2P message queue full for channel ${o}, dropping message`),this.reportPacketDrop(o,"RECEIVE","QUEUE_FULL");return}let a=e.byteLength-this.WIRE_PAYLOAD_OFFSET,c=this.PAYLOAD_OFFSET+a,l=this.MESSAGE_SIZE-this.MESSAGE_SLOT_HEADER_SIZE;if(c>l){u.warn(`Message too large for queue: ${c} > ${l}, dropping message.`),this.reportPacketDrop(o,"RECEIVE","PAYLOAD_TOO_LARGE");return}let d=i.writeIndex*this.MESSAGE_SIZE,p=d+this.MESSAGE_SLOT_HEADER_SIZE,y=new DataView(i.buffer,d,this.MESSAGE_SIZE);y.setUint32(0,c,!0);let h=this.textEncoder.encode(r).slice(0,this.USERID_SIZE);i.incomingDataView.fill(0,p,p+this.USERID_SIZE),i.incomingDataView.set(h,p),y.setUint32(this.MESSAGE_SLOT_HEADER_SIZE+this.CHANNEL_OFFSET,o,!0),y.setUint32(this.MESSAGE_SLOT_HEADER_SIZE+this.DATALENGTH_OFFSET,a,!0),a>0&&i.incomingDataView.set(s.subarray(this.WIRE_PAYLOAD_OFFSET),p+this.PAYLOAD_OFFSET),i.writeIndex=(i.writeIndex+1)%this.QUEUE_SIZE,i.messageCount++}catch(s){u.error("Error enqueuing binary P2P message:",s)}}getMaxPayloadSize(){return this.ensureInitialized(),this.MAX_PAYLOAD_SIZE}getMaxIncomingMessages(){return this.ensureInitialized(),this.QUEUE_SIZE}getOutgoingMessageBuffer(){return this.ensureInitialized(),this.outgoingMessageBuffer}readMessageFromChannel(e){this.ensureInitialized();let r=this.channelQueues.get(e);if(!r)return null;let s=this.readRawMessage(r);return s?this.decodeBinaryMessage(s):null}readRawMessage(e){if(e.messageCount===0)return null;let r=e.readIndex*this.MESSAGE_SIZE,o=new DataView(e.buffer,r,this.MESSAGE_SIZE).getUint32(0,!0),i=this.MESSAGE_SIZE-this.MESSAGE_SLOT_HEADER_SIZE;if(o===0||o>i)return e.readIndex=(e.readIndex+1)%this.QUEUE_SIZE,e.messageCount--,null;let a=new Uint8Array(e.buffer,r+this.MESSAGE_SLOT_HEADER_SIZE,o);return e.readIndex=(e.readIndex+1)%this.QUEUE_SIZE,e.messageCount--,a}drainChannelToBuffer(e,r){this.ensureInitialized();let s=this.channelQueues.get(e);if(!s||s.messageCount===0)return new Uint8Array(0);if(!r||r.byteLength===0){let l=[],d=0;for(;s.messageCount>0;){let m=this.readRawMessage(s);m&&(l.push(m),d+=this.MESSAGE_SLOT_HEADER_SIZE+m.length)}if(l.length===0)return new Uint8Array(0);let p=new Uint8Array(d),y=new DataView(p.buffer),h=0;for(let m of l)y.setUint32(h,m.length,!0),h+=this.MESSAGE_SLOT_HEADER_SIZE,p.set(m,h),h+=m.length;return p}let o=new DataView(r.buffer,r.byteOffset,r.byteLength),i=new DataView(s.buffer),a=this.MESSAGE_SIZE-this.MESSAGE_SLOT_HEADER_SIZE,c=0;for(;s.messageCount>0;){let l=s.readIndex*this.MESSAGE_SIZE,d=i.getUint32(l,!0);if(d===0||d>a){s.readIndex=(s.readIndex+1)%this.QUEUE_SIZE,s.messageCount--;continue}let p=this.MESSAGE_SLOT_HEADER_SIZE+d;if(c+p>r.byteLength)break;o.setUint32(c,d,!0),c+=this.MESSAGE_SLOT_HEADER_SIZE,r.set(new Uint8Array(s.buffer,l+this.MESSAGE_SLOT_HEADER_SIZE,d),c),c+=d,s.readIndex=(s.readIndex+1)%this.QUEUE_SIZE,s.messageCount--}return r.subarray(0,c)}encodeWireMessage(e,r){if(e<0||e>=this.MAX_CHANNELS)throw new Error(`P2P channel ${e} must be between 0 and ${this.MAX_CHANNELS-1}`);let s=this.WIRE_PAYLOAD_OFFSET+r.length,o=new Uint8Array(s);return o[this.WIRE_CHANNEL_OFFSET]=e,r.length>0&&o.set(r,this.WIRE_PAYLOAD_OFFSET),o}decodeBinaryMessage(e){if(e.byteLength<this.PAYLOAD_OFFSET)throw new Error("Invalid binary message: too short");let r=new DataView(e.buffer,e.byteOffset,e.byteLength),s=e,o=0,i=s.slice(o,o+this.USERID_SIZE),a=this.textDecoder.decode(i).replace(/\0+$/,"");o+=this.USERID_SIZE;let c=r.getUint32(o,!0);o+=this.CHANNEL_SIZE;let l=r.getUint32(o,!0);o+=this.DATALENGTH_SIZE;let d=e.slice(o,o+l);return{fromUserId:a,channel:c,payload:d}}};K.MAX_MESSAGE_SIZE=64*1024,K.MEMORY_WARNING_THRESHOLD_BYTES=128*1024*1024;var Rt=K;function cn(n){return typeof document>"u"?Promise.resolve(!1):new Promise(t=>{let e=document.createElement("div");e.style.cssText="position:fixed;inset:0;z-index:2147483647;display:flex;align-items:center;justify-content:center;background:rgba(8,10,18,0.72);font:14px ui-sans-serif,system-ui,sans-serif;color:#e2e8f0";let r=document.createElement("div");r.style.cssText="max-width:420px;width:calc(100% - 48px);background:#11151f;border:1px solid #2a3344;border-radius:12px;padding:24px;box-shadow:0 20px 60px rgba(0,0,0,0.5);box-sizing:border-box";let s=document.createElement("p");s.textContent="wavedash dev \u2014 simulated purchase",s.style.cssText="margin:0 0 12px;font-size:11px;letter-spacing:0.08em;text-transform:uppercase;color:#7c8aa5";let o=document.createElement("p");o.textContent="Unlock paid content?",o.style.cssText="margin:0 0 8px;font-size:18px;font-weight:600;color:#f1f5f9";let i=document.createElement("p");i.style.cssText="margin:0 0 20px;line-height:1.5;color:#cbd5e1",i.append(document.createTextNode("This game is requesting purchase of \u201C"));let a=document.createElement("code");a.textContent=n,a.style.cssText="background:#1c2433;border-radius:4px;padding:1px 6px;color:#93c5fd",i.append(a,document.createTextNode("\u201D. No real payment happens in dev \u2014 simulate the outcome to test your flow."));let c=document.createElement("div");c.style.cssText="display:flex;gap:12px;justify-content:flex-end";let l="border-radius:8px;padding:9px 18px;font-size:14px;font-weight:600;cursor:pointer;border:1px solid transparent",d=document.createElement("button");d.type="button",d.textContent="Cancel",d.style.cssText=l+";background:transparent;border-color:#374151;color:#cbd5e1";let p=document.createElement("button");p.type="button",p.textContent="Simulate purchase",p.style.cssText=l+";background:#2563eb;color:#fff",c.append(d,p),r.append(s,o,i,c),e.append(r);let y=!1,h=M=>{y||(y=!0,document.removeEventListener("keydown",m,!0),e.remove(),t(M))},m=M=>{M.key==="Escape"&&(M.preventDefault(),h(!1))};d.addEventListener("click",()=>h(!1)),p.addEventListener("click",()=>h(!0)),e.addEventListener("click",M=>{M.target===e&&h(!1)}),document.addEventListener("keydown",m,!0),document.body.append(e)})}var ai=600*1e3;function ci(n){try{let[,t]=n.split(".");if(!t)return null;let e=t.replace(/-/g,"+").replace(/_/g,"/"),r=e+"===".slice((e.length+3)%4),s=Uint8Array.from(atob(r),i=>i.charCodeAt(0)),o=new TextDecoder().decode(s);return JSON.parse(o)}catch(t){return u.warn("Failed to decode JWT payload",t),null}}function un(n){let e=ci(n)?.ents;return Array.isArray(e)?e.filter(r=>typeof r=="string"):[]}var _t=class extends w{constructor(){super(...arguments);this.paywallOpen=!1}async isEntitled(e){let r=await this.sdk.ensureGameplayJwt();return un(r).includes(e)}async getEntitlements(){let e=await this.sdk.ensureGameplayJwt();return un(e)}async triggerPaywall(e){if(await this.isEntitled(e))return!0;if(this.paywallOpen)throw new Error("Paywall already in progress");if(this.paywallOpen=!0,this.restorePointerLock=xt(),!k()){let s;try{s=await cn(e)}finally{this.restorePointerLock?.(),this.restorePointerLock=void 0,this.paywallOpen=!1}return s?(await this.sdk.convexClient.mutation(f.sdk.paidContent.mockPurchase,{contentIdentifier:e}),await this.sdk.ensureGameplayJwt(!0),!0):!1}let r;try{r=await this.sdk.iframeMessenger.requestFromParent(E.TRIGGER_PAYWALL,{contentIdentifier:e},ai)}finally{this.restorePointerLock?.(),this.restorePointerLock=void 0,this.paywallOpen=!1}return r.purchased?(await this.sdk.ensureGameplayJwt(!0),!0):!1}isPaywallOpen(){return this.paywallOpen}destroy(){this.restorePointerLock?.(),this.restorePointerLock=void 0}};var ln=hr(cr(),1),ui=1e3,Lt=class extends w{constructor(e){super(e);this.stats=new Map;this.unlockedAchievements=new Set;this.dirtyStats=new Set;this.dirtyAchievements=new Set;this.knownStatIds=new Set;this.knownAchievementIds=new Set;this.loaded={stats:!1,achievements:!1};this.subscriptions=[];this.inFlightPersist=null;this.flushRequested=!1;this.throttledPersist=(0,ln.default)(()=>this.persist(),ui,{leading:!1,trailing:!0});this.subscribe(),this.requestStats().catch(r=>{u.error("Initial stats fetch failed:",r)})}destroy(){this.throttledPersist.cancel();for(let e of this.subscriptions)e();this.subscriptions=[]}isReady(){return this.loaded.stats&&this.loaded.achievements}subscribe(){this.subscriptions.push(this.sdk.convexClient.onUpdate(f.sdk.gameAchievements.listStatIdentifiers,{},e=>{this.knownStatIds=new Set(e)},e=>{u.error("Stat identifiers subscription error:",e)}),this.sdk.convexClient.onUpdate(f.sdk.gameAchievements.listAchievementIdentifiers,{},e=>{this.knownAchievementIds=new Set(e)},e=>{u.error("Achievement identifiers subscription error:",e)}),this.sdk.convexClient.onUpdate(f.sdk.gameAchievements.getMyAchievementsForGame,{},e=>{this.loaded.achievements=!0;for(let{achievement:r}of e)this.unlockedAchievements.add(r.identifier)},e=>{u.error("Achievement subscription error:",e)}))}async requestStats(){let e=await this.sdk.convexClient.query(f.sdk.gameAchievements.getMyStatsForGame,{});this.loaded.stats=!0;for(let r of e)this.stats.has(r.identifier)||this.stats.set(r.identifier,r.value);return!0}storeStats(){return this.isReady()?(this.throttledPersist(),this.requestPersistFlush(),!0):!1}requestPersistFlush(){this.inFlightPersist!==null&&(this.flushRequested=!0),this.throttledPersist.flush()}persist(){if(this.inFlightPersist!==null||this.dirtyStats.size===0&&this.dirtyAchievements.size===0)return;let e=this.getPendingData();e&&(this.inFlightPersist=Promise.all([e.stats.length>0?this.sdk.convexClient.mutation(f.sdk.gameAchievements.setUserGameStats,{stats:e.stats}):Promise.resolve(),e.achievements.length>0?this.sdk.convexClient.mutation(f.sdk.gameAchievements.setUserGameAchievements,{achievements:e.achievements}):Promise.resolve()]).then(()=>{this.sdk.gameEventManager.notifyGame(v.STATS_STORED,{success:!0})}).catch(r=>{let s=r instanceof Error?r.message:`Error storing stats: ${r}`;u.error(s),this.sdk.gameEventManager.notifyGame(v.STATS_STORED,{success:!1,message:s})}).finally(()=>{this.inFlightPersist=null;let r=this.flushRequested;this.flushRequested=!1,(this.dirtyStats.size>0||this.dirtyAchievements.size>0)&&(this.throttledPersist(),r&&this.throttledPersist.flush())}))}getStat(e){return!this.isReady()||!this.knownStatIds.has(e)?0:this.stats.get(e)??0}setStat(e,r,s=!1){return!this.isReady()||!this.knownStatIds.has(e)?!1:(this.stats.get(e)!==r&&(this.stats.set(e,r),this.dirtyStats.add(e),this.throttledPersist()),s&&this.requestPersistFlush(),!0)}getAchievement(e){return!this.isReady()||!this.knownAchievementIds.has(e)?!1:this.unlockedAchievements.has(e)}setAchievement(e,r=!1){return!this.isReady()||!this.knownAchievementIds.has(e)?!1:(this.unlockedAchievements.has(e)||(this.unlockedAchievements.add(e),this.dirtyAchievements.add(e),this.throttledPersist()),r&&this.requestPersistFlush(),!0)}getPendingData(){if(this.dirtyStats.size===0&&this.dirtyAchievements.size===0)return null;let e=[...this.dirtyStats].map(s=>({identifier:s,value:this.stats.get(s)})),r=[...this.dirtyAchievements];return this.dirtyStats.clear(),this.dirtyAchievements.clear(),{stats:e,achievements:r}}};var kt=class extends w{constructor(t){super(t)}async createUGCItem(t,e,r,s,o){let{ugcId:i,uploadUrl:a}=await this.sdk.convexClient.mutation(f.sdk.userGeneratedContent.createUGCItem,{ugcType:t,title:e,description:r,visibility:s,createPresignedUploadUrl:!!o});if(o&&!a)throw new Error(`Failed to create a presigned upload URL for UGC item: ${o}`);if(o&&a&&!await this.sdk.fileSystemManager.upload(a,o))throw new Error(`Failed to upload UGC item: ${o}`);return i}async updateUGCItem(t,e={}){let{title:r,description:s,visibility:o,filePath:i}=e,{uploadUrl:a}=await this.sdk.convexClient.mutation(f.sdk.userGeneratedContent.updateUGCItem,{ugcId:t,title:r,description:s,visibility:o,createPresignedUploadUrl:!!i});if(i&&!a)throw new Error(`Failed to create a presigned upload URL for UGC item: ${i}`);if(i&&a&&!await this.sdk.fileSystemManager.upload(a,i))throw new Error(`Failed to upload UGC item: ${i}`);return t}async deleteUGCItem(t){return await this.sdk.convexClient.mutation(f.sdk.userGeneratedContent.deleteUGCItem,{ugcId:t}),t}async downloadUGCItem(t,e){let r=await this.sdk.convexClient.query(f.sdk.userGeneratedContent.getUGCItemDownloadUrl,{ugcId:t});try{await this.sdk.fileSystemManager.download(r,e)}catch(s){let o=s instanceof Error?s.message:String(s);throw new Error(`Failed to download UGC item ${t}: ${o}`)}return t}async listUGCItems(t={}){let{createdBy:e,ugcType:r,titleSearch:s,numItems:o,continueCursor:i}=t,a=e!==void 0||r!==void 0||s!==void 0?{createdBy:e,ugcType:r,titleSearch:s}:void 0;return await this.sdk.convexClient.query(f.sdk.userGeneratedContent.listUGCItems,{filters:a,numItems:o,continueCursor:i})}};var li=15e3,Ot=class{constructor(){this.handleMessage=t=>{if(t.origin!==gt()){t.source!==window&&console.warn(`Ignored message from untrusted origin: ${t.origin}`);return}if(t.data?.requestId){let s=this.pendingRequests.get(t.data.requestId);s&&(clearTimeout(s.timeout),this.pendingRequests.delete(t.data.requestId),s.resolve(t.data.data));return}let e=t.data?.type;if(!e)return;let r=this.listeners.get(e);if(r)for(let s of r)s(t.data)};this.pendingRequests=new Map,this.requestIdCounter=0,this.listeners=new Map,typeof window<"u"&&window.addEventListener("message",this.handleMessage)}addEventListener(t,e){let r=this.listeners.get(t);r||(r=new Set,this.listeners.set(t,r)),r.add(e)}removeEventListener(t,e){this.listeners.get(t)?.delete(e)}postToParent(t,e){let r=gt();return typeof window>"u"||!r?!1:(window.parent.postMessage({type:t,...e},r),!0)}async requestFromParent(t,e,r=li){return new Promise((s,o)=>{let i=gt();if(typeof window>"u"||!i){o(new Error("Parent origin not found"));return}let a=`${t}_${++this.requestIdCounter}_${Date.now()}`,c=setTimeout(()=>{this.pendingRequests.delete(a),o(new Error(`${t} request timed out after ${r}ms`))},r);this.pendingRequests.set(a,{resolve:s,reject:o,timeout:c}),window.parent.postMessage({type:t,requestId:a,...e},i)})}};var Dt=class{constructor(){this.handleMessage=t=>{let e=t.data,r=e?.type;if(!r)return;let s=this.listeners.get(r);if(!s||s.size===0)return;let o=t.ports?.[0],i=a=>{if(o)try{o.postMessage(a)}catch(c){u.warn("Failed to reply to SW via port",c)}this.postToServiceWorker(a)};for(let a of s)a(e?.payload,i)};this.listeners=new Map,typeof navigator<"u"&&navigator.serviceWorker&&navigator.serviceWorker.addEventListener("message",this.handleMessage)}addEventListener(t,e){let r=this.listeners.get(t);r||(r=new Set,this.listeners.set(t,r)),r.add(e)}removeEventListener(t,e){this.listeners.get(t)?.delete(e)}postToServiceWorker(t){if(typeof navigator>"u"||!navigator.serviceWorker)return!1;try{return navigator.serviceWorker.controller?.postMessage(t),!0}catch(e){return u.warn("Failed to post message to service worker",e),!1}}};var di=/^[0-9a-z]{31,37}$/,b=(n,t)=>{if(typeof n!="string")throw new Error(`${t}: expected string, got ${$(n)}`);return n},U=(n,t)=>{if(typeof n!="number"||!Number.isFinite(n))throw new Error(`${t}: expected finite number, got ${$(n)}`);return n},re=(n,t)=>{if(typeof n!="boolean")throw new Error(`${t}: expected boolean, got ${$(n)}`);return n},dn=(n,t)=>{if(n!==null)throw new Error(`${t}: expected null, got ${$(n)}`);return null},hn=(n,t)=>{if(!(n instanceof Uint8Array))throw new Error(`${t}: expected Uint8Array, got ${$(n)}`);return n},pn=(n,t)=>{if(typeof n!="object"||n===null||Array.isArray(n))throw new Error(`${t}: expected plain object, got ${$(n)}`);for(let[e,r]of Object.entries(n))if(typeof r=="object"&&r!==null)throw new Error(`${t}: expected flat record with no nested objects, but key "${e}" contains ${$(r)}`);return n};function C(n){return(t,e)=>{if(typeof t!="string"||!di.test(t))throw new Error(`${e}: expected Id<"${n}"> (base32 string, 31-37 chars), got ${$(t)}`);return t}}function ne(n,t){let e=Object.values(n);return(r,s)=>{if(!e.includes(r)){let o=Object.entries(n).map(([a,c])=>`${JSON.stringify(c)} (${a})`).join(", "),i=t?`${t} `:"";throw new Error(`${s}: invalid ${i}value ${$(r)}. Expected one of: ${o}`)}return r}}function x(n){return(t,e)=>{if(t!==void 0)return n(t,e)}}function fn(...n){return(t,e)=>{for(let r of n)try{return r(t,e)}catch{}throw new Error(`${e}: no variant matched, got ${$(t)}`)}}function Nt(n){return(t,e)=>{if(typeof t!="object"||t===null||Array.isArray(t))throw new Error(`${e}: expected plain object, got ${$(t)}`);let r=t;for(let s of Object.keys(r))if(!(s in n))throw new Error(`${e}: unrecognized property "${s}"`);for(let s of Object.keys(n))n[s](r[s],`${e}.${s}`);return r}}function se(n,t,e){let r={},s={};for(let o=0;o<t.length;o++){let[i,a]=t[o];r[i]=a,s[i]=e[o]}Nt(r)(s,n)}function $(n){if(n===void 0)return"undefined";if(n===null)return"null";if(n instanceof Uint8Array)return`Uint8Array(byteLength=${n.byteLength})`;if(Array.isArray(n))return`array(length=${n.length})`;let t=typeof n;return t==="string"||t==="number"||t==="boolean"?`${t} ${JSON.stringify(n)}`:t}var Oe=new Ot,ur=class extends EventTarget{constructor(e){super();this._initialized=!1;this._eventsReady=!1;this.destroyed=!1;this.gameFinishedLoading=!1;this.Events=v;this.LobbyVisibility=ut;this.LeaderboardSortOrder=dt;this.LeaderboardDisplayType=ht;this.UGCType=xe;this.UGCVisibility=Me;this.AvatarSize=ft;this.LobbyKickedReason=ye;this.LobbyUserChangeType=ke;this.P2PPacketDropReason=Gr;this.config=null;this.engineCallbackReceiver="WavedashCallbackReceiver";this.engineInstance=null;this.gameplayJwt=null;this.gameplayJwtPromise=null;this.setupWarningTimeout=null;this.listenerWrappers=new Map;this.convexClient=new Ae(e.convexCloudUrl,{expectAuth:!0}),this.gameCloudId=e.gameCloudId,this.iframeMessenger=Oe,this.convexClient.setAuth(({forceRefreshToken:r})=>this.getAuthToken(r)),this.wavedashUser=e.wavedashUser,this.ugcHost=e.ugcHost,this.uploadsHost=e.uploadsHost,this.swMessenger=new Dt,this.p2pManager=new Rt(this),this.lobbyManager=new Tt(this),this.statsManager=new Lt(this),this.heartbeatManager=new Ct(this),this.fileSystemManager=new vt(this),this.ugcManager=new kt(this),this.leaderboardManager=new It(this),this.friendsManager=new wt(this),this.gameEventManager=new St(this),this.fullscreenManager=new Et(this),this.overlayManager=new Mt(this),this.audioManager=new mt(this),this.paidContentManager=new _t(this),this.managers=[this.p2pManager,this.lobbyManager,this.statsManager,this.heartbeatManager,this.fileSystemManager,this.ugcManager,this.leaderboardManager,this.friendsManager,this.gameEventManager,this.fullscreenManager,this.overlayManager,this.audioManager,this.paidContentManager],this.friendsManager.cacheUsers([{userId:this.wavedashUser.id,username:this.wavedashUser.username,avatarUrl:this.wavedashUser.avatarUrl}]),this.setupSessionEndListeners(),this.setupSwCredsListener(),this.launchParams=e.launchParams??{},this.setupWarningTimeout=setTimeout(()=>{this.setupWarningTimeout=null,u.warn("Wavedash.init(), Wavedash.loadComplete(), or Wavedash.updateLoadProgressZeroToOne() not called yet")},1e4)}get initialized(){return this._initialized}get eventsReady(){return this._eventsReady}clearSetupWarning(){this.setupWarningTimeout!==null&&(clearTimeout(this.setupWarningTimeout),this.setupWarningTimeout=null)}init(e){if(this.loadComplete(),this._initialized)return u.warn("init called twice! Already initialized, skipping init"),!1;if(typeof e=="string")try{e=JSON.parse(e)}catch(r){return u.error("Initialized with invalid config:",r),!1}return this.config=e??{},this._initialized=!0,u.setLogLevel(this.config.debug?X.DEBUG:X.WARN),this.p2pManager.init(this.config.p2p),u.debug("Initialized with config:",this.config),this.config.deferEvents||this.readyForEvents(),!0}readyForEvents(){this._eventsReady||(this.ensureInit(),this._eventsReady=!0,this.gameEventManager.flushEventQueue())}on(e,r){let s=a=>{r(a.detail)},o=this.listenerWrappers.get(e);o||(o=new Map,this.listenerWrappers.set(e,o));let i=o.get(r);return i&&this.removeEventListener(e,i),o.set(r,s),this.addEventListener(e,s),()=>this.off(e,r)}off(e,r){let s=this.listenerWrappers.get(e),o=s?.get(r);!s||!o||(this.removeEventListener(e,o),s.delete(r),s.size===0&&this.listenerWrappers.delete(e))}addEventListener(e,r,s){super.addEventListener(e,r,s)}removeEventListener(e,r,s){super.removeEventListener(e,r,s)}loadScript(e){return se("loadScript",[["src",b]],[e]),new Promise((r,s)=>{let o=document.createElement("script");o.type="text/javascript",o.crossOrigin="anonymous",o.src=e,o.onload=r,o.onerror=s,document.head.appendChild(o)})}updateLoadProgressZeroToOne(e){se("updateLoadProgressZeroToOne",[["progress",U]],[e]),this.clearSetupWarning(),Oe.postToParent(E.PROGRESS_UPDATE,{progress:e})}loadComplete(){this.clearSetupWarning(),!this.gameFinishedLoading&&(this.gameFinishedLoading=!0,this.heartbeatManager.start(),Oe.postToParent(E.LOADING_COMPLETE,{}))}get gameLoaded(){return this.gameFinishedLoading}toggleOverlay(){this.overlayManager.toggleOverlay()}isFullscreen(){return this.fullscreenManager.isFullscreen()}async requestFullscreen(e){return this.fullscreenManager.requestFullscreen(e)}async toggleFullscreen(){return this.fullscreenManager.toggleFullscreen()}isMuted(){return this.audioManager.isMuted()}async requestMute(e){return this.audioManager.requestMute(e)}async toggleMute(){return this.audioManager.toggleMute()}getUser(){return this.formatResponse(this.wavedashUser)}getUsername(e){return e===void 0?this.wavedashUser.username:(se("getUsername",[["userId",C("users")]],[e]),this.friendsManager.getUsername(e))}getUserId(){return this.wavedashUser.id}async getUserJwt(){u.debug("getUserJwt");try{let e=await this.ensureGameplayJwt();return this.formatResponse({success:!0,data:e})}catch(e){let r=e instanceof Error?e.message:String(e);return u.error("getUserJwt",r),this.formatResponse({success:!1,data:null,message:r})}}getLaunchParams(){return this.formatResponse(this.launchParams)}async listFriends(){return this.apiCall(this.friendsManager,"listFriends",[])}getUserAvatarUrl(e,r=this.AvatarSize.MEDIUM){return this.apiCallSync(this.friendsManager,"getUserAvatarUrl",[["userId",C("users")],["size",U]],e,r)}async getLeaderboard(e){return this.apiCall(this.leaderboardManager,"getLeaderboard",[["name",b]],e)}async getOrCreateLeaderboard(e,r,s){return this.apiCall(this.leaderboardManager,"getOrCreateLeaderboard",[["name",b],["sortOrder",ne(dt,"LeaderboardSortOrder")],["displayType",ne(ht,"LeaderboardDisplayType")]],e,r,s)}getLeaderboardEntryCount(e){return this.apiCallSync(this.leaderboardManager,"getLeaderboardEntryCount",[["leaderboardId",C("leaderboards")]],e)}async getMyLeaderboardEntries(e){return this.apiCall(this.leaderboardManager,"getMyLeaderboardEntries",[["leaderboardId",C("leaderboards")]],e)}async listLeaderboardEntriesAroundUser(e,r,s,o=!1){return this.apiCall(this.leaderboardManager,"listLeaderboardEntriesAroundUser",[["leaderboardId",C("leaderboards")],["countAhead",U],["countBehind",U],["friendsOnly",re]],e,r,s,o)}async listLeaderboardEntries(e,r,s,o=!1){return this.apiCall(this.leaderboardManager,"listLeaderboardEntries",[["leaderboardId",C("leaderboards")],["offset",U],["limit",U],["friendsOnly",re]],e,r,s,o)}async uploadLeaderboardScore(e,r,s,o){return this.apiCall(this.leaderboardManager,"uploadLeaderboardScore",[["leaderboardId",C("leaderboards")],["score",U],["keepBest",re],["ugcId",x(C("userGeneratedContent"))]],e,r,s,o)}async createUGCItem(e,r,s,o,i){return this.apiCall(this.ugcManager,"createUGCItem",[["ugcType",ne(xe,"UGCType")],["title",x(b)],["description",x(b)],["visibility",x(ne(Me,"UGCVisibility"))],["filePath",x(b)]],e,r,s,o,i)}async updateUGCItem(e,r={}){if(typeof r=="string"){let s=r;try{r=JSON.parse(s)}catch(o){let i=`updateUGCItem: invalid JSON: ${s}`;return u.error(i,o),this.formatResponse({success:!1,data:null,message:i})}}return this.apiCall(this.ugcManager,"updateUGCItem",[["ugcId",C("userGeneratedContent")],["updates",x(Nt({title:x(b),description:x(b),visibility:x(ne(Me,"UGCVisibility")),filePath:x(b)}))]],e,r)}async deleteUGCItem(e){return this.apiCall(this.ugcManager,"deleteUGCItem",[["ugcId",C("userGeneratedContent")]],e)}async downloadUGCItem(e,r){return this.apiCall(this.ugcManager,"downloadUGCItem",[["ugcId",C("userGeneratedContent")],["filePath",b]],e,r)}async listUGCItems(e={}){if(typeof e=="string"){let r=e;try{e=JSON.parse(r)}catch(s){let o=`listUGCItems: invalid JSON: ${r}`;return u.error(o,s),this.formatResponse({success:!1,data:null,message:o})}}return this.apiCall(this.ugcManager,"listUGCItems",[["args",x((r,s)=>{let o=Nt({createdBy:x(C("users")),ugcType:x(ne(xe,"UGCType")),titleSearch:x(b),numItems:x(U),continueCursor:x(b)})(r,s);if(o.continueCursor!==void 0&&(o.createdBy!==void 0||o.ugcType!==void 0||o.titleSearch!==void 0||o.numItems!==void 0))throw new Error(`${s}: continueCursor should be the only argument if present`);return o})]],e)}async deleteRemoteFile(e){return this.apiCall(this.fileSystemManager,"deleteRemoteFile",[["filePath",b]],e)}async downloadRemoteFile(e){return this.apiCall(this.fileSystemManager,"downloadRemoteFile",[["filePath",b]],e)}async remoteFileExists(e){return this.apiCall(this.fileSystemManager,"remoteFileExists",[["filePath",b]],e)}async uploadRemoteFile(e){return this.apiCall(this.fileSystemManager,"uploadRemoteFile",[["filePath",b]],e)}async listRemoteDirectory(e){return this.apiCall(this.fileSystemManager,"listRemoteDirectory",[["path",b]],e)}async downloadRemoteDirectory(e){return this.apiCall(this.fileSystemManager,"downloadRemoteDirectory",[["path",b]],e)}async writeLocalFile(e,r){return se("writeLocalFile",[["filePath",b],["data",hn]],[e,r]),await this.fileSystemManager.writeLocalFile(e,r)}async readLocalFile(e){return se("readLocalFile",[["filePath",b]],[e]),await this.fileSystemManager.readLocalFile(e)}getAchievement(e){return this.apiCallSync(this.statsManager,"getAchievement",[["identifier",b]],e)}getStat(e){return this.apiCallSync(this.statsManager,"getStat",[["identifier",b]],e)}setAchievement(e,r=!1){return this.apiCallSync(this.statsManager,"setAchievement",[["identifier",b],["storeNow",re]],e,r)}setStat(e,r,s=!1){return this.apiCallSync(this.statsManager,"setStat",[["identifier",b],["value",U],["storeNow",re]],e,r,s)}async requestStats(){return this.apiCall(this.statsManager,"requestStats",[])}storeStats(){return this.apiCallSync(this.statsManager,"storeStats",[])}getP2PMaxPayloadSize(){return this.ensureInit(),this.apiCallSync(this.p2pManager,"getMaxPayloadSize",[])}getP2PMaxIncomingMessages(){return this.ensureInit(),this.apiCallSync(this.p2pManager,"getMaxIncomingMessages",[])}getP2POutgoingMessageBuffer(){return this.ensureInit(),this.apiCallSync(this.p2pManager,"getOutgoingMessageBuffer",[])}sendP2PMessage(e,r=0,s=!0,o,i=o.length){return e&&!this.p2pManager.isPeerReady(e)||!e&&!this.p2pManager.isBroadcastReady()?!1:this.p2pManager.sendP2PMessage(e,r,s,o,i)}broadcastP2PMessage(e=0,r=!0,s,o=s.length){return this.p2pManager.isBroadcastReady()?this.p2pManager.sendP2PMessage(void 0,e,r,s,o):!1}readP2PMessageFromChannel(e){return this.p2pManager.readMessageFromChannel(e)}drainP2PChannelToBuffer(e,r){return this.p2pManager.drainChannelToBuffer(e,r)}async createLobby(e,r){return this.apiCall(this.lobbyManager,"createLobby",[["visibility",ne(ut,"LobbyVisibility")],["maxPlayers",x(U)]],e,r)}async joinLobby(e){return this.apiCall(this.lobbyManager,"joinLobby",[["lobbyId",C("lobbies")]],e)}async listAvailableLobbies(e=!1){return this.apiCall(this.lobbyManager,"listAvailableLobbies",[["friendsOnly",re]],e)}getLobbyUsers(e){return this.apiCallSync(this.lobbyManager,"getLobbyUsers",[["lobbyId",C("lobbies")]],e)}getNumLobbyUsers(e){return this.apiCallSync(this.lobbyManager,"getNumLobbyUsers",[["lobbyId",C("lobbies")]],e)}getLobbyHostId(e){return this.apiCallSync(this.lobbyManager,"getHostId",[["lobbyId",C("lobbies")]],e)}getLobbyData(e,r){return this.apiCallSync(this.lobbyManager,"getLobbyData",[["lobbyId",C("lobbies")],["key",b]],e,r)}setLobbyData(e,r,s){return this.apiCallSync(this.lobbyManager,"setLobbyData",[["lobbyId",C("lobbies")],["key",b],["value",fn(b,U,dn)]],e,r,s)}deleteLobbyData(e,r){return this.apiCallSync(this.lobbyManager,"deleteLobbyData",[["lobbyId",C("lobbies")],["key",b]],e,r)}async leaveLobby(e){return this.apiCall(this.lobbyManager,"leaveLobby",[["lobbyId",C("lobbies")]],e)}sendLobbyMessage(e,r){return this.apiCallSync(this.lobbyManager,"sendLobbyMessage",[["lobbyId",C("lobbies")],["message",b]],e,r)}async inviteUserToLobby(e,r){return this.apiCall(this.lobbyManager,"inviteUserToLobby",[["lobbyId",C("lobbies")],["userId",C("users")]],e,r)}async getLobbyInviteLink(e=!1){return this.apiCall(this.lobbyManager,"getLobbyInviteLink",[["copyToClipboard",re]],e)}async isEntitled(e){return this.apiCall(this.paidContentManager,"isEntitled",[["contentIdentifier",b]],e)}async isEntitled_EXPERIMENTAL(e){return this.isEntitled(e)}async getEntitlements(){return this.apiCall(this.paidContentManager,"getEntitlements",[])}async getEntitlements_EXPERIMENTAL(){return this.getEntitlements()}async triggerPaywall(e){return this.apiCall(this.paidContentManager,"triggerPaywall",[["contentIdentifier",b]],e)}async triggerPaywall_EXPERIMENTAL(e){return this.triggerPaywall(e)}async updateUserPresence(e){if(typeof e=="string"){let r=e;try{e=JSON.parse(r)}catch(s){let o=`updateUserPresence: invalid JSON: ${r}`;return u.error(o,s),this.formatResponse({success:!1,data:null,message:o})}}return this.apiCall(this.heartbeatManager,"updateUserPresence",[["data",pn]],e)}isGodot(){return this.engineInstance!==null&&this.engineInstance.type===er.GODOT}formatResponse(e){return this.isGodot()&&e!==null&&(Array.isArray(e)||Object.getPrototypeOf(e)===Object.prototype)?JSON.stringify(e):e}ensureInit(){if(!this._initialized)throw u.error("SDK not initialized. Call WavedashJS.init first."),new Error("SDK not initialized")}async apiCall(e,r,s,...o){u.debug(r,...o);try{se(r,s,o);let i=await e[r](...o);return this.formatResponse({success:!0,data:i})}catch(i){let a=i instanceof Error?i.message:String(i);return u.error(r,a),this.formatResponse({success:!1,data:null,message:a})}}apiCallSync(e,r,s,...o){u.debug(r,...o);try{se(r,s,o)}catch(i){let a=i instanceof Error?i.message:String(i);throw u.error(r,a),i}return this.formatResponse(e[r](...o))}setEngineInstance(e){this.engineInstance?Object.assign(this.engineInstance,e):this.engineInstance=e}getAuthToken(e=!1){if(!e&&this.gameplayJwt)return Promise.resolve(this.gameplayJwt);if(!e&&this.gameplayJwtPromise)return this.gameplayJwtPromise;let r=this.gameplayJwtPromise,o=(async()=>{r&&await r.catch(()=>{});let i=new URLSearchParams({[Re.Caller]:qr.Wavedash});e&&i.set("fresh","1");let a=`/auth/refresh?${i.toString()}`,c=await fetch(a,{method:"POST",credentials:"same-origin"});if(!c.ok)throw new Error(`Failed to refresh gameplay token: ${c.status}`);return c.text()})().then(i=>(this.gameplayJwt=i,this.gameplayJwtPromise===o&&Oe.postToParent(E.GAMEPLAY_JWT_READY,{gameplayJwt:i}),i)).finally(()=>{this.gameplayJwtPromise===o&&(this.gameplayJwtPromise=null)});return this.gameplayJwtPromise=o,o}async ensureGameplayJwt(e=!1){return this.getAuthToken(e)}destroy(){if(!this.destroyed){this.destroyed=!0;for(let e of this.managers)e.destroy()}}setupSessionEndListeners(){Oe.addEventListener(E.END_SESSION,()=>this.destroy())}setupSwCredsListener(){this.swMessenger.addEventListener(tr.EMBED_CREDS_REQUEST,async(e,r)=>{let s;try{s=await this.ensureGameplayJwt()}catch(o){u.warn("Failed to resolve JWT for creds-request",o);return}r({type:tr.EMBED_CREDS_RESPONSE,payload:{gameplayJwt:s}})})}};function gn(){let n=window.Wavedash;if(n)return n;let t=new URLSearchParams(window.location.search).get(Re.SdkConfig)??window.__wavedashSdkConfig;if(!t)throw new Error(`Wavedash SDK: missing ?${Re.SdkConfig}= query param (or __wavedashSdkConfig global) on the page.`);let e;try{e=JSON.parse(t)}catch(s){let o=s instanceof Error?s.message:String(s);throw new Error(`Wavedash SDK: failed to parse ?${Re.SdkConfig}= as JSON: ${o}`)}Vr(e.parentOrigin);let r=new ur(e);return window.Wavedash=r,window.WavedashJS=r,r}gn();})();
|