@indiegems/gem-web-sdk 22.0.0 → 23.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,3 +1,3 @@
1
- var $e=Object.defineProperty;var je=(t,e)=>{for(var n in e)$e(t,n,{get:e[n],enumerable:true});};globalThis.__gemWebSdkVersion="[gem-web-sdk:sdkVersion:22.0.0]";var Be={initialDelayMs:2e3,maxDelayMs:6e4};function Fe(t,e){return e!==void 0?!e:t==="chain_exhausted"}var N=class{constructor(e){this.options=e;}options;grant=null;state="pending";failure=null;generation=0;inFlight=null;rejected=false;retry=null;failures=0;notBefore=0;disposed=false;get currentState(){return this.state}get lastFailure(){return this.failure}async get(){if(this.state==="lost")throw new h(this.failure??"unavailable","the session cannot be renewed");let e=this.seconds();if(this.grant&&e<this.grant.expiresAt-this.renewBefore())return this.grant.token;if(this.pastChainCeiling())throw new h("chain_exhausted","the token chain reached its ceiling");if(this.inFlight===null&&this.options.clock.now()<this.notBefore)throw new h(this.failure??"unavailable","the embedder asked for no new token yet; one is asked for when that wait is over");return this.refresh(this.nextReason())}pastChainCeiling(){return this.grant===null||this.seconds()<this.grant.chainEndsAt?false:(this.enter("lost","chain_exhausted"),true)}nextReason(){return this.rejected?"rejected":this.grant?"expiring":"initial"}invalidate(e){e!==void 0&&this.grant!==null&&this.grant.token!==e||this.rejected&&this.grant===null||(this.grant=null,this.generation+=1,this.inFlight=null,this.rejected=true,this.state!=="lost"&&this.enter("pending"));}accept(e){this.state!=="lost"&&(this.grant=e,this.rejected=false,this.enter("ready"));}close(e="unavailable"){this.grant=null,this.generation+=1,this.inFlight=null,this.enter("lost",e);}dispose(){this.disposed=true,this.cancelRetry();}scheduleRetry(e){if(this.cancelRetry(),this.failures+=1,this.notBefore=e===void 0?0:this.options.clock.now()+e,this.disposed)return;let{initialDelayMs:n,maxDelayMs:r}=Be,o=Math.min(r,n*2**(this.failures-1)),a=Math.max(o/2,e??0)+Math.random()*(o/2);this.retry={handle:this.options.clock.setTimeout(()=>this.retryNow(),a)};}retryNow(){this.retry=null,this.notBefore=0,!(this.state==="lost"||this.pastChainCeiling())&&this.refresh(this.nextReason()).catch(()=>{});}cancelRetry(){this.retry!==null&&(this.options.clock.clearTimeout(this.retry.handle),this.retry=null);}refresh(e){if(this.inFlight)return this.inFlight;this.cancelRetry();let n=this.generation;this.enter("pending");let r=this.options.request(e).then(o=>{if(n!==this.generation)throw new h("internal","token arrived for a superseded generation");return this.grant=o,this.rejected=false,this.enter("ready"),o.token}).catch(o=>{let a=Ue(o),{retryable:i,retryAfterMs:d}=o??{};throw n===this.generation&&(Fe(a,typeof i=="boolean"?i:void 0)?this.enter("lost",a):(this.scheduleRetry(typeof d=="number"&&Number.isFinite(d)&&d>0?d:void 0),this.enter("degraded",a))),o instanceof h?o:new h(a,String(o))}).finally(()=>{this.inFlight===r&&(this.inFlight=null);});return this.inFlight=r,r}enter(e,n){(e==="ready"||e==="lost")&&this.cancelRetry(),e==="ready"&&(this.failures=0,this.notBefore=0),this.failure=n??(e==="ready"?null:this.failure),this.state!==e&&(this.state=e,this.options.onStateChange?.(e,n));}renewBefore(){return this.options.renewBeforeSeconds??60}seconds(){return Math.floor(this.options.clock.now()/1e3)}},h=class t extends Error{constructor(n,r){super(`auth ${n}: ${r}`);this.reason=n;this.name="AuthError";}reason;static isAuthError(n){if(n instanceof t)return true;let r=n;return r?.name==="AuthError"&&typeof r.reason=="string"}};function Ue(t){if(t instanceof h)return t.reason;let e=t?.reason;return typeof e=="string"&&["chain_exhausted","unavailable","timeout","internal"].includes(e)?e:"internal"}var f=class t extends Error{retryable=false;constructor(e){super(e),this.name="TransportRefusal";}static isRefusal(e){if(e instanceof t)return true;let n=e;return n?.name==="TransportRefusal"&&n.retryable===false}},H=["if-match","if-none-match"],ee=4096;function De(t){if(!t)return;let e={};for(let[n,r]of Object.entries(t)){let o=n.toLowerCase();if(!H.includes(o)||r===void 0)continue;let a=typeof r=="string"?Ne(r):r;if(typeof a!="string"||a.length>ee||!He(a))throw new f(`the ${o} header value cannot be sent \u2014 it is not a string, is longer than ${ee} characters, or contains a character outside the range an HTTP header value may carry. This is a malformed request, not a server failure; the value is withheld here rather than written to logs.`);a!==""&&(e[o]=a);}return Object.freeze(e)}function Ne(t){let e=o=>o===32||o===9||o===10||o===13,n=0,r=t.length;for(;n<r&&e(t.charCodeAt(n));)n++;for(;r>n&&e(t.charCodeAt(r-1));)r--;return t.slice(n,r)}function He(t){for(let e=0;e<t.length;e++){let n=t.charCodeAt(e);if(n!==9&&(n<32||n===127||n>255))return false}return true}function Ve(t){let{bytes:e}=t;if(e!==void 0){if(Object.prototype.toString.call(e)!=="[object Uint8Array]")throw new f("the raw body is not a Uint8Array, so it cannot be sent as bytes. This is a malformed request, not a server failure.");if(t.body!==void 0)throw new f("the request carries both a JSON body and a raw body, and only one can be sent. This is a malformed request, not a server failure.");return new Uint8Array(e)}}function te(t,e){let n=e.replayUnauthorizedOnce??true;return {async request(r){let o={...r},a=De(o.headers),i=Ve(o),d=Object.freeze({...o,headers:a,...i===void 0?{}:{bytes:i}}),u=await e.tokenSource.get(),c=await t(d,u);if(c.status!==401||!n)return c;e.tokenSource.invalidate(u);let g=await e.tokenSource.get(),S=await t(d,g);if(S.status===401)throw e.tokenSource.close("unavailable"),new h("unavailable","the server refused a freshly minted token");return S}}}function ne(t){let e=typeof t=="string"?new TextEncoder().encode(t):t;return btoa(We(e))}function We(t){let n="";for(let r=0;r<t.length;r+=32768)n+=String.fromCharCode(...t.subarray(r,r+32768));return n}var p=class extends Error{constructor(n,r,o,a,i){super(`${n} (${r}): ${o}`);this.reason=n;this.status=r;this.detail=o;this.retryAfterSeconds=a;this.code=i;this.name="GemApiError";}reason;status;detail;retryAfterSeconds;code;get retryable(){return this.reason==="unavailable"||this.reason==="rate_limited"}},ae=new WeakMap;function se(t){return ae.get(t)??{}}var ze=new Set([408,429,500,502,503,504]),Ke=6e4,Ye=new WeakMap;function re(t){return t!==null&&(t.reason==="rate_limited"||t.retryAfterSeconds!==void 0)}function Je(t){if(t===void 0)return 2;if(!Number.isInteger(t)||t<0||t>10)throw new f(`maxRetries must be a whole number between 0 and 10; received ${JSON.stringify(t)}. This is a configuration fault, not a server failure.`);return t}var L=class{constructor(e){this.options=e;}options;async get(e,n){return this.send({method:"GET",path:e,signal:n},true)}async getWithEtag(e,n={}){let r=await this.sendRaw({method:"GET",path:e,...n.signal===void 0?{}:{signal:n.signal},...n.ifNoneMatch===void 0?{}:{headers:{"if-none-match":n.ifNoneMatch}}},true),o=r.etag===void 0?{}:{etag:r.etag};return r.status===304?{modified:false,...o}:{modified:true,body:r.body,...o}}async put(e,n,r,o={}){return this.send({method:"PUT",path:e,body:n,signal:r,...$(o)},o.replaySafe===true,o.retryRateLimited!==false)}async post(e,n,r,o={}){return this.send({method:"POST",path:e,body:n,signal:r,...$(o)},o.replaySafe===true,o.retryRateLimited!==false)}async postBytes(e,n,r,o={}){let a=await this.sendRaw({method:"POST",path:e,bytes:n,responseType:"bytes",signal:r,...$(o)},o.replaySafe===true,o.retryRateLimited!==false);return {bytes:Xe(a.body),...a.invocationId===void 0?{}:{invocationId:a.invocationId}}}async patch(e,n,r,o={}){return this.send({method:"PATCH",path:e,body:n,signal:r,...$(o)},o.replaySafe===true,o.retryRateLimited!==false)}async delete(e,n,r={}){return this.send({method:"DELETE",path:e,signal:n,...$(r)},r.replaySafe===true,r.retryRateLimited!==false)}async send(e,n,r=true){return (await this.sendRaw(e,n,r)).body}async sendRaw(e,n,r=true){let o=n?Je(this.options.maxRetries)+1:1,a=null;if(e.signal?.aborted)throw oe(e.signal);let i=e.signal===void 0?void 0:Ye.get(e.signal);for(let d=0;d<o;d++){if(d>0){let g=this.backoffMs(d,a);if(re(a)&&i!==void 0&&g>=i())throw a;await this.backoff(g,e.signal);}if(e.signal?.aborted)throw re(a)&&i!==void 0&&i()<=0?a:oe(e.signal);let u;try{u=await this.options.transport.request(e);}catch(g){if(h.isAuthError(g)||f.isRefusal(g)||e.signal?.aborted||Qe(g))throw g;a=new p("unavailable",0,String(g));continue}if(u.status>=200&&u.status<300||u.status===304)return u;let c=Ze(u);if(!ze.has(u.status)||u.status===429&&!r)throw c;a=c;}throw a??new p("unavailable",0,"no attempt was made")}backoffMs(e,n){let r=n?.retryAfterSeconds,o=r!==void 0?r*1e3:2**(e-1)*250,a=2**(e-1)*250;return Math.min(Math.max(o,a),Ke)}backoff(e,n){return n?.aborted?Promise.resolve():new Promise(r=>{let o=this.options.clock,a=false,i=false,d,u=()=>{a||(a=true,i&&o.clearTimeout(d),n?.removeEventListener("abort",u),r());};n?.addEventListener("abort",u,{once:true}),d=o.setTimeout(u,e),i=true,a&&o.clearTimeout(d);})}};function Xe(t){if(t instanceof Uint8Array)return t;if(t==null)return new Uint8Array(0);let e=typeof t=="string"?t:JSON.stringify(t);return new TextEncoder().encode(e)}function $(t){return {...t.keepalive===void 0?{}:{keepalive:t.keepalive},...t.ifMatch===void 0?{}:{headers:{"if-match":t.ifMatch}}}}function oe(t){return t.reason!==void 0?t.reason:new DOMException("The operation was aborted.","AbortError")}function Qe(t){let e=t?.name;return e==="AbortError"||e==="TimeoutError"}function Ze(t){let e=tt(t),n=rt(t.body),r={...n===void 0?{}:{details:n},...t.invocationId===void 0?{}:{invocationId:t.invocationId}};return Object.keys(r).length>0&&ae.set(e,r),e}var et=new Map([["insufficient_funds","insufficient_funds"]]);function tt(t){let{status:e,body:n}=t,r=nt(n),o=t.retryAfterSeconds??at(n),a=ot(n),i=a===void 0?void 0:et.get(a);if(i!==void 0)return new p(i,e,r,void 0,a);switch(e){case 304:return new p("not_modified",e,r);case 400:case 422:return new p("invalid",e,r,void 0,a);case 403:return new p("forbidden",e,r,void 0,a);case 404:return new p("not_found",e,r,void 0,a);case 402:return new p("insufficient_funds",e,r,void 0,a);case 409:return new p("conflict",e,r,void 0,a);case 412:return new p("precondition_failed",e,r,void 0,a);case 413:return new p("too_large",e,r,void 0,a);case 429:return new p("rate_limited",e,r,o,a);default:return new p("unavailable",e,r,o,a)}}function nt(t){if(typeof t=="string")return t;let e=t?.message;if(typeof e=="string")return e;let n=t?.error;if(typeof n=="string")return n;let r=n?.message;return typeof r=="string"?r:"no detail"}function rt(t){let n=t?.error?.details;return n===null?void 0:n}function ot(t){let n=t?.error?.code;return typeof n=="string"&&n.length>0?n:void 0}function at(t){let e=t?.retryAfterSeconds;return typeof e=="number"&&Number.isFinite(e)&&e>=0?e:void 0}function st(t){let e=t.lastIndexOf("@");return (e===-1?t:`***@${t.slice(e+1)}`).slice(0,200)}var it=new Set(H);function lt(t){if(!t)return {};let e={};for(let[n,r]of Object.entries(t))it.has(n.toLowerCase())&&(e[n.toLowerCase()]=r);return e}function ie(t){let e=t.fetch??globalThis.fetch.bind(globalThis);return te(async(n,r)=>{let o;try{o=new URL(t.baseUrl.replace(/\/+$/,""));}catch{throw new f("the configured baseUrl is not a valid URL. Its value is withheld here rather than written to logs. This is a configuration fault, not a server failure.")}let a;try{a=new URL(o.href.replace(/\/+$/,"")+n.path);}catch{throw new f(`${JSON.stringify(typeof n.path=="string"?st(n.path):"(a non-string path)")} does not form a valid URL against ${o.protocol}//${o.host}. This is a malformed request, not a server failure.`)}if(a.protocol!==o.protocol||a.host!==o.host)throw new f(`${JSON.stringify(a.pathname)} resolves to ${a.protocol}//${a.host}, not ${o.protocol}//${o.host}. A request path may not change the request's origin \u2014 it carries the play token.`);if(a.username!==""||a.password!==""){let b=o.username!==""||o.password!=="",y=a.username!==o.username||a.password!==o.password,x=b?y?"baseUrl (and possibly the request path)":"baseUrl":"request path";throw new f(`the ${x} puts credentials in the URL, which cannot be fetched (${n.method} ${a.pathname}). The value is withheld here rather than written to logs. This is a malformed request, not a server failure.`)}for(let[b,y]of Object.entries(t.defaultQuery??{}))a.searchParams.has(b)||a.searchParams.set(b,y);let i=n.bytes,d=n.bytes===void 0?void 0:"application/octet-stream";try{n.body!==void 0&&(i=JSON.stringify(n.body),d="application/json");}catch(b){throw new f(`the body of ${n.method} ${JSON.stringify(a.pathname)} could not be serialised to JSON: ${String(b)}. This is a bug in the request, not a server failure \u2014 retrying sends the same unserialisable value.`)}let u=await e(a.toString(),{method:n.method,headers:{authorization:`Bearer ${r}`,...d===void 0?{}:{"content-type":d},...lt(n.headers)},body:i,signal:n.signal,...n.keepalive===void 0?{}:{keepalive:n.keepalive},credentials:"omit",mode:"cors",redirect:"error",cache:"no-store",referrerPolicy:"no-referrer"}),c=null;if(n.responseType==="bytes"&&u.status>=200&&u.status<300)c=new Uint8Array(await u.arrayBuffer());else {let b=await u.text();if(b.length>0)try{c=JSON.parse(b);}catch{c=b;}}let g=u.headers.get("etag"),S=dt(u.headers.get("retry-after")),w=u.headers.get("x-gem-invocation-id");return {status:u.status,body:c,...g===null?{}:{etag:g},...S===void 0?{}:{retryAfterSeconds:S},...w===null||w===""?{}:{invocationId:w}}},t)}function dt(t){if(t===null)return;let e=t.trim();if(!/^\d+$/.test(e))return;let n=Number(e);return Number.isFinite(n)?n:void 0}var ut="gem-web-bridge";var ct=65536,le=8,V=5e3,de=1024;var W=Object.create(null);var ue=Object.create(null);function mt(t){let e=/^([a-z][a-z0-9+.-]*):\/\/([a-z0-9.-]+|\[[0-9a-f:.]+\])(:([0-9]{1,5}))?$/i.exec(t);return e===null?false:e[4]===void 0||Number(e[4])<=65535}function gt(t){let e;try{e=new URL(t);}catch{return false}return e.username!==""||e.password!==""?false:e.protocol==="https:"?true:e.protocol==="http:"&&(e.hostname==="localhost"||e.hostname==="127.0.0.1")}function pt(t){return /^[a-z]{2,8}(-[a-z0-9]{1,8})*$/i.test(t)}function yt(t){return /^[a-z_]+$/.test(t)}function ft(t){return /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(t)||/^[a-z0-9][a-z0-9-]{1,38}[a-z0-9]$/.test(t)&&!t.includes("--")}function K(t,e,n){if(e>le)return `nesting deeper than ${le}`;if(++n.nodes>V)return `more than ${V} values`;if(n.bytes>n.cap)return `over the ${n.cap} byte limit`;if(t==null)return n.bytes+=4,null;let r=typeof t;if(r==="boolean")return n.bytes+=5,null;if(r==="number")return n.bytes+=8,null;if(r==="string")return n.bytes+=t.length*3+2,null;if(r!=="object")return `${r} is not plain data`;let o=t;if(n.seen.has(o))return "a repeated or cyclic object reference";if(n.seen.add(o),Array.isArray(t)){if(t.length>de)return `an array of ${t.length} entries, over the ${de} limit`;n.bytes+=2;for(let d of t){let u=K(d,e+1,n);if(u)return u}return null}let a=Object.getPrototypeOf(t);if(a!==Object.prototype&&a!==null)return "a value that is not a plain object";n.bytes+=2;let i=t;for(let d in i){if(!Object.prototype.hasOwnProperty.call(i,d))continue;if(++n.nodes>V)return `more than ${V} values`;if(n.bytes+=d.length*3+4,n.bytes>n.cap)return `over the ${n.cap} byte limit`;let u=K(i[d],e+1,n);if(u)return u}return null}function ht(t,e=ct){let n={nodes:0,bytes:0,seen:new Set,cap:e},r=K(t,0,n);return r?`message contains ${r}`:n.bytes>e?`message is over the ${e} byte limit`:null}var _t={origin:[mt,"not a well-formed origin"],url:[gt,"not a safe absolute http(s) URL"],bcp47:[pt,"not a well-formed BCP 47 tag"],code:[yt,"not a code of lower-case letters and underscores"],gameRef:[ft,"not a game id or web address"]};function ce(t,e,n){for(let r of e){let o=n===""?r[0]:`${n}.${r[0]}`,a=t[r[0]];if(a==null){if(r[1]<"a")continue;return `${o}: required`}let i=Y(a,r,o);if(i)return i}return null}function Y(t,e,n){let r=e[1].toLowerCase();switch(r){case "u":return typeof t=="boolean"?null:Y(t,typeof t=="string"?[e[0],"s",e[2]]:[e[0],"n",e[3],e[4]],n);case "s":{if(typeof t!="string")return `${n}: expected string`;if(t.length>e[2])return `${n}: exceeds ${e[2]} characters`;if(e[3]){let[o,a]=_t[e[3]];if(!o(t))return `${n}: ${a}`}return null}case "n":case "i":return typeof t!="number"||!(r=="i"?Number.isInteger:Number.isFinite)(t)?`${n}: expected ${r=="i"?"integer":"number"}`:t<e[2]||t>e[3]?`${n}: out of range ${e[2]}..${e[3]}`:null;case "b":return typeof t=="boolean"?null:`${n}: expected boolean`;case "e":{let o=e[2];return o.includes(t)?null:`${n}: not one of ${o.join("|")}`}case "o":return typeof t!="object"||t===null||Array.isArray(t)?`${n}: expected object`:ce(t,e[2],n);case "j":return typeof t!="object"||t===null||Array.isArray(t)?`${n}: expected a plain object`:null;case "a":{if(!Array.isArray(t))return `${n}: expected array`;if(t.length>e[2])return `${n}: exceeds ${e[2]} items`;let o=e[3],a=`${n}[]`;for(let i of t){if(i==null){if(o[1]<"a")continue;return `${a}: required`}let d=Y(i,o,a);if(d)return d}return null}default:return `${n}: unknown kind ${String(r)}`}}var me=Object.create(null);function l(t,e,n,r,o){return W[t]=n,r&&(ue[t]=r),me[t]=a=>{let i=ht(a,o);if(i)return i;if(typeof a!="object"||a===null||Array.isArray(a))return "message: expected object";let d=a;return d.gem!==ut?"gem: wrong protocol marker":d.type!==t?`type: expected ${t}`:ce(d,e,"")}}var j=["","s",64],m=["requestId","s",64],B=["matchId","s",64],T=["reason","S",64,"code"],E=["outcome","e",["ok","declined","unavailable"]];l("gem.handshake",[["versions","o",[["min","i",1,1e3],["max","i",1,1e3]]],["capabilities","A",64,j],["embedder","s",2048,"origin"],["unbidden","B"]],30);l("gem.handshake.accept",[["v","i",1,1e3],["capabilities","A",64,j]],5);l("gem.token",[["token","s",4096],["requestId","S",64],["generation","i",0,2147483647],["apiBaseUrl","S",512,"url"],["playerId","s",64],["gameId","s",64],["channel","e",["dev","test","release"]],["gameVersion","S",64],["expiresAt","i",0,4102444800],["chainEndsAt","i",0,4102444800],["allowDevTools","B"]],30);l("gem.token.denied",[m,["retryable","b"],["retryAfterMs","I",0,36e5],["reason","e",["chain_exhausted","unavailable"]],["correlationId","s",64]],30);l("gem.player",[["untrusted","o",[["displayName","s",64],["displayTag","S",80],["displayHandle","s",80]]],["playerId","S",64],["discriminator","S",8],["avatarIconUrl","S",2048,"url"],["avatarIconId","S",64],["avatar3dId","S",64],["avatar3dModelUrl","S",2048,"url"],["avatar3dIconUrl","S",2048,"url"],["avatars3d","A",8,["","o",[["family","s",32],["id","s",64],["modelUrl","s",256,"url"],["iconUrl","s",256,"url"]]]],["badges","A",2,["","o",[["itemId","s",64],["iconUrl","s",2048,"url"]]]],["displayTag","s",8],["avatarUrl","S",2048,"url"],["boost","O",[["multipliers","a",8,["","o",[["currencyId","s",64],["currencySlug","s",32],["multiplierBp","i",1e4,1e6]]]],["expiresInDays","I",1,7]]]],12);l("gem.pause",[["paused","b"]],120);l("gem.prefs",[["reducedMotion","b"],["muted","b"],["showFrameStats","B"],["music","B"],["sounds","B"],["locale","s",35,"bcp47"],["recommended","O",[["volume","i",0,100],["batterySaver","b"],["keyboardLayout","e",["wasd","arrows"]],["gamepadConfirm","e",["south","east"]],["vibration","b"],["lookSensitivity","I",20,400],["gamepadLookSensitivity","I",20,400],["invertLookY","B"],["touchMovement","S",16,"code"],["graphicsQuality","S",16,"code"],["graphicsQualityAuto","B"],["colorHelp","B"]]]],60);l("gem.cohorts",[["cohorts","a",8,["","o",[["experimentId","s",36],["variantKey","s",32]]]]],12,"cohorts");l("gem.earnAllowanceChanged",[],30,"earnAllowance");l("gem.viewport",[["insets","o",[["top","i",0,4096],["right","i",0,4096],["bottom","i",0,4096],["left","i",0,4096]]],["reserved","A",4,["","o",[["x","i",0,16384],["y","i",0,16384],["width","i",0,16384],["height","i",0,16384],["control","O",[["x","i",0,16384],["y","i",0,16384],["width","i",0,16384],["height","i",0,16384]]]]]]],60,"viewport");l("gem.deviceSettings",[["settings","J"]],12,"deviceSettings");l("gem.willTerminate",[["reason","e",["grant_expiring","session_ended","navigating","kill_switch"]],["graceMs","i",0,6e4]],10);l("gem.roomEvent",[["event","e",["updated","match_started","match_ready","match_failed","version_stale"]],["roomId","s",64],["matchId","S",64],["version","I",0,2147483647],["reason","S",64],["platform","E",["universal","mobile"]]],120,"rooms");l("gem.socketState",[["connected","b"],["reason","E",["connecting","dropped","watchdog","terminal"]]],12,"socketState");l("gem.seatedEvent",[["roomId","s",64]],60,"partySeating");l("gem.autoStartFailedEvent",[["roomId","s",64],["code","s",64]],30,"autoStartFailure");l("gem.ticketEvent",[["event","e",["queued","matched","expired","cancelled","failed"]],["ticketId","s",64],["partySize","I",1,64],["queuedAt","I",0,4102444800],["expiresAt","I",0,4102444800],["reason","S",64],["roomId","S",64]],60,"ticketEvents");l("gem.signalEvent",[["event","e",["hello","offer","answer","ice","peerJoined","peerLeft","migration","matchEnded","error"]],B,["data","j"]],1800,"p2p");l("gem.relayDraining",[B,["clusterTargetId","s",64],["relayIps","a",16,j],["drainingSince","s",40],["deadline","s",40]],60,"p2pRelayDrain");l("gem.dedicatedEvent",[["event","e",["answer","error","matchEnded"]],B,["sdp","S",10240],["sessionId","S",64],["code","S",64],["message","S",256],["reason","S",64]],120,"dedicated");l("gem.partyResult",[m,["partyId","S",64]],30,"parties");l("gem.clusterTarget",[["clusterTargetId","s",64],["clusterTargetIds","A",3,j]],12,"clusterTarget");l("gem.graphicsRoutes",[["entries","a",32,["","o",[["gpu","s",32],["route","S",32],["host","S",32]]]]],12,"graphicsRoutes");l("gem.devtools",[["action","e",["open","close","toggle"]]],30,"devtools");l("gem.screenshot",[["maxWidth","i",1,7680],["maxHeight","i",1,4320]],6,"screenshot");l("gem.screenshot.denied",[["reason","e",["not_wired","no_source","unsupported","unreadable","tainted","too_large","busy","declined","failed"]],["retryable","b"]],12,"screenshot");l("gem.requestContext",[],12,"feedbackContext");l("gem.gameContext",[["context","j"]],12,"feedbackContext");l("gem.signal",[["signal","e",["join","offer","answer","ice","migrationAck","hostUnreachable"]],B,["data","j"]],1200,"p2p");l("gem.dedicatedOffer",[B,["sdp","s",10240],["intent","e",["initial","ice_restart","full_reconnect"]]],60,"dedicated");l("gem.partyRequest",[m],12,"parties");l("gem.ready",[],5);l("gem.engaged",[],5,"engagement");l("gem.progress",[["loaded","i",0,1099511627776],["total","i",0,1099511627776]],600);l("gem.requestToken",[m,["reason","e",["initial","expiring","rejected"]]],12);l("gem.requestLocalServer",[m,["gameRoomId","s",64]],6,"localHost");l("gem.localServer",[m,["serverId","S",128]],30,"localHost");l("gem.localServer.denied",[m,["retryable","b"],["reason","e",["refused","unavailable"]]],30,"localHost");l("gem.exit",[["reason","S",64]],5);l("gem.openExternal",[["url","s",2048,"url"]],6);l("gem.requestFullscreen",[["enabled","b"]],30);l("gem.audioState",[["muted","b"]],120,"audioState");l("gem.rewardCue",[["currencySlug","s",32],["cueId","S",64],["expected","I",1,1e9],["origin","O",[["x","i",0,16384],["y","i",0,16384]]]],60,"rewardCue");l("gem.rewardPresentation",[["mode","e",["arcade","game"]]],12,"rewardPresentation");l("gem.walletDisplay",[["visible","b"],["currencies","A",8,j],["score","B"]],60,"walletDisplay");l("gem.controlsDeclare",[["uses","o",[["lookSensitivity","S",16,"code"],["gamepadLookSensitivity","S",16,"code"],["invertLookY","S",16,"code"],["touchMovement","S",16,"code"]]]],60,"controls");l("gem.menu",[["settings","b"],["items","A",4,["","o",[["id","s",32],["label","s",40]]]]],60,"gameMenu");l("gem.menuSelect",[["entry","e",["settings","item"]],["id","S",32]],60,"gameMenu");l("gem.gemCorner",[["corner","e",["top-left","top-right","bottom-left","bottom-right"]]],12,"gemCorner");l("gem.menuStyle",[["ground","S",7],["accent","S",7]],12,"menuStyle");l("gem.settingsDeclare",[["settings","a",8,["","o",[["id","s",40],["label","s",40],["kind","e",["toggle","slider","choice"]],["value","u",40,-1e6,1e6],["quick","B"],["icon","S",16,"code"],["min","N",-1e6,1e6],["max","N",-1e6,1e6],["step","N",0,1e6],["options","A",4,["","o",[["id","s",40],["label","s",40]]]]]]]],120,"gameSettings");l("gem.settingChange",[["id","s",40],["value","u",40,-1e6,1e6]],120,"gameSettings");l("gem.requestShare",[["requestId","S",64],["params","a",16,["","o",[["key","s",64],["value","s",512]]]]],6,"share");l("gem.shareResult",[m,["outcome","e",["accepted","refused"]],T,["key","S",64]],30,"shareResult");l("gem.requestAvatarPicker",[["tab","E",["2d","3d"]]],6,"avatarPicker");l("gem.vibrate",[["pattern","a",99,["","i",0,1e4]]],600,"vibration");l("gem.frameStats",[["fps","i",0,1e3],["frameTimeP95Ms","i",0,1e5],["counts","E",["pageFrames","gameDraws"]]],120,"frameStats");l("gem.portraitBorders",[["name","S",40]],60,"portraitBorders");l("gem.error",[["code","e",["version_mismatch","handshake_timeout","handshake_duplicate","invalid_message","rate_limited","token_unavailable","unsupported","unsupported_capability","internal"]],["message","S",256]],60);l("gem.requestPurchase",[m,["purchaseKind","e",["item","recipe"]],["targetId","s",64],["currencySlug","s",32],["quantity","I",1,10],["catalogId","S",64],["origin","E",["sheet","direct_refused"]]],12,"purchases");l("gem.requestAvatar3dPurchase",[m,["itemId","s",64],["currencySlug","s",32]],12,"avatar3dPurchases");l("gem.purchaseResult",[m,E,T,["purchaseId","S",64]],30,"purchases");l("gem.purchaseSettled",[["purchaseKind","e",["item","recipe"]],["targetId","s",64],["catalogId","S",64],["quantity","i",1,10],["purchaseId","S",64]],30,"purchaseSettled");l("gem.deviceSettings.put",[m,["settings","j"]],30,"deviceSettings");l("gem.deviceSettings.result",[m,["outcome","e",["stored","too_large","unavailable"]]],30,"deviceSettings");l("gem.requestAd",[m,["placement","s",32],["format","e",["interstitial","rewarded"]]],6,"ads");l("gem.adResult",[m,["outcome","e",["shown","no_ad","unavailable"]]],12,"ads");l("gem.signalMoment",[m,["kind","e",["level_end","run_end","match_end","menu_return","other_break"]],["placement","S",32],["wall","B"]],6,"moments");l("gem.momentResult",[m,["shown","b"]],12,"moments");l("gem.requestSignIn",[m],6,"signIn");l("gem.signInResult",[m,["outcome","e",["signed_in","declined","unavailable"]]],12,"signIn");l("gem.requestFriendChallenge",[m,["playerId","s",64],["template","s",64],["params","J"]],12,"friendChallenges");l("gem.friendChallengeResult",[m,["outcome","e",["accepted","cancelled","refused","unavailable","rate_limited","invalid"]],["code","S",64],["param","S",64],["channel","S",16],["configVersion","I",0,9007199254740991],["retryAfterMs","I",0,864e5],["detail","S",300]],30,"friendChallenges");l("gem.requestAppLinks",[m],12,"appLinks");l("gem.appLinksResult",[m,E,T,["arcade","O",[["store","e",["app_store","google_play"]]]],["game","O",[["store","e",["app_store","google_play"]]]]],30,"appLinks");l("gem.requestOpenApp",[m,["target","e",["arcade","game"]]],6,"appLinks");l("gem.openAppResult",[m,E,T],30,"appLinks");l("gem.requestOpenGame",[m,["ref","s",40,"gameRef"]],6,"openGame");l("gem.openGameResult",[m,E,T],30,"openGame");l("gem.requestSimilarGames",[m,["limit","I",1,24]],12,"openGame");l("gem.similarGamesResult",[m,E,T,["games","a",24,["","o",[["gameId","s",36,"gameRef"],["slug","S",40,"gameRef"],["iconUrl","s",1024,"url"],["capsuleLandscapeUrl","s",1024,"url"],["capsulePortraitUrl","s",1024,"url"],["previewVideoUrl","S",1024,"url"],["previewPosterUrl","S",1024,"url"],["untrusted","o",[["name","s",64],["tagline","s",64],["shortDescription","s",320],["tags","a",10,["","s",32]]]]]]]],30,"openGame",524288);l("gem.requestStoreOffers",[m],12,"store");l("gem.storeOffersResult",[m,E,T,["offers","a",32,["","o",[["skuId","s",64],["kind","e",["gem_pack","boost","pass","bundle"]],["name","s",80],["description","s",400],["imageUrl","S",1024,"url"],["priceDisplay","s",32],["grant","O",[["currency","s",32],["amount","i",1,1e9]]]]]]],30,"store",262144);l("gem.requestStorePurchase",[m,["skuId","s",64]],12,"store");l("gem.storePurchaseResult",[m,E,T],30,"store");l("gem.storePurchaseSettled",[["skuId","s",64]],30,"store");l("gem.requestStoreOfferSheet",[m,["skuId","s",64]],12,"storeOfferSheet");l("gem.storeOfferSheetResult",[m,E,T],30,"storeOfferSheet");Object.freeze(me);W.__malformed=60;Object.freeze(W);Object.freeze(ue);var q={now:()=>Date.now(),setTimeout:(t,e)=>setTimeout(t,e),clearTimeout:t=>clearTimeout(t)};function ge(t){let e=t.toLowerCase();return e==="localhost"||e.endsWith(".localhost")||e==="[::1]"||e==="::1"?true:/^127(\.\d{1,3}){3}$/.test(e)}var Rt=1e4;function pe(t,e){return J(t,e)}function J(t,e){if(typeof t.serverToken!="function"||typeof t.onServerToken!="function")throw new Error("this runtime delivers no game-server token: host.serverToken/onServerToken are missing. The server image running this bundle predates token delivery \u2014 the bundle cannot call gem-api on it.");let n=i=>({token:i.token,expiresAt:i.expiresAt,chainEndsAt:Number.POSITIVE_INFINITY}),r=null,o=new N({clock:e.clock,...e.onStateChange===void 0?{}:{onStateChange:e.onStateChange},request:()=>new Promise((i,d)=>{let u=e.clock.setTimeout(()=>{r=null,d({reason:"unavailable",retryable:true});},e.timeoutMs??Rt);r={resolve:c=>{e.clock.clearTimeout(u),i(c);},reject:d,timer:u};})}),a=t.onServerToken(i=>{let d=n(i),u=r;if(u){r=null,u.resolve(d);return}o.accept(d);});return {source:o,dispose(){a(),o.dispose(),r&&(e.clock.clearTimeout(r.timer),r.reject({reason:"unavailable",retryable:false}),r=null);}}}var Q={};je(Q,{acceptTransfer:()=>bt,addEntityProgression:()=>vt,adminAction:()=>St,cancelInventoryTransfer:()=>xt,claimEntityProgressionRewards:()=>wt,closeGameRoom:()=>kt,createEntityBatchOrder:()=>At,createEntityOrder:()=>Ot,createSession:()=>Pt,deleteEntityGameSetting:()=>Gt,deleteEntitySave:()=>Tt,deleteSession:()=>Ct,deleteShowcaseValue:()=>It,executeEntityRecipe:()=>Et,finalizeSaveUpload:()=>Lt,getChannelAssignment:()=>qt,getDropRates:()=>Mt,getEntityCurrency:()=>$t,getEntityGameSetting:()=>jt,getEntityInventory:()=>Bt,getEntityInventoryItem:()=>Ft,getEntityLeaderboard:()=>Ut,getEntityOrder:()=>Dt,getEntityProgression:()=>Nt,getEntityRecipeAvailability:()=>Ht,getEntityRecipeUsage:()=>Vt,getEntitySave:()=>Wt,getEvent:()=>zt,getGameRoomV2:()=>Kt,getLeaderboard:()=>Yt,getPlayerGameProfile:()=>Jt,getPurchaseCatalog:()=>Xt,getResolvedTemplate:()=>Qt,getRoomArgs:()=>Zt,getShowcaseValue:()=>en,getTransferDetails:()=>tn,ingestAnalyticsEvents:()=>X,initiateInventoryTransfer:()=>nn,invokeFunction:()=>rn,kickPlayer:()=>on,listChallenges:()=>an,listEntityGameSettings:()=>sn,listEntityOrders:()=>ln,listEntityProgressions:()=>dn,listEntitySaves:()=>un,listEvents:()=>cn,listGameRooms:()=>mn,listResolvedTemplates:()=>gn,listTransfers:()=>pn,maxEntityProgression:()=>yn,putEntityGameSetting:()=>fn,putRoomArgs:()=>hn,putShowcaseValue:()=>_n,rejectTransfer:()=>Rn,reportMatchPlayers:()=>bn,requestSaveUploadUrl:()=>vn,resetEntityProgression:()=>Sn,setMatchBackfill:()=>xn,simulateEntityOrder:()=>wn,transferHostV2:()=>kn,updateGameRoomV2:()=>An});function s(t){let e=String(t);if(!/^[A-Za-z0-9_.-]{1,128}$/.test(e)||e==="."||e==="..")throw new TypeError(`${JSON.stringify(e)} is not a usable path segment \u2014 it is interpolated into a URL`);return encodeURIComponent(e)}async function bt(t,e,n){let r=`/v1/inventory/transfers/${s(e)}/accept`;return t.client.post(r,void 0,n?.signal)}async function vt(t,e,n,r,o,a){let i=`/v1/inventory/${s(e)}/${s(n)}/progressions/${s(r)}/add`;return t.client.post(i,o,a?.signal)}async function St(t,e,n,r){let o=`/v1/voice/sessions/${s(e)}/admin`;return t.client.post(o,n,r?.signal)}async function xt(t,e,n){let r=`/v1/inventory/transfers/${s(e)}/cancel`;return t.client.post(r,void 0,n?.signal)}async function wt(t,e,n,r,o,a){let i=`/v1/inventory/${s(e)}/${s(n)}/progressions/${s(r)}/claim`;return t.client.post(i,o,a?.signal)}async function kt(t,e,n){let r=`/v1/games/${s(t.gameId())}/game-rooms/${s(e)}`;return t.client.delete(r,n?.signal)}async function At(t,e,n,r,o){let a=`/v1/inventory/${s(e)}/${s(n)}/orders/batch`;return t.client.post(a,r,o?.signal,{...o?.ifMatch===void 0?{}:{ifMatch:o.ifMatch}})}async function Ot(t,e,n,r,o){let a=`/v1/inventory/${s(e)}/${s(n)}/orders`;return t.client.post(a,r,o?.signal,{...o?.ifMatch===void 0?{}:{ifMatch:o.ifMatch}})}async function Pt(t,e,n){return t.client.post("/v1/voice/sessions",e,n?.signal)}async function Gt(t,e,n,r,o){let a=`/v1/settings/${s(e)}/${s(n)}/${s(r)}`;return t.client.delete(a,o?.signal)}async function Tt(t,e,n,r,o){let a=`/v1/saves/${s(e)}/${s(n)}/${s(r)}`;return t.client.delete(a,o?.signal)}async function Ct(t,e,n){let r=`/v1/voice/sessions/${s(e)}`;return t.client.delete(r,n?.signal)}async function It(t,e,n,r){let o=`/v1/showcase/players/${s(e)}/${s(n)}`;return t.client.delete(o,r?.signal)}async function Et(t,e,n,r,o){let a=`/v1/inventory/${s(e)}/${s(n)}/recipes/execute`;return t.client.post(a,r,o?.signal,{...o?.ifMatch===void 0?{}:{ifMatch:o.ifMatch}})}async function Lt(t,e,n,r,o,a){let i=`/v1/saves/${s(e)}/${s(n)}/${s(r)}/finalize`;return t.client.post(i,o,a?.signal)}async function qt(t,e,n){let r=`/v1/games/${s(t.gameId())}/config/channels/${s(e)}`;return t.client.getWithEtag(r,{...n?.signal===void 0?{}:{signal:n.signal},...n?.ifNoneMatch===void 0?{}:{ifNoneMatch:n.ifNoneMatch}})}async function Mt(t,e,n){let r=`/v1/inventory/loot-tables/${s(e)}/drop-rates`;return t.client.get(r,n?.signal)}async function $t(t,e,n,r,o){let a=`/v1/inventory/${s(e)}/${s(n)}/currencies/${s(r)}`;return t.client.get(a,o?.signal)}async function jt(t,e,n,r,o){let a=`/v1/settings/${s(e)}/${s(n)}/${s(r)}`;return t.client.getWithEtag(a,{...o?.signal===void 0?{}:{signal:o.signal},...o?.ifNoneMatch===void 0?{}:{ifNoneMatch:o.ifNoneMatch}})}async function Bt(t,e,n,r){let o=new URLSearchParams;r?.include_buckets!==void 0&&o.set("include_buckets",String(r?.include_buckets)),r?.include_custom_data!==void 0&&o.set("include_custom_data",String(r?.include_custom_data)),r?.currency_limit!==void 0&&o.set("currency_limit",String(r?.currency_limit)),r?.currency_cursor!==void 0&&o.set("currency_cursor",String(r?.currency_cursor)),r?.item_limit!==void 0&&o.set("item_limit",String(r?.item_limit)),r?.item_cursor!==void 0&&o.set("item_cursor",String(r?.item_cursor)),r?.progression_limit!==void 0&&o.set("progression_limit",String(r?.progression_limit)),r?.progression_cursor!==void 0&&o.set("progression_cursor",String(r?.progression_cursor));let a=o.toString(),i=`/v1/inventory/${s(e)}/${s(n)}`+(a?`?${a}`:"");return t.client.get(i,r?.signal)}async function Ft(t,e,n,r,o){let a=`/v1/inventory/${s(e)}/${s(n)}/items/${s(r)}`;return t.client.get(a,o?.signal)}async function Ut(t,e,n,r,o){let a=new URLSearchParams;o?.bucket_1!==void 0&&a.set("bucket_1",String(o?.bucket_1)),o?.bucket_2!==void 0&&a.set("bucket_2",String(o?.bucket_2)),o?.limit!==void 0&&a.set("limit",String(o?.limit)),o?.periods_back!==void 0&&a.set("periods_back",String(o?.periods_back)),o?.period!==void 0&&a.set("period",String(o?.period)),o?.player_id!==void 0&&a.set("player_id",String(o?.player_id));let i=a.toString(),d=`/v1/leaderboards/${s(e)}/${s(n)}/${s(r)}`+(i?`?${i}`:"");return t.client.get(d,o?.signal)}async function Dt(t,e,n,r,o){let a=`/v1/inventory/${s(e)}/${s(n)}/orders/${s(r)}`;return t.client.get(a,o?.signal)}async function Nt(t,e,n,r,o){let a=`/v1/inventory/${s(e)}/${s(n)}/progressions/${s(r)}`;return t.client.get(a,o?.signal)}async function Ht(t,e,n,r,o,a){let i=`/v1/inventory/${s(e)}/${s(n)}/catalogs/${s(r)}/recipes/${s(o)}/availability`;return t.client.get(i,a?.signal)}async function Vt(t,e,n,r){let o=new URLSearchParams;r?.limit!==void 0&&o.set("limit",String(r?.limit));let a=o.toString(),i=`/v1/inventory/${s(e)}/${s(n)}/recipe-usage`+(a?`?${a}`:"");return t.client.get(i,r?.signal)}async function Wt(t,e,n,r,o){let a=`/v1/saves/${s(e)}/${s(n)}/${s(r)}`;return t.client.getWithEtag(a,{...o?.signal===void 0?{}:{signal:o.signal},...o?.ifNoneMatch===void 0?{}:{ifNoneMatch:o.ifNoneMatch}})}async function zt(t,e,n){let r=`/v1/events/${s(e)}`;return t.client.get(r,n?.signal)}async function Kt(t,e,n){let r=`/v2/games/${s(t.gameId())}/game-rooms/${s(e)}`;return t.client.getWithEtag(r,{...n?.signal===void 0?{}:{signal:n.signal},...n?.ifNoneMatch===void 0?{}:{ifNoneMatch:n.ifNoneMatch}})}async function Yt(t,e,n){let r=new URLSearchParams;n?.bucket_1!==void 0&&r.set("bucket_1",String(n?.bucket_1)),n?.bucket_2!==void 0&&r.set("bucket_2",String(n?.bucket_2)),n?.periods_back!==void 0&&r.set("periods_back",String(n?.periods_back)),n?.period!==void 0&&r.set("period",String(n?.period)),n?.player_id!==void 0&&r.set("player_id",String(n?.player_id));let o=r.toString(),a=`/v1/leaderboards/${s(e)}`+(o?`?${o}`:"");return t.client.get(a,n?.signal)}async function Jt(t,e,n){let r=`/v1/profiles/players/${s(e)}`;return t.client.get(r,n?.signal)}async function Xt(t,e){let n=new URLSearchParams;e?.config_version!==void 0&&n.set("config_version",String(e?.config_version));let r=n.toString(),o="/v1/inventory/platform-funded-game-inventory-purchase-catalog"+(r?`?${r}`:"");return t.client.get(o,e?.signal)}async function Qt(t,e,n){let r=`/v1/game-room-templates/${s(e)}`;return t.client.get(r,n?.signal)}async function Zt(t,e,n){let r=`/v1/games/${s(t.gameId())}/game-rooms/${s(e)}/room-args`;return t.client.get(r,n?.signal)}async function en(t,e,n,r){let o=`/v1/showcase/players/${s(e)}/${s(n)}`;return t.client.get(o,r?.signal)}async function tn(t,e,n){let r=`/v1/inventory/transfers/${s(e)}`;return t.client.get(r,n?.signal)}async function X(t,e,n){let r=`/v1/games/${s(t.gameId())}/analytics/events`;return t.client.post(r,e,n?.signal,{replaySafe:true,retryRateLimited:false})}async function nn(t,e,n){return t.client.post("/v1/inventory/transfers",e,n?.signal)}async function rn(t,e,n){let r=new URLSearchParams;n?.cue_id!==void 0&&r.set("cue_id",String(n?.cue_id));let o=r.toString(),a="/v1/functions/invoke"+(o?`?${o}`:"");return t.client.postBytes(a,e,n?.signal)}async function on(t,e,n,r){let o=`/v1/games/${s(t.gameId())}/game-rooms/${s(e)}/kick/${s(n)}`;return t.client.post(o,void 0,r?.signal)}async function an(t,e){let n=new URLSearchParams;e?.periods_back!==void 0&&n.set("periods_back",String(e?.periods_back)),e?.player_id!==void 0&&n.set("player_id",String(e?.player_id));let r=n.toString(),o="/v1/challenges"+(r?`?${r}`:"");return t.client.get(o,e?.signal)}async function sn(t,e,n,r){let o=`/v1/settings/${s(e)}/${s(n)}`;return t.client.get(o,r?.signal)}async function ln(t,e,n,r){let o=new URLSearchParams;r?.limit!==void 0&&o.set("limit",String(r?.limit)),r?.cursor!==void 0&&o.set("cursor",String(r?.cursor));let a=o.toString(),i=`/v1/inventory/${s(e)}/${s(n)}/orders`+(a?`?${a}`:"");return t.client.get(i,r?.signal)}async function dn(t,e,n,r){let o=`/v1/inventory/${s(e)}/${s(n)}/progressions`;return t.client.get(o,r?.signal)}async function un(t,e,n,r){let o=new URLSearchParams;r?.limit!==void 0&&o.set("limit",String(r?.limit)),r?.cursor!==void 0&&o.set("cursor",String(r?.cursor));let a=o.toString(),i=`/v1/saves/${s(e)}/${s(n)}`+(a?`?${a}`:"");return t.client.get(i,r?.signal)}async function cn(t,e){let n=new URLSearchParams;e?.include_inactive!==void 0&&n.set("include_inactive",String(e?.include_inactive)),e?.limit!==void 0&&n.set("limit",String(e?.limit)),e?.offset!==void 0&&n.set("offset",String(e?.offset));let r=n.toString(),o="/v1/events"+(r?`?${r}`:"");return t.client.get(o,e?.signal)}async function mn(t,e){let n=new URLSearchParams;e?.status!==void 0&&n.set("status",String(e?.status)),e?.game_channel!==void 0&&n.set("game_channel",String(e?.game_channel)),e?.game_room_type!==void 0&&n.set("game_room_type",String(e?.game_room_type)),e?.template_id!==void 0&&n.set("template_id",String(e?.template_id)),e?.template_slug!==void 0&&n.set("template_slug",String(e?.template_slug)),e?.limit!==void 0&&n.set("limit",String(e?.limit)),e?.cursor!==void 0&&n.set("cursor",String(e?.cursor));let r=n.toString(),o=`/v1/games/${s(t.gameId())}/game-rooms`+(r?`?${r}`:"");return t.client.get(o,e?.signal)}async function gn(t,e){return t.client.get("/v1/game-room-templates",e?.signal)}async function pn(t,e){let n=new URLSearchParams;e.entity_type!==void 0&&n.set("entity_type",String(e.entity_type)),e.entity_id!==void 0&&n.set("entity_id",String(e.entity_id)),e?.direction!==void 0&&n.set("direction",String(e?.direction)),e?.status!==void 0&&n.set("status",String(e?.status)),e?.cursor!==void 0&&n.set("cursor",String(e?.cursor)),e?.limit!==void 0&&n.set("limit",String(e?.limit));let r=n.toString(),o="/v1/inventory/transfers"+(r?`?${r}`:"");return t.client.get(o,e?.signal)}async function yn(t,e,n,r,o,a){let i=`/v1/inventory/${s(e)}/${s(n)}/progressions/${s(r)}/max`;return t.client.post(i,o,a?.signal)}async function fn(t,e,n,r,o,a){let i=`/v1/settings/${s(e)}/${s(n)}/${s(r)}`;return t.client.put(i,o,a?.signal,{...a?.ifMatch===void 0?{}:{ifMatch:a.ifMatch}})}async function hn(t,e,n,r){let o=`/v1/games/${s(t.gameId())}/game-rooms/${s(e)}/room-args`;return t.client.put(o,n,r?.signal)}async function _n(t,e,n,r,o){let a=`/v1/showcase/players/${s(e)}/${s(n)}`;return t.client.put(a,r,o?.signal)}async function Rn(t,e,n){let r=`/v1/inventory/transfers/${s(e)}/reject`;return t.client.post(r,void 0,n?.signal)}async function bn(t,e,n,r){let o=`/v1/games/${s(t.gameId())}/matches/${s(e)}/players/report`;return t.client.post(o,n,r?.signal)}async function vn(t,e,n,r,o,a){let i=`/v1/saves/${s(e)}/${s(n)}/${s(r)}/upload-url`;return t.client.post(i,o,a?.signal,{replaySafe:true})}async function Sn(t,e,n,r,o,a){let i=`/v1/inventory/${s(e)}/${s(n)}/progressions/${s(r)}/reset`;return t.client.post(i,o,a?.signal)}async function xn(t,e,n,r){let o=`/v1/games/${s(t.gameId())}/matches/${s(e)}/backfill`;return t.client.put(o,n,r?.signal)}async function wn(t,e,n,r,o){let a=`/v1/inventory/${s(e)}/${s(n)}/orders/simulate`;return t.client.post(a,r,o?.signal)}async function kn(t,e,n,r){let o=`/v2/games/${s(t.gameId())}/game-rooms/${s(e)}/transfer/${s(n)}`;return t.client.post(o,void 0,r?.signal)}async function An(t,e,n,r){let o=`/v2/games/${s(t.gameId())}/game-rooms/${s(e)}`;return t.client.patch(o,n,r?.signal,{...r?.ifMatch===void 0?{}:{ifMatch:r.ifMatch}})}var ye="gem_";function fe(t,e){let n=e?.retryAfterSeconds,r=typeof n=="number"&&Number.isFinite(n)&&n>0?n*1e3:0,o=1e4*2**Math.min(Math.max(0,t-1),16);return Math.min(Math.max(r,o),3e5)}var Gn=1e4,Tn=50,Cn=1e3,In=65536-4*1024,he=t=>typeof t=="number"?t:0,En=t=>typeof t=="string"?t:"";function _e(){let t=globalThis.crypto;return typeof t?.randomUUID=="function"?t.randomUUID():"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,e=>{let n=Math.floor(Math.random()*16);return (e==="x"?n:n&3|8).toString(16)})}function Ln(t){return t?.retryable===true}function qn(t,e){let n=t??{},r=Array.isArray(n.rejected)?n.rejected.map(o=>{let a=o??{};return {index:he(a.index),code:En(a.code)}}):[];return {accepted:he(n.accepted),rejected:r,dropped:e,duplicate:n.duplicate===true}}function Re(t,e){return {event_uid:t.uid,name:t.name,offset_ms:Math.round(t.atMs)-e,player_id:t.playerId,dimensions:t.dimensions,measures:t.measures}}function be(t){let e=Math.max(1,Math.floor(t.maxQueue??Cn)),n={client:t.client,gameId:()=>t.gameId},r=[],o=0,a=null,i=false,d=null,u=0,c=0,g=false,S=false,w=_=>{t.log?.(_);},b=()=>{a!==null&&(t.clock.clearTimeout(a),a=null);},y=()=>Math.max(0,c-t.clock.now()),x=()=>{a!==null||i||d!==null||(a=t.clock.setTimeout(()=>{a=null,P().catch(()=>{});},Math.max(Gn,y())));},A=()=>{let _=Math.min(r.length,100),R=128;for(let G=0;G<_;G+=1){let C=r[G];if(C===void 0)break;if(R+=JSON.stringify(Re(C,0)).length+1,R>In)return Math.max(1,G)}return _};async function P(_){for(;d!==null;)await d.catch(()=>{});if(r.length===0)return {accepted:0,rejected:[],dropped:0,duplicate:false};let R=qe(_);d=R;try{return await R}finally{d===R&&(d=null),r.length>0&&x();}}async function qe(_){b();let R=r.splice(0,A()),G=o;o=0;let C=Math.round(t.clock.now()),D={batch_id:_e(),sent_at_ms:C,events:R.map(k=>Re(k,C))};try{let k=await X(n,D,_===void 0?void 0:{signal:_}),I=qn(k,G);u=0,c=0;for(let Me of I.rejected)w(`[gem] analytics: an event was refused (${Me.code}). See the analytics_events section of your game config.`);return I}catch(k){if(Ln(k)){for(r=[...R,...r],o+=G;r.length>e;)r.shift(),o+=1;u+=1,c=t.clock.now()+fe(u,k);}else w(`[gem] analytics: ${R.length} event(s) were discarded \u2014 the platform refused the batch and will refuse it again: ${String(k)}`);throw k}}return {track(_,R,G={}){if(i)return;if(typeof _!="string"||_===""){S||(S=true,w(`[gem] analytics: '${R}' was not recorded \u2014 an event from a server has to name the player it is about. A game-server token names no player, so the platform cannot infer one; pass the id from join() or host.players().`));return}if(R.startsWith(ye)){g||(g=true,w(`[gem] analytics: '${R}' was not recorded \u2014 the gem_ prefix is reserved, and the platform's own events are client-sourced, so a server may not emit one at all. Name your event something else.`));return}let C={},D={};for(let[k,I]of Object.entries(G))typeof I=="string"?C[k]=I:typeof I=="number"&&Number.isFinite(I)&&(D[k]=I);for(;r.length>=e;)r.shift(),o+=1;r.push({uid:_e(),playerId:_,name:R,atMs:t.clock.now(),dimensions:C,measures:D}),r.length>=Tn&&d===null&&y()===0?P().catch(()=>{}):x();},flush:_=>P(_),get pending(){return r.length},dispose(){i=true,b(),r=[],o=0;}}}function Mn(t){return typeof t=="string"&&/^[\w-]{1,64}$/.test(t)}function ve(t,e){if(t===void 0||Mn(t))return t;let n=typeof t=="string"?JSON.stringify(t.slice(0,72)):`a value of type ${typeof t}`;console.warn(`[gem] ${e}: cueId ${n} is not 1 to 64 letters, digits, _ or -, so it was left out. Use one crypto.randomUUID() per award.`);}var $n=new Map([["function_error",false],["function_failed",false],["function_timeout",false],["function_not_published",false],["function_input_too_large",false],["invalid_cue_id",false],["functions_not_configured",false],["forbidden",false],["function_capacity_unavailable",true],["function_host_unreachable",true],["function_host_error",true],["rate_limited",true],["service_unavailable",true]]),F=class extends p{constructor(e,n){super(e.reason,e.status,e.detail,e.retryAfterSeconds,e.code),this.name="GemFunctionError",Object.assign(this,n);}get retryable(){return (this.code===void 0?void 0:$n.get(this.code))??super.retryable}},M=class{#e;constructor(e){this.#e=e;}async invoke(e,n={}){let r=jn(e),o=ve(n.cueId,"functions.invoke"),a;try{a=await this.#e(r,{...n.signal===void 0?{}:{signal:n.signal},...o===void 0?{}:{cue_id:o}});}catch(i){throw i instanceof p?Fn(i):i}return Bn(a)}};function jn(t){if(t instanceof ArrayBuffer)return new Uint8Array(t);if(ArrayBuffer.isView(t))return new Uint8Array(t.buffer,t.byteOffset,t.byteLength);let e;try{e=JSON.stringify(t);}catch(n){throw new f(`the function input could not be serialised to JSON: ${String(n)}. Pass bytes, or a value JSON can carry. This is a bug in the call, not a server failure.`)}if(e===void 0)throw new f(`the function input is ${typeof t}, which JSON cannot carry. Pass bytes \u2014 an empty Uint8Array for no input \u2014 or a JSON value. This is a bug in the call, not a server failure.`);return new TextEncoder().encode(e)}function Bn(t){let{bytes:e}=t,n=()=>new TextDecoder("utf-8",{fatal:true}).decode(e);return {bytes:e,...t.invocationId===void 0?{}:{invocationId:t.invocationId},text:n,json:()=>JSON.parse(n())}}function Fn(t){let{details:e,invocationId:n}=se(t),o=e?.untrusted?.message,a=e?.reason;return new F(t,{...n===void 0?{}:{invocationId:n},...t.code==="function_error"&&typeof o=="string"?{functionMessage:o}:{},...t.code==="function_failed"&&typeof a=="string"?{failure:a}:{}})}var O=t=>typeof t=="string"?t:"",Un=/(?:Z|[+-]\d{2}:?\d{2})$/i;function Se(t){let e=O(t);if(!Un.test(e))return 0;let n=Date.parse(e);return Number.isFinite(n)?Math.floor(n/1e3):0}var Dn=/^[0-9a-f]{1,64}$/,Nn=/^[0-9a-f]{16}$/,Hn=/^[A-Za-z][A-Za-z0-9_+\-/]{0,63}$/,Vn=/^(?:[01]\d|2[0-3]):[0-5]\d$/;function Wn(t){let e=O(t),n=/^(\d{4})-(\d{2})-(\d{2})$/.exec(e);if(!n)return;let[r,o,a]=[Number(n[1]),Number(n[2]),Number(n[3])],i=new Date(Date.UTC(r,o-1,a));return i.getUTCFullYear()===r&&i.getUTCMonth()===o-1&&i.getUTCDate()===a?e:void 0}var zn=4096,Kn=new TextEncoder;function Yn(t){let e=O(t.challenge_data),n=O(t.challenge_data_hash);return e===""||!Nn.test(n)?{}:Kn.encode(e).length>zn?{}:{data:e,dataHash:n}}function Jn(t){let e=t??{},n=Se(e.period_start_at),r=Se(e.period_ends_at);if(n===0||r===0)return;let o=O(e.slug),a=O(e.seed),i=Wn(e.period_local_date),d=O(e.boundary),u=O(e.reset_time);return {id:O(e.progression_definition_id),...o===""?{}:{slug:o},window:O(e.window),periodStartAt:n,periodEndsAt:r,...i===void 0?{}:{periodLocalDate:i},boundary:Hn.test(d)?d:"",resetTime:Vn.test(u)?u:"",seed:Dn.test(a)?a:"",...Yn(e)}}function xe(t){if(t!==void 0&&(!Number.isInteger(t)||t<0||t>400))throw new TypeError(`periodsBack must be an integer between 0 and 400, got ${String(t)}`)}function we(t){let e=t??{};return Array.isArray(e.challenges)?e.challenges.map(Jn).filter(n=>n!==void 0):[]}function ke(t){return {async list(e){let{playerId:n,periodsBack:r,signal:o}=e??{};if(typeof n!="string"||n==="")throw new TypeError("gem.challenges.list needs { playerId }: a game-server token names no player, so the platform cannot tell whose period you mean. Pass the id from join() or gem.players().");xe(r);let a=await t({player_id:n,...r===void 0?{}:{periods_back:r},...o===void 0?{}:{signal:o}});return we(a)}}}function Xn(t){let e={};for(let[n,r]of Object.entries(Q))if(typeof r=="function"){let o=r;e[n]=(...a)=>o(t,...a);}return e}function z(t,e={}){let n=e.clock??q,r=e.baseUrl??t.apiBaseUrl;if(!r)throw new Error("this runtime names no gem-api host (host.apiBaseUrl is missing). The server image running this bundle predates token delivery \u2014 the bundle cannot call gem-api on it.");let o=J(t,{clock:n,...e.onAuthStateChange===void 0?{}:{onStateChange:e.onAuthStateChange}}),a=ie({baseUrl:r,tokenSource:o.source,defaultQuery:{game_id:t.gameId,channel:t.channel},...e.fetch===void 0?{}:{fetch:e.fetch}}),i=new L({transport:a,clock:n}),d={gameId:t.gameId,channel:t.channel,matchId:t.matchId,...t.gameRoomId===void 0?{}:{gameRoomId:t.gameRoomId}},u=Xn({client:i,gameId:()=>d.gameId}),c=d.gameRoomId,g=t.endMatch,S=t.log,w=be({client:i,clock:n,gameId:d.gameId,...typeof S=="function"?{log:y=>S.call(t,y)}:{}});return {identity:d,client:i,api:u,match:{end:async()=>{if(g===void 0)throw new Error("this runtime cannot end the match: the server image running this bundle predates host.endMatch, and only the platform half holds the allocation proof an end needs.");await g.call(t);},setBackfill:async(y,x)=>{let A=await u.setMatchBackfill(d.matchId,{open:y.open,...y.seats===void 0?{}:{seats:y.seats}},x===void 0?{}:{signal:x});return {open:A.open,seats:A.seats??null}},reportPlayers:async(y,x)=>(await u.reportMatchPlayers(d.matchId,{players:y.map(P=>({player_id:P.playerId,state:P.state}))},x===void 0?{}:{signal:x})).players.map(P=>({playerId:P.player_id,outcome:P.outcome}))},analytics:w,functions:new M(u.invokeFunction),challenges:ke(u.listChallenges),...c===void 0?{}:{room:{get:y=>u.getGameRoomV2(c,y),args:async y=>{let x=await u.getGameRoomV2(c,y?.signal===void 0?{}:{signal:y.signal}),A=x.modified?x.body:void 0;if(A?.room_args==null||A.room_args_template==null)throw new p("not_found",404,"this room's template declares no room args",void 0,"room_args_not_defined");return {room_args:A.room_args,room_args_template:A.room_args_template}}}},dispose:()=>{w.dispose(),o.dispose();}}}var Qn=["explicit","stale_cleanup","game_room_closed","replaced","migration_failed","host_left","insufficient_players","all_left","expired","migration_rate_exceeded","game_room_gone","failed","idle","reclaimed"],Zn=new Set(Qn);function Ae(t){return typeof t=="string"&&Zn.has(t)?t:"unknown"}var Ge="[gem: use gem.text.toPlain()]",Oe=new Set,Pe;function er(t){try{if(Oe.has(t))return;let e=globalThis.location;if(Pe??=!!e?.port&&ge(e.hostname??""),!Pe)return;Oe.add(t),console.warn(`[gem] ${t} is PlayerText, turned into a string: players see ${Ge}. Render text.toPlain(value) (text is in @indiegems/gem-web-sdk/sdk).
2
- ${new Error().stack}`);}catch{}}var v=class{#e;#t;constructor(e,n="player text"){this.#e=e,this.#t=n,Object.freeze(this);}toString(){return er(this.#t),Ge}toJSON(){return this.toString()}get[Symbol.toStringTag](){return "PlayerText"}static unwrap(e){return e.#e}};function U(t,e){return new v(t,e)}var Te={toPlain(t){return v.unwrap(t)},compare(t,e,n){let r=t instanceof v?v.unwrap(t):t,o=e instanceof v?v.unwrap(e):e;if(typeof Intl>"u"||typeof Intl.Collator!="function")return r<o?-1:r>o?1:0;let a;try{a=new Intl.Collator(n);}catch{a=new Intl.Collator;}return a.compare(r,o)},equals(t,e){let n=t instanceof v?v.unwrap(t):t,r=e instanceof v?v.unwrap(e):e;return n.normalize("NFC")===r.normalize("NFC")}};var Ce="the match has not started yet: the runtime hands over the host at `init`, and this was read before that. Read it from `init` or later \u2014 a bundle that needs a value at module scope is reading it one call too early.";function Z(t,e={}){let n=e.clock??q,r=()=>{let d=t();if(d===null)throw new Error(Ce);return d},o=null,a=()=>{if(o===null)throw new Error(Ce);return o};return {server:{get identity(){return a().identity},get client(){return a().client},get api(){return a().api},get match(){return a().match},get analytics(){return a().analytics},get functions(){return a().functions},get challenges(){return a().challenges},get room(){return a().room},dispose(){o?.dispose();},get sizeClass(){return r().sizeClass},get roomArgs(){return r().roomArgs},get roster(){return r().roster},players(){return r().players()},profile(d){let c=r().profile?.(d);if(!c)return null;let g=c.displayName;return typeof g!="string"||g===""?null:{displayName:U(g,"profile.displayName"),...typeof c.displayTag=="string"&&c.displayTag!==""?{displayTag:U(c.displayTag,"profile.displayTag")}:{},...typeof c.discriminator=="string"?{discriminator:c.discriminator}:{}}},playerNumber(d){return r().playerNumber?.(d)},send(d,u,c){c===void 0?r().send(d,u):r().send(d,u,c);},broadcast(d,u){u===void 0?r().broadcast(d):r().broadcast(d,u);},kick(d,u){u===void 0?r().kick(d):r().kick(d,u);},log(d){r().log(d);},warn(d){r().warn(d);}},attach:()=>{o=z(r(),{...e,clock:n});}}}function Ie(t,e={}){let{server:n,attach:r}=Z(()=>t,e);return r(),n}function tr(t){if(t===void 0||typeof t.reason!="string"||t.reason==="")return;let e=t.platform_reason??t.endedReason;return {reason:t.reason,...e===void 0?{}:{endedReason:Ae(e)}}}var nr=1e4;function rr(t){let e=false;return n=>{if(e)return;let r;try{r=t.match.reportPlayers([{playerId:n,state:"connected"}],AbortSignal.timeout(nr));}catch{return}r.catch(o=>{o instanceof p&&o.status>=400&&o.status<500&&(e=o.status!==429);});}}function Ee(t,e={}){return ()=>{let n=null,{server:r,attach:o}=Z(()=>n,e),a=t(r),i={async init(u){n=u,o(),await a.init?.();},async shutdown(u){let c=tr(u);try{await a.shutdown?.(c);}finally{r.dispose();}}},d=rr(r);return i.join=(u,c)=>(d(u),a.join?.(u,c)),a.leave&&(i.leave=(u,c)=>a.leave?.(u,c)),a.message&&(i.message=(u,c,g,S)=>a.message?.(u,c,g,S)),i}}var or=new Set(["unlocked","already_unlocked","suppressed"]);function Le(t){let e=t?.changes;if(!Array.isArray(e))return [];let n=[];for(let r of e){let o=r??{};if(o.type!=="achievement_unlocked"||typeof o.outcome!="string"||!or.has(o.outcome)||typeof o.achievement_id!="string"||o.achievement_id==="")continue;let a=o.outcome;n.push({achievementId:o.achievement_id,progressionDefinitionId:typeof o.progression_definition_id=="string"?o.progression_definition_id:"",points:a==="unlocked"&&typeof o.points=="number"&&Number.isFinite(o.points)?o.points:0,outcome:a,...typeof o.reason=="string"?{reason:o.reason}:{}});}return n}export{h as AuthError,H as CONDITIONAL_HEADERS,M as FunctionsApi,p as GemApiError,L as GemClient,F as GemFunctionError,v as PlayerText,f as TransportRefusal,Le as achievementReceipts,U as asPlayerText,z as createGemServer,pe as createHostTokenSource,Ie as createMatchServer,Ee as defineServer,q as systemClock,Te as text,ne as toBase64};//# sourceMappingURL=gem-web-sdk.server.js.map
1
+ var je=Object.defineProperty;var $e=(n,e)=>{for(var t in e)je(n,t,{get:e[t],enumerable:true});};globalThis.__gemWebSdkVersion="[gem-web-sdk:sdkVersion:23.0.0]";var Be={initialDelayMs:2e3,maxDelayMs:6e4};function Fe(n,e){return e!==void 0?!e:n==="chain_exhausted"}var N=class{constructor(e){this.options=e;}options;grant=null;state="pending";failure=null;generation=0;inFlight=null;rejected=false;retry=null;failures=0;notBefore=0;disposed=false;get currentState(){return this.state}get lastFailure(){return this.failure}async get(){if(this.state==="lost")throw new h(this.failure??"unavailable","the session cannot be renewed");let e=this.seconds();if(this.grant&&e<this.grant.expiresAt-this.renewBefore())return this.grant.token;if(this.pastChainCeiling())throw new h("chain_exhausted","the token chain reached its ceiling");if(this.inFlight===null&&this.options.clock.now()<this.notBefore)throw new h(this.failure??"unavailable","the embedder asked for no new token yet; one is asked for when that wait is over");return this.refresh(this.nextReason())}pastChainCeiling(){return this.grant===null||this.seconds()<this.grant.chainEndsAt?false:(this.enter("lost","chain_exhausted"),true)}nextReason(){return this.rejected?"rejected":this.grant?"expiring":"initial"}invalidate(e){e!==void 0&&this.grant!==null&&this.grant.token!==e||this.rejected&&this.grant===null||(this.grant=null,this.generation+=1,this.inFlight=null,this.rejected=true,this.state!=="lost"&&this.enter("pending"));}accept(e){this.state!=="lost"&&(this.grant=e,this.rejected=false,this.enter("ready"));}close(e="unavailable"){this.grant=null,this.generation+=1,this.inFlight=null,this.enter("lost",e);}dispose(){this.disposed=true,this.cancelRetry();}scheduleRetry(e){if(this.cancelRetry(),this.failures+=1,this.notBefore=e===void 0?0:this.options.clock.now()+e,this.disposed)return;let{initialDelayMs:t,maxDelayMs:r}=Be,o=Math.min(r,t*2**(this.failures-1)),a=Math.max(o/2,e??0)+Math.random()*(o/2);this.retry={handle:this.options.clock.setTimeout(()=>this.retryNow(),a)};}retryNow(){this.retry=null,this.notBefore=0,!(this.state==="lost"||this.pastChainCeiling())&&this.refresh(this.nextReason()).catch(()=>{});}cancelRetry(){this.retry!==null&&(this.options.clock.clearTimeout(this.retry.handle),this.retry=null);}refresh(e){if(this.inFlight)return this.inFlight;this.cancelRetry();let t=this.generation;this.enter("pending");let r=this.options.request(e).then(o=>{if(t!==this.generation)throw new h("internal","token arrived for a superseded generation");return this.grant=o,this.rejected=false,this.enter("ready"),o.token}).catch(o=>{let a=Ue(o),{retryable:i,retryAfterMs:d}=o??{};throw t===this.generation&&(Fe(a,typeof i=="boolean"?i:void 0)?this.enter("lost",a):(this.scheduleRetry(typeof d=="number"&&Number.isFinite(d)&&d>0?d:void 0),this.enter("degraded",a))),o instanceof h?o:new h(a,String(o))}).finally(()=>{this.inFlight===r&&(this.inFlight=null);});return this.inFlight=r,r}enter(e,t){(e==="ready"||e==="lost")&&this.cancelRetry(),e==="ready"&&(this.failures=0,this.notBefore=0),this.failure=t??(e==="ready"?null:this.failure),this.state!==e&&(this.state=e,this.options.onStateChange?.(e,t));}renewBefore(){return this.options.renewBeforeSeconds??60}seconds(){return Math.floor(this.options.clock.now()/1e3)}},h=class n extends Error{constructor(t,r){super(`auth ${t}: ${r}`);this.reason=t;this.name="AuthError";}reason;static isAuthError(t){if(t instanceof n)return true;let r=t;return r?.name==="AuthError"&&typeof r.reason=="string"}};function Ue(n){if(n instanceof h)return n.reason;let e=n?.reason;return typeof e=="string"&&["chain_exhausted","unavailable","timeout","internal"].includes(e)?e:"internal"}var f=class n extends Error{retryable=false;constructor(e){super(e),this.name="TransportRefusal";}static isRefusal(e){if(e instanceof n)return true;let t=e;return t?.name==="TransportRefusal"&&t.retryable===false}},H=["if-match","if-none-match"],ee=4096;function De(n){if(!n)return;let e={};for(let[t,r]of Object.entries(n)){let o=t.toLowerCase();if(!H.includes(o)||r===void 0)continue;let a=typeof r=="string"?Ne(r):r;if(typeof a!="string"||a.length>ee||!He(a))throw new f(`the ${o} header value cannot be sent \u2014 it is not a string, is longer than ${ee} characters, or contains a character outside the range an HTTP header value may carry. This is a malformed request, not a server failure; the value is withheld here rather than written to logs.`);a!==""&&(e[o]=a);}return Object.freeze(e)}function Ne(n){let e=o=>o===32||o===9||o===10||o===13,t=0,r=n.length;for(;t<r&&e(n.charCodeAt(t));)t++;for(;r>t&&e(n.charCodeAt(r-1));)r--;return n.slice(t,r)}function He(n){for(let e=0;e<n.length;e++){let t=n.charCodeAt(e);if(t!==9&&(t<32||t===127||t>255))return false}return true}function Ve(n){let{bytes:e}=n;if(e!==void 0){if(Object.prototype.toString.call(e)!=="[object Uint8Array]")throw new f("the raw body is not a Uint8Array, so it cannot be sent as bytes. This is a malformed request, not a server failure.");if(n.body!==void 0)throw new f("the request carries both a JSON body and a raw body, and only one can be sent. This is a malformed request, not a server failure.");return new Uint8Array(e)}}function ne(n,e){let t=e.replayUnauthorizedOnce??true;return {async request(r){let o={...r},a=De(o.headers),i=Ve(o),d=Object.freeze({...o,headers:a,...i===void 0?{}:{bytes:i}}),u=await e.tokenSource.get(),c=await n(d,u);if(c.status!==401||!t)return c;e.tokenSource.invalidate(u);let g=await e.tokenSource.get(),S=await n(d,g);if(S.status===401)throw e.tokenSource.close("unavailable"),new h("unavailable","the server refused a freshly minted token");return S}}}function te(n){let e=typeof n=="string"?new TextEncoder().encode(n):n;return btoa(We(e))}function We(n){let t="";for(let r=0;r<n.length;r+=32768)t+=String.fromCharCode(...n.subarray(r,r+32768));return t}var p=class extends Error{constructor(t,r,o,a,i){super(`${t} (${r}): ${o}`);this.reason=t;this.status=r;this.detail=o;this.retryAfterSeconds=a;this.code=i;this.name="GemApiError";}reason;status;detail;retryAfterSeconds;code;get retryable(){return this.reason==="unavailable"||this.reason==="rate_limited"}},ae=new WeakMap;function se(n){return ae.get(n)??{}}var ze=new Set([408,429,500,502,503,504]),Ke=6e4,Ye=new WeakMap;function re(n){return n!==null&&(n.reason==="rate_limited"||n.retryAfterSeconds!==void 0)}function Je(n){if(n===void 0)return 2;if(!Number.isInteger(n)||n<0||n>10)throw new f(`maxRetries must be a whole number between 0 and 10; received ${JSON.stringify(n)}. This is a configuration fault, not a server failure.`);return n}var q=class{constructor(e){this.options=e;}options;async get(e,t){return this.send({method:"GET",path:e,signal:t},true)}async getWithEtag(e,t={}){let r=await this.sendRaw({method:"GET",path:e,...t.signal===void 0?{}:{signal:t.signal},...t.ifNoneMatch===void 0?{}:{headers:{"if-none-match":t.ifNoneMatch}}},true),o=r.etag===void 0?{}:{etag:r.etag};return r.status===304?{modified:false,...o}:{modified:true,body:r.body,...o}}async put(e,t,r,o={}){return this.send({method:"PUT",path:e,body:t,signal:r,...j(o)},o.replaySafe===true,o.retryRateLimited!==false)}async post(e,t,r,o={}){return this.send({method:"POST",path:e,body:t,signal:r,...j(o)},o.replaySafe===true,o.retryRateLimited!==false)}async postBytes(e,t,r,o={}){let a=await this.sendRaw({method:"POST",path:e,bytes:t,responseType:"bytes",signal:r,...j(o)},o.replaySafe===true,o.retryRateLimited!==false);return {bytes:Xe(a.body),...a.invocationId===void 0?{}:{invocationId:a.invocationId}}}async patch(e,t,r,o={}){return this.send({method:"PATCH",path:e,body:t,signal:r,...j(o)},o.replaySafe===true,o.retryRateLimited!==false)}async delete(e,t,r={}){return this.send({method:"DELETE",path:e,signal:t,...j(r)},r.replaySafe===true,r.retryRateLimited!==false)}async send(e,t,r=true){return (await this.sendRaw(e,t,r)).body}async sendRaw(e,t,r=true){let o=t?Je(this.options.maxRetries)+1:1,a=null;if(e.signal?.aborted)throw oe(e.signal);let i=e.signal===void 0?void 0:Ye.get(e.signal);for(let d=0;d<o;d++){if(d>0){let g=this.backoffMs(d,a);if(re(a)&&i!==void 0&&g>=i())throw a;await this.backoff(g,e.signal);}if(e.signal?.aborted)throw re(a)&&i!==void 0&&i()<=0?a:oe(e.signal);let u;try{u=await this.options.transport.request(e);}catch(g){if(h.isAuthError(g)||f.isRefusal(g)||e.signal?.aborted||Qe(g))throw g;a=new p("unavailable",0,String(g));continue}if(u.status>=200&&u.status<300||u.status===304)return u;let c=Ze(u);if(!ze.has(u.status)||u.status===429&&!r)throw c;a=c;}throw a??new p("unavailable",0,"no attempt was made")}backoffMs(e,t){let r=t?.retryAfterSeconds,o=r!==void 0?r*1e3:2**(e-1)*250,a=2**(e-1)*250;return Math.min(Math.max(o,a),Ke)}backoff(e,t){return t?.aborted?Promise.resolve():new Promise(r=>{let o=this.options.clock,a=false,i=false,d,u=()=>{a||(a=true,i&&o.clearTimeout(d),t?.removeEventListener("abort",u),r());};t?.addEventListener("abort",u,{once:true}),d=o.setTimeout(u,e),i=true,a&&o.clearTimeout(d);})}};function Xe(n){if(n instanceof Uint8Array)return n;if(n==null)return new Uint8Array(0);let e=typeof n=="string"?n:JSON.stringify(n);return new TextEncoder().encode(e)}function j(n){return {...n.keepalive===void 0?{}:{keepalive:n.keepalive},...n.ifMatch===void 0?{}:{headers:{"if-match":n.ifMatch}}}}function oe(n){return n.reason!==void 0?n.reason:new DOMException("The operation was aborted.","AbortError")}function Qe(n){let e=n?.name;return e==="AbortError"||e==="TimeoutError"}function Ze(n){let e=nn(n),t=rn(n.body),r={...t===void 0?{}:{details:t},...n.invocationId===void 0?{}:{invocationId:n.invocationId}};return Object.keys(r).length>0&&ae.set(e,r),e}var en=new Map([["insufficient_funds","insufficient_funds"]]);function nn(n){let{status:e,body:t}=n,r=tn(t),o=n.retryAfterSeconds??an(t),a=on(t),i=a===void 0?void 0:en.get(a);if(i!==void 0)return new p(i,e,r,void 0,a);switch(e){case 304:return new p("not_modified",e,r);case 400:case 422:return new p("invalid",e,r,void 0,a);case 403:return new p("forbidden",e,r,void 0,a);case 404:return new p("not_found",e,r,void 0,a);case 402:return new p("insufficient_funds",e,r,void 0,a);case 409:return new p("conflict",e,r,void 0,a);case 412:return new p("precondition_failed",e,r,void 0,a);case 413:return new p("too_large",e,r,void 0,a);case 429:return new p("rate_limited",e,r,o,a);default:return new p("unavailable",e,r,o,a)}}function tn(n){if(typeof n=="string")return n;let e=n?.message;if(typeof e=="string")return e;let t=n?.error;if(typeof t=="string")return t;let r=t?.message;return typeof r=="string"?r:"no detail"}function rn(n){let t=n?.error?.details;return t===null?void 0:t}function on(n){let t=n?.error?.code;return typeof t=="string"&&t.length>0?t:void 0}function an(n){let e=n?.retryAfterSeconds;return typeof e=="number"&&Number.isFinite(e)&&e>=0?e:void 0}function sn(n){let e=n.lastIndexOf("@");return (e===-1?n:`***@${n.slice(e+1)}`).slice(0,200)}var ln=new Set(H);function dn(n){if(!n)return {};let e={};for(let[t,r]of Object.entries(n))ln.has(t.toLowerCase())&&(e[t.toLowerCase()]=r);return e}function ie(n){let e=n.fetch??globalThis.fetch.bind(globalThis);return ne(async(t,r)=>{let o;try{o=new URL(n.baseUrl.replace(/\/+$/,""));}catch{throw new f("the configured baseUrl is not a valid URL. Its value is withheld here rather than written to logs. This is a configuration fault, not a server failure.")}let a;try{a=new URL(o.href.replace(/\/+$/,"")+t.path);}catch{throw new f(`${JSON.stringify(typeof t.path=="string"?sn(t.path):"(a non-string path)")} does not form a valid URL against ${o.protocol}//${o.host}. This is a malformed request, not a server failure.`)}if(a.protocol!==o.protocol||a.host!==o.host)throw new f(`${JSON.stringify(a.pathname)} resolves to ${a.protocol}//${a.host}, not ${o.protocol}//${o.host}. A request path may not change the request's origin \u2014 it carries the play token.`);if(a.username!==""||a.password!==""){let b=o.username!==""||o.password!=="",y=a.username!==o.username||a.password!==o.password,x=b?y?"baseUrl (and possibly the request path)":"baseUrl":"request path";throw new f(`the ${x} puts credentials in the URL, which cannot be fetched (${t.method} ${a.pathname}). The value is withheld here rather than written to logs. This is a malformed request, not a server failure.`)}for(let[b,y]of Object.entries(n.defaultQuery??{}))a.searchParams.has(b)||a.searchParams.set(b,y);let i=t.bytes,d=t.bytes===void 0?void 0:"application/octet-stream";try{t.body!==void 0&&(i=JSON.stringify(t.body),d="application/json");}catch(b){throw new f(`the body of ${t.method} ${JSON.stringify(a.pathname)} could not be serialised to JSON: ${String(b)}. This is a bug in the request, not a server failure \u2014 retrying sends the same unserialisable value.`)}let u=await e(a.toString(),{method:t.method,headers:{authorization:`Bearer ${r}`,...d===void 0?{}:{"content-type":d},...dn(t.headers)},body:i,signal:t.signal,...t.keepalive===void 0?{}:{keepalive:t.keepalive},credentials:"omit",mode:"cors",redirect:"error",cache:"no-store",referrerPolicy:"no-referrer"}),c=null;if(t.responseType==="bytes"&&u.status>=200&&u.status<300)c=new Uint8Array(await u.arrayBuffer());else {let b=await u.text();if(b.length>0)try{c=JSON.parse(b);}catch{c=b;}}let g=u.headers.get("etag"),S=un(u.headers.get("retry-after")),w=u.headers.get("x-gem-invocation-id");return {status:u.status,body:c,...g===null?{}:{etag:g},...S===void 0?{}:{retryAfterSeconds:S},...w===null||w===""?{}:{invocationId:w}}},n)}function un(n){if(n===null)return;let e=n.trim();if(!/^\d+$/.test(e))return;let t=Number(e);return Number.isFinite(t)?t:void 0}var cn="gem-web-bridge";var mn=65536,le=8,V=5e3,de=1024;var W=Object.create(null);var ue=Object.create(null);function gn(n){let e=/^([a-z][a-z0-9+.-]*):\/\/([a-z0-9.-]+|\[[0-9a-f:.]+\])(:([0-9]{1,5}))?$/i.exec(n);return e===null?false:e[4]===void 0||Number(e[4])<=65535}function pn(n){let e;try{e=new URL(n);}catch{return false}return e.username!==""||e.password!==""?false:e.protocol==="https:"?true:e.protocol==="http:"&&(e.hostname==="localhost"||e.hostname==="127.0.0.1")}function yn(n){return /^[a-z]{2,8}(-[a-z0-9]{1,8})*$/i.test(n)}function fn(n){return /^[a-z_]+$/.test(n)}function hn(n){return /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(n)||/^[a-z0-9][a-z0-9-]{1,38}[a-z0-9]$/.test(n)&&!n.includes("--")}function K(n,e,t){if(e>le)return `nesting deeper than ${le}`;if(++t.nodes>V)return `more than ${V} values`;if(t.bytes>t.cap)return `over the ${t.cap} byte limit`;if(n==null)return t.bytes+=4,null;let r=typeof n;if(r==="boolean")return t.bytes+=5,null;if(r==="number")return t.bytes+=8,null;if(r==="string")return t.bytes+=n.length*3+2,null;if(r!=="object")return `${r} is not plain data`;let o=n;if(t.seen.has(o))return "a repeated or cyclic object reference";if(t.seen.add(o),Array.isArray(n)){if(n.length>de)return `an array of ${n.length} entries, over the ${de} limit`;t.bytes+=2;for(let d of n){let u=K(d,e+1,t);if(u)return u}return null}let a=Object.getPrototypeOf(n);if(a!==Object.prototype&&a!==null)return "a value that is not a plain object";t.bytes+=2;let i=n;for(let d in i){if(!Object.prototype.hasOwnProperty.call(i,d))continue;if(++t.nodes>V)return `more than ${V} values`;if(t.bytes+=d.length*3+4,t.bytes>t.cap)return `over the ${t.cap} byte limit`;let u=K(i[d],e+1,t);if(u)return u}return null}function _n(n,e=mn){let t={nodes:0,bytes:0,seen:new Set,cap:e},r=K(n,0,t);return r?`message contains ${r}`:t.bytes>e?`message is over the ${e} byte limit`:null}var Rn={origin:[gn,"not a well-formed origin"],url:[pn,"not a safe absolute http(s) URL"],bcp47:[yn,"not a well-formed BCP 47 tag"],code:[fn,"not a code of lower-case letters and underscores"],gameRef:[hn,"not a game id or web address"]};function ce(n,e,t){for(let r of e){let o=t===""?r[0]:`${t}.${r[0]}`,a=n[r[0]];if(a==null){if(r[1]<"a")continue;return `${o}: required`}let i=Y(a,r,o);if(i)return i}return null}function Y(n,e,t){let r=e[1].toLowerCase();switch(r){case "u":return typeof n=="boolean"?null:Y(n,typeof n=="string"?[e[0],"s",e[2]]:[e[0],"n",e[3],e[4]],t);case "s":{if(typeof n!="string")return `${t}: expected string`;if(n.length>e[2])return `${t}: exceeds ${e[2]} characters`;if(e[3]){let[o,a]=Rn[e[3]];if(!o(n))return `${t}: ${a}`}return null}case "n":case "i":return typeof n!="number"||!(r=="i"?Number.isInteger:Number.isFinite)(n)?`${t}: expected ${r=="i"?"integer":"number"}`:n<e[2]||n>e[3]?`${t}: out of range ${e[2]}..${e[3]}`:null;case "b":return typeof n=="boolean"?null:`${t}: expected boolean`;case "e":{let o=e[2];return o.includes(n)?null:`${t}: not one of ${o.join("|")}`}case "o":return typeof n!="object"||n===null||Array.isArray(n)?`${t}: expected object`:ce(n,e[2],t);case "j":return typeof n!="object"||n===null||Array.isArray(n)?`${t}: expected a plain object`:null;case "a":{if(!Array.isArray(n))return `${t}: expected array`;if(n.length>e[2])return `${t}: exceeds ${e[2]} items`;let o=e[3],a=`${t}[]`;for(let i of n){if(i==null){if(o[1]<"a")continue;return `${a}: required`}let d=Y(i,o,a);if(d)return d}return null}default:return `${t}: unknown kind ${String(r)}`}}var me=Object.create(null);function l(n,e,t,r,o){return W[n]=t,r&&(ue[n]=r),me[n]=a=>{let i=_n(a,o);if(i)return i;if(typeof a!="object"||a===null||Array.isArray(a))return "message: expected object";let d=a;return d.gem!==cn?"gem: wrong protocol marker":d.type!==n?`type: expected ${n}`:ce(d,e,"")}}var $=["","s",64],m=["requestId","s",64],B=["matchId","s",64],T=["reason","S",64,"code"],E=["outcome","e",["ok","declined","unavailable"]];l("gem.handshake",[["versions","o",[["min","i",1,1e3],["max","i",1,1e3]]],["capabilities","A",64,$],["embedder","s",2048,"origin"],["unbidden","B"]],30);l("gem.handshake.accept",[["v","i",1,1e3],["capabilities","A",64,$]],5);l("gem.token",[["token","s",4096],["requestId","S",64],["generation","i",0,2147483647],["apiBaseUrl","S",512,"url"],["playerId","s",64],["gameId","s",64],["channel","e",["dev","test","release"]],["gameVersion","S",64],["expiresAt","i",0,4102444800],["chainEndsAt","i",0,4102444800],["allowDevTools","B"]],30);l("gem.token.denied",[m,["retryable","b"],["retryAfterMs","I",0,36e5],["reason","e",["chain_exhausted","unavailable"]],["correlationId","s",64]],30);l("gem.player",[["untrusted","o",[["displayName","s",64],["displayTag","S",80],["displayHandle","s",80]]],["playerId","S",64],["discriminator","S",8],["avatarIconUrl","S",2048,"url"],["avatarIconId","S",64],["avatar3dId","S",64],["avatar3dModelUrl","S",2048,"url"],["avatar3dIconUrl","S",2048,"url"],["avatars3d","A",8,["","o",[["family","s",32],["id","s",64],["modelUrl","s",256,"url"],["iconUrl","s",256,"url"]]]],["badges","A",2,["","o",[["itemId","s",64],["iconUrl","s",2048,"url"]]]],["displayTag","s",8],["avatarUrl","S",2048,"url"],["boost","O",[["multipliers","a",8,["","o",[["currencyId","s",64],["currencySlug","s",32],["multiplierBp","i",1e4,1e6]]]],["expiresInDays","I",1,7]]]],12);l("gem.pause",[["paused","b"]],120);l("gem.prefs",[["reducedMotion","b"],["muted","b"],["showFrameStats","B"],["music","B"],["sounds","B"],["locale","s",35,"bcp47"],["recommended","O",[["volume","i",0,100],["batterySaver","b"],["keyboardLayout","e",["wasd","arrows"]],["gamepadConfirm","e",["south","east"]],["vibration","b"],["lookSensitivity","I",20,400],["gamepadLookSensitivity","I",20,400],["invertLookY","B"],["touchMovement","S",16,"code"],["graphicsQuality","S",16,"code"],["graphicsQualityAuto","B"],["colorHelp","B"]]]],60);l("gem.cohorts",[["cohorts","a",8,["","o",[["experimentId","s",36],["variantKey","s",32]]]]],12,"cohorts");l("gem.earnAllowanceChanged",[],30,"earnAllowance");l("gem.inventoryChanged",[],30,"inventoryChanged");l("gem.viewport",[["insets","o",[["top","i",0,4096],["right","i",0,4096],["bottom","i",0,4096],["left","i",0,4096]]],["reserved","A",4,["","o",[["x","i",0,16384],["y","i",0,16384],["width","i",0,16384],["height","i",0,16384],["control","O",[["x","i",0,16384],["y","i",0,16384],["width","i",0,16384],["height","i",0,16384]]]]]]],60,"viewport");l("gem.deviceSettings",[["settings","J"]],12,"deviceSettings");l("gem.willTerminate",[["reason","e",["grant_expiring","session_ended","navigating","kill_switch"]],["graceMs","i",0,6e4]],10);l("gem.roomEvent",[["event","e",["updated","match_started","match_ready","match_failed","version_stale"]],["roomId","s",64],["matchId","S",64],["version","I",0,2147483647],["reason","S",64],["platform","E",["universal","mobile"]]],120,"rooms");l("gem.socketState",[["connected","b"],["reason","E",["connecting","dropped","watchdog","terminal"]]],12,"socketState");l("gem.seatedEvent",[["roomId","s",64]],60,"partySeating");l("gem.autoStartFailedEvent",[["roomId","s",64],["code","s",64]],30,"autoStartFailure");l("gem.ticketEvent",[["event","e",["queued","matched","expired","cancelled","failed"]],["ticketId","s",64],["partySize","I",1,64],["queuedAt","I",0,4102444800],["expiresAt","I",0,4102444800],["reason","S",64],["roomId","S",64]],60,"ticketEvents");l("gem.signalEvent",[["event","e",["hello","offer","answer","ice","peerJoined","peerLeft","migration","matchEnded","error"]],B,["data","j"]],1800,"p2p");l("gem.relayDraining",[B,["clusterTargetId","s",64],["relayIps","a",16,$],["drainingSince","s",40],["deadline","s",40]],60,"p2pRelayDrain");l("gem.dedicatedEvent",[["event","e",["answer","error","matchEnded"]],B,["sdp","S",10240],["sessionId","S",64],["code","S",64],["message","S",256],["reason","S",64]],120,"dedicated");l("gem.partyResult",[m,["partyId","S",64]],30,"parties");l("gem.clusterTarget",[["clusterTargetId","s",64],["clusterTargetIds","A",3,$]],12,"clusterTarget");l("gem.graphicsRoutes",[["entries","a",32,["","o",[["gpu","s",32],["route","S",32],["host","S",32]]]]],12,"graphicsRoutes");l("gem.devtools",[["action","e",["open","close","toggle"]]],30,"devtools");l("gem.screenshot",[["maxWidth","i",1,7680],["maxHeight","i",1,4320]],6,"screenshot");l("gem.screenshot.denied",[["reason","e",["not_wired","no_source","unsupported","unreadable","tainted","too_large","busy","declined","failed"]],["retryable","b"]],12,"screenshot");l("gem.requestContext",[],12,"feedbackContext");l("gem.gameContext",[["context","j"]],12,"feedbackContext");l("gem.signal",[["signal","e",["join","offer","answer","ice","migrationAck","hostUnreachable"]],B,["data","j"]],1200,"p2p");l("gem.dedicatedOffer",[B,["sdp","s",10240],["intent","e",["initial","ice_restart","full_reconnect"]]],60,"dedicated");l("gem.partyRequest",[m],12,"parties");l("gem.ready",[],5);l("gem.engaged",[],5,"engagement");l("gem.progress",[["loaded","i",0,1099511627776],["total","i",0,1099511627776]],600);l("gem.requestToken",[m,["reason","e",["initial","expiring","rejected"]]],12);l("gem.requestLocalServer",[m,["gameRoomId","s",64]],6,"localHost");l("gem.localServer",[m,["serverId","S",128]],30,"localHost");l("gem.localServer.denied",[m,["retryable","b"],["reason","e",["refused","unavailable"]]],30,"localHost");l("gem.exit",[["reason","S",64]],5);l("gem.openExternal",[["url","s",2048,"url"]],6);l("gem.requestFullscreen",[["enabled","b"]],30);l("gem.audioState",[["muted","b"]],120,"audioState");l("gem.rewardCue",[["currencySlug","s",32],["cueId","S",64],["expected","I",1,1e9],["origin","O",[["x","i",0,16384],["y","i",0,16384]]]],60,"rewardCue");l("gem.rewardPresentation",[["mode","e",["arcade","game"]]],12,"rewardPresentation");l("gem.walletDisplay",[["visible","b"],["currencies","A",8,$],["score","B"]],60,"walletDisplay");l("gem.controlsDeclare",[["uses","o",[["lookSensitivity","S",16,"code"],["gamepadLookSensitivity","S",16,"code"],["invertLookY","S",16,"code"],["touchMovement","S",16,"code"]]]],60,"controls");l("gem.menu",[["settings","b"],["items","A",4,["","o",[["id","s",32],["label","s",40]]]]],60,"gameMenu");l("gem.menuSelect",[["entry","e",["settings","item"]],["id","S",32]],60,"gameMenu");l("gem.gemCorner",[["corner","e",["top-left","top-right","bottom-left","bottom-right"]]],12,"gemCorner");l("gem.menuStyle",[["ground","S",7],["accent","S",7]],12,"menuStyle");l("gem.settingsDeclare",[["settings","a",8,["","o",[["id","s",40],["label","s",40],["kind","e",["toggle","slider","choice"]],["value","u",40,-1e6,1e6],["quick","B"],["icon","S",16,"code"],["min","N",-1e6,1e6],["max","N",-1e6,1e6],["step","N",0,1e6],["options","A",4,["","o",[["id","s",40],["label","s",40]]]]]]]],120,"gameSettings");l("gem.settingChange",[["id","s",40],["value","u",40,-1e6,1e6]],120,"gameSettings");l("gem.requestShare",[["requestId","S",64],["params","a",16,["","o",[["key","s",64],["value","s",512]]]]],6,"share");l("gem.shareResult",[m,["outcome","e",["accepted","refused"]],T,["key","S",64]],30,"shareResult");l("gem.requestAvatarPicker",[["tab","E",["2d","3d"]]],6,"avatarPicker");l("gem.vibrate",[["pattern","a",99,["","i",0,1e4]]],600,"vibration");l("gem.frameStats",[["fps","i",0,1e3],["frameTimeP95Ms","i",0,1e5],["counts","E",["pageFrames","gameDraws"]]],120,"frameStats");l("gem.portraitBorders",[["name","S",40]],60,"portraitBorders");l("gem.error",[["code","e",["version_mismatch","handshake_timeout","handshake_duplicate","invalid_message","rate_limited","token_unavailable","unsupported","unsupported_capability","internal"]],["message","S",256]],60);l("gem.requestPurchase",[m,["purchaseKind","e",["item","recipe"]],["targetId","s",64],["currencySlug","s",32],["quantity","I",1,10],["catalogId","S",64],["origin","E",["sheet","direct_refused"]]],12,"purchases");l("gem.requestAvatar3dPurchase",[m,["itemId","s",64],["currencySlug","s",32]],12,"avatar3dPurchases");l("gem.purchaseResult",[m,E,T,["purchaseId","S",64]],30,"purchases");l("gem.purchaseSettled",[["purchaseKind","e",["item","recipe"]],["targetId","s",64],["catalogId","S",64],["quantity","i",1,10],["purchaseId","S",64]],30,"purchaseSettled");l("gem.deviceSettings.put",[m,["settings","j"]],30,"deviceSettings");l("gem.deviceSettings.result",[m,["outcome","e",["stored","too_large","unavailable"]]],30,"deviceSettings");l("gem.requestAd",[m,["placement","s",32],["format","e",["interstitial","rewarded"]]],6,"ads");l("gem.adResult",[m,["outcome","e",["shown","no_ad","unavailable"]]],12,"ads");l("gem.signalMoment",[m,["kind","e",["level_end","run_end","match_end","menu_return","other_break"]],["placement","S",32],["wall","B"]],6,"moments");l("gem.momentResult",[m,["shown","b"]],12,"moments");l("gem.requestSignIn",[m],6,"signIn");l("gem.signInResult",[m,["outcome","e",["signed_in","declined","unavailable"]]],12,"signIn");l("gem.requestFriendChallenge",[m,["playerId","s",64],["template","s",64],["params","J"]],12,"friendChallenges");l("gem.friendChallengeResult",[m,["outcome","e",["accepted","cancelled","refused","unavailable","rate_limited","invalid"]],["code","S",64],["param","S",64],["channel","S",16],["configVersion","I",0,9007199254740991],["retryAfterMs","I",0,864e5],["detail","S",300]],30,"friendChallenges");l("gem.requestPlayInvite",[m,["params","A",16,["","o",[["key","s",64],["value","s",512]]]]],6,"playInvites");l("gem.playInviteResult",[m,["shown","b"]],12,"playInvites");l("gem.inviteParams",[["params","A",16,["","o",[["key","s",64],["value","s",512]]]]],30,"playInvites");l("gem.requestAppLinks",[m],12,"appLinks");l("gem.appLinksResult",[m,E,T,["arcade","O",[["store","e",["app_store","google_play"]]]],["game","O",[["store","e",["app_store","google_play"]]]]],30,"appLinks");l("gem.requestOpenApp",[m,["target","e",["arcade","game"]]],6,"appLinks");l("gem.openAppResult",[m,E,T],30,"appLinks");l("gem.requestOpenGame",[m,["ref","s",40,"gameRef"]],6,"openGame");l("gem.openGameResult",[m,E,T],30,"openGame");l("gem.requestSimilarGames",[m,["limit","I",1,24]],12,"openGame");l("gem.similarGamesResult",[m,E,T,["games","a",24,["","o",[["gameId","s",36,"gameRef"],["slug","S",40,"gameRef"],["iconUrl","s",1024,"url"],["capsuleLandscapeUrl","s",1024,"url"],["capsulePortraitUrl","s",1024,"url"],["previewVideoUrl","S",1024,"url"],["previewPosterUrl","S",1024,"url"],["untrusted","o",[["name","s",64],["tagline","s",64],["shortDescription","s",320],["tags","a",10,["","s",32]]]]]]]],30,"openGame",524288);l("gem.requestStoreOffers",[m],12,"store");l("gem.storeOffersResult",[m,E,T,["offers","a",32,["","o",[["skuId","s",64],["kind","e",["gem_pack","boost","pass","bundle"]],["name","s",80],["description","s",400],["imageUrl","S",1024,"url"],["priceDisplay","s",32],["grant","O",[["currency","s",32],["amount","i",1,1e9]]]]]]],30,"store",262144);l("gem.requestStorePurchase",[m,["skuId","s",64]],12,"store");l("gem.storePurchaseResult",[m,E,T],30,"store");l("gem.storePurchaseSettled",[["skuId","s",64]],30,"store");l("gem.requestStoreOfferSheet",[m,["skuId","s",64]],12,"storeOfferSheet");l("gem.storeOfferSheetResult",[m,E,T],30,"storeOfferSheet");Object.freeze(me);W.__malformed=60;Object.freeze(W);Object.freeze(ue);var L={now:()=>Date.now(),setTimeout:(n,e)=>setTimeout(n,e),clearTimeout:n=>clearTimeout(n)};function ge(n){let e=n.toLowerCase();return e==="localhost"||e.endsWith(".localhost")||e==="[::1]"||e==="::1"?true:/^127(\.\d{1,3}){3}$/.test(e)}var bn=1e4;function pe(n,e){return J(n,e)}function J(n,e){if(typeof n.serverToken!="function"||typeof n.onServerToken!="function")throw new Error("this runtime delivers no game-server token: host.serverToken/onServerToken are missing. The server image running this bundle predates token delivery \u2014 the bundle cannot call gem-api on it.");let t=i=>({token:i.token,expiresAt:i.expiresAt,chainEndsAt:Number.POSITIVE_INFINITY}),r=null,o=new N({clock:e.clock,...e.onStateChange===void 0?{}:{onStateChange:e.onStateChange},request:()=>new Promise((i,d)=>{let u=e.clock.setTimeout(()=>{r=null,d({reason:"unavailable",retryable:true});},e.timeoutMs??bn);r={resolve:c=>{e.clock.clearTimeout(u),i(c);},reject:d,timer:u};})}),a=n.onServerToken(i=>{let d=t(i),u=r;if(u){r=null,u.resolve(d);return}o.accept(d);});return {source:o,dispose(){a(),o.dispose(),r&&(e.clock.clearTimeout(r.timer),r.reject({reason:"unavailable",retryable:false}),r=null);}}}var Q={};$e(Q,{acceptTransfer:()=>vn,addEntityProgression:()=>Sn,adminAction:()=>xn,cancelInventoryTransfer:()=>wn,claimEntityProgressionRewards:()=>kn,closeGameRoom:()=>An,createEntityBatchOrder:()=>On,createEntityOrder:()=>Pn,createSession:()=>Gn,deleteEntityGameSetting:()=>Tn,deleteEntitySave:()=>Cn,deleteSession:()=>In,deleteShowcaseValue:()=>En,executeEntityRecipe:()=>qn,finalizeSaveUpload:()=>Ln,getChannelAssignment:()=>Mn,getDropRates:()=>jn,getEntityCurrency:()=>$n,getEntityGameSetting:()=>Bn,getEntityInventory:()=>Fn,getEntityInventoryItem:()=>Un,getEntityLeaderboard:()=>Dn,getEntityOrder:()=>Nn,getEntityProgression:()=>Hn,getEntityRecipeAvailability:()=>Vn,getEntityRecipeUsage:()=>Wn,getEntitySave:()=>zn,getEvent:()=>Kn,getGameRoomV2:()=>Yn,getLeaderboard:()=>Jn,getPlayerGameProfile:()=>Xn,getPurchaseCatalog:()=>Qn,getResolvedTemplate:()=>Zn,getRoomArgs:()=>et,getShowcaseValue:()=>nt,getTransferDetails:()=>tt,ingestAnalyticsEvents:()=>X,initiateInventoryTransfer:()=>rt,invokeFunction:()=>ot,kickPlayer:()=>at,listChallenges:()=>st,listEntityGameSettings:()=>it,listEntityOrders:()=>lt,listEntityProgressions:()=>dt,listEntitySaves:()=>ut,listEvents:()=>ct,listGameRooms:()=>mt,listResolvedTemplates:()=>gt,listTransfers:()=>pt,maxEntityProgression:()=>yt,putEntityGameSetting:()=>ft,putRoomArgs:()=>ht,putShowcaseValue:()=>_t,rejectTransfer:()=>Rt,reportMatchPlayers:()=>bt,requestSaveUploadUrl:()=>vt,resetEntityProgression:()=>St,setMatchBackfill:()=>xt,simulateEntityOrder:()=>wt,transferHostV2:()=>kt,updateGameRoomV2:()=>At});function s(n){let e=String(n);if(!/^[A-Za-z0-9_.-]{1,128}$/.test(e)||e==="."||e==="..")throw new TypeError(`${JSON.stringify(e)} is not a usable path segment \u2014 it is interpolated into a URL`);return encodeURIComponent(e)}async function vn(n,e,t){let r=`/v1/inventory/transfers/${s(e)}/accept`;return n.client.post(r,void 0,t?.signal)}async function Sn(n,e,t,r,o,a){let i=`/v1/inventory/${s(e)}/${s(t)}/progressions/${s(r)}/add`;return n.client.post(i,o,a?.signal)}async function xn(n,e,t,r){let o=`/v1/voice/sessions/${s(e)}/admin`;return n.client.post(o,t,r?.signal)}async function wn(n,e,t){let r=`/v1/inventory/transfers/${s(e)}/cancel`;return n.client.post(r,void 0,t?.signal)}async function kn(n,e,t,r,o,a){let i=`/v1/inventory/${s(e)}/${s(t)}/progressions/${s(r)}/claim`;return n.client.post(i,o,a?.signal)}async function An(n,e,t){let r=`/v1/games/${s(n.gameId())}/game-rooms/${s(e)}`;return n.client.delete(r,t?.signal)}async function On(n,e,t,r,o){let a=`/v1/inventory/${s(e)}/${s(t)}/orders/batch`;return n.client.post(a,r,o?.signal,{...o?.ifMatch===void 0?{}:{ifMatch:o.ifMatch}})}async function Pn(n,e,t,r,o){let a=`/v1/inventory/${s(e)}/${s(t)}/orders`;return n.client.post(a,r,o?.signal,{...o?.ifMatch===void 0?{}:{ifMatch:o.ifMatch}})}async function Gn(n,e,t){return n.client.post("/v1/voice/sessions",e,t?.signal)}async function Tn(n,e,t,r,o){let a=`/v1/settings/${s(e)}/${s(t)}/${s(r)}`;return n.client.delete(a,o?.signal)}async function Cn(n,e,t,r,o){let a=`/v1/saves/${s(e)}/${s(t)}/${s(r)}`;return n.client.delete(a,o?.signal)}async function In(n,e,t){let r=`/v1/voice/sessions/${s(e)}`;return n.client.delete(r,t?.signal)}async function En(n,e,t,r){let o=`/v1/showcase/players/${s(e)}/${s(t)}`;return n.client.delete(o,r?.signal)}async function qn(n,e,t,r,o){let a=`/v1/inventory/${s(e)}/${s(t)}/recipes/execute`;return n.client.post(a,r,o?.signal,{...o?.ifMatch===void 0?{}:{ifMatch:o.ifMatch}})}async function Ln(n,e,t,r,o,a){let i=`/v1/saves/${s(e)}/${s(t)}/${s(r)}/finalize`;return n.client.post(i,o,a?.signal)}async function Mn(n,e,t){let r=`/v1/games/${s(n.gameId())}/config/channels/${s(e)}`;return n.client.getWithEtag(r,{...t?.signal===void 0?{}:{signal:t.signal},...t?.ifNoneMatch===void 0?{}:{ifNoneMatch:t.ifNoneMatch}})}async function jn(n,e,t){let r=`/v1/inventory/loot-tables/${s(e)}/drop-rates`;return n.client.get(r,t?.signal)}async function $n(n,e,t,r,o){let a=`/v1/inventory/${s(e)}/${s(t)}/currencies/${s(r)}`;return n.client.get(a,o?.signal)}async function Bn(n,e,t,r,o){let a=`/v1/settings/${s(e)}/${s(t)}/${s(r)}`;return n.client.getWithEtag(a,{...o?.signal===void 0?{}:{signal:o.signal},...o?.ifNoneMatch===void 0?{}:{ifNoneMatch:o.ifNoneMatch}})}async function Fn(n,e,t,r){let o=new URLSearchParams;r?.include_buckets!==void 0&&o.set("include_buckets",String(r?.include_buckets)),r?.include_custom_data!==void 0&&o.set("include_custom_data",String(r?.include_custom_data)),r?.currency_limit!==void 0&&o.set("currency_limit",String(r?.currency_limit)),r?.currency_cursor!==void 0&&o.set("currency_cursor",String(r?.currency_cursor)),r?.item_limit!==void 0&&o.set("item_limit",String(r?.item_limit)),r?.item_cursor!==void 0&&o.set("item_cursor",String(r?.item_cursor)),r?.progression_limit!==void 0&&o.set("progression_limit",String(r?.progression_limit)),r?.progression_cursor!==void 0&&o.set("progression_cursor",String(r?.progression_cursor));let a=o.toString(),i=`/v1/inventory/${s(e)}/${s(t)}`+(a?`?${a}`:"");return n.client.get(i,r?.signal)}async function Un(n,e,t,r,o){let a=`/v1/inventory/${s(e)}/${s(t)}/items/${s(r)}`;return n.client.get(a,o?.signal)}async function Dn(n,e,t,r,o){let a=new URLSearchParams;o?.bucket_1!==void 0&&a.set("bucket_1",String(o?.bucket_1)),o?.bucket_2!==void 0&&a.set("bucket_2",String(o?.bucket_2)),o?.limit!==void 0&&a.set("limit",String(o?.limit)),o?.periods_back!==void 0&&a.set("periods_back",String(o?.periods_back)),o?.period!==void 0&&a.set("period",String(o?.period)),o?.player_id!==void 0&&a.set("player_id",String(o?.player_id));let i=a.toString(),d=`/v1/leaderboards/${s(e)}/${s(t)}/${s(r)}`+(i?`?${i}`:"");return n.client.get(d,o?.signal)}async function Nn(n,e,t,r,o){let a=`/v1/inventory/${s(e)}/${s(t)}/orders/${s(r)}`;return n.client.get(a,o?.signal)}async function Hn(n,e,t,r,o){let a=`/v1/inventory/${s(e)}/${s(t)}/progressions/${s(r)}`;return n.client.get(a,o?.signal)}async function Vn(n,e,t,r,o,a){let i=`/v1/inventory/${s(e)}/${s(t)}/catalogs/${s(r)}/recipes/${s(o)}/availability`;return n.client.get(i,a?.signal)}async function Wn(n,e,t,r){let o=new URLSearchParams;r?.limit!==void 0&&o.set("limit",String(r?.limit));let a=o.toString(),i=`/v1/inventory/${s(e)}/${s(t)}/recipe-usage`+(a?`?${a}`:"");return n.client.get(i,r?.signal)}async function zn(n,e,t,r,o){let a=`/v1/saves/${s(e)}/${s(t)}/${s(r)}`;return n.client.getWithEtag(a,{...o?.signal===void 0?{}:{signal:o.signal},...o?.ifNoneMatch===void 0?{}:{ifNoneMatch:o.ifNoneMatch}})}async function Kn(n,e,t){let r=`/v1/events/${s(e)}`;return n.client.get(r,t?.signal)}async function Yn(n,e,t){let r=`/v2/games/${s(n.gameId())}/game-rooms/${s(e)}`;return n.client.getWithEtag(r,{...t?.signal===void 0?{}:{signal:t.signal},...t?.ifNoneMatch===void 0?{}:{ifNoneMatch:t.ifNoneMatch}})}async function Jn(n,e,t){let r=new URLSearchParams;t?.bucket_1!==void 0&&r.set("bucket_1",String(t?.bucket_1)),t?.bucket_2!==void 0&&r.set("bucket_2",String(t?.bucket_2)),t?.periods_back!==void 0&&r.set("periods_back",String(t?.periods_back)),t?.period!==void 0&&r.set("period",String(t?.period)),t?.player_id!==void 0&&r.set("player_id",String(t?.player_id));let o=r.toString(),a=`/v1/leaderboards/${s(e)}`+(o?`?${o}`:"");return n.client.get(a,t?.signal)}async function Xn(n,e,t){let r=`/v1/profiles/players/${s(e)}`;return n.client.get(r,t?.signal)}async function Qn(n,e){let t=new URLSearchParams;e?.config_version!==void 0&&t.set("config_version",String(e?.config_version));let r=t.toString(),o="/v1/inventory/platform-funded-game-inventory-purchase-catalog"+(r?`?${r}`:"");return n.client.get(o,e?.signal)}async function Zn(n,e,t){let r=`/v1/game-room-templates/${s(e)}`;return n.client.get(r,t?.signal)}async function et(n,e,t){let r=`/v1/games/${s(n.gameId())}/game-rooms/${s(e)}/room-args`;return n.client.get(r,t?.signal)}async function nt(n,e,t,r){let o=`/v1/showcase/players/${s(e)}/${s(t)}`;return n.client.get(o,r?.signal)}async function tt(n,e,t){let r=`/v1/inventory/transfers/${s(e)}`;return n.client.get(r,t?.signal)}async function X(n,e,t){let r=`/v1/games/${s(n.gameId())}/analytics/events`;return n.client.post(r,e,t?.signal,{replaySafe:true,retryRateLimited:false})}async function rt(n,e,t){return n.client.post("/v1/inventory/transfers",e,t?.signal)}async function ot(n,e,t){let r=new URLSearchParams;t?.cue_id!==void 0&&r.set("cue_id",String(t?.cue_id));let o=r.toString(),a="/v1/functions/invoke"+(o?`?${o}`:"");return n.client.postBytes(a,e,t?.signal)}async function at(n,e,t,r){let o=`/v1/games/${s(n.gameId())}/game-rooms/${s(e)}/kick/${s(t)}`;return n.client.post(o,void 0,r?.signal)}async function st(n,e){let t=new URLSearchParams;e?.periods_back!==void 0&&t.set("periods_back",String(e?.periods_back)),e?.player_id!==void 0&&t.set("player_id",String(e?.player_id));let r=t.toString(),o="/v1/challenges"+(r?`?${r}`:"");return n.client.get(o,e?.signal)}async function it(n,e,t,r){let o=`/v1/settings/${s(e)}/${s(t)}`;return n.client.get(o,r?.signal)}async function lt(n,e,t,r){let o=new URLSearchParams;r?.limit!==void 0&&o.set("limit",String(r?.limit)),r?.cursor!==void 0&&o.set("cursor",String(r?.cursor));let a=o.toString(),i=`/v1/inventory/${s(e)}/${s(t)}/orders`+(a?`?${a}`:"");return n.client.get(i,r?.signal)}async function dt(n,e,t,r){let o=`/v1/inventory/${s(e)}/${s(t)}/progressions`;return n.client.get(o,r?.signal)}async function ut(n,e,t,r){let o=new URLSearchParams;r?.limit!==void 0&&o.set("limit",String(r?.limit)),r?.cursor!==void 0&&o.set("cursor",String(r?.cursor));let a=o.toString(),i=`/v1/saves/${s(e)}/${s(t)}`+(a?`?${a}`:"");return n.client.get(i,r?.signal)}async function ct(n,e){let t=new URLSearchParams;e?.include_inactive!==void 0&&t.set("include_inactive",String(e?.include_inactive)),e?.limit!==void 0&&t.set("limit",String(e?.limit)),e?.offset!==void 0&&t.set("offset",String(e?.offset));let r=t.toString(),o="/v1/events"+(r?`?${r}`:"");return n.client.get(o,e?.signal)}async function mt(n,e){let t=new URLSearchParams;e?.status!==void 0&&t.set("status",String(e?.status)),e?.game_channel!==void 0&&t.set("game_channel",String(e?.game_channel)),e?.game_room_type!==void 0&&t.set("game_room_type",String(e?.game_room_type)),e?.template_id!==void 0&&t.set("template_id",String(e?.template_id)),e?.template_slug!==void 0&&t.set("template_slug",String(e?.template_slug)),e?.limit!==void 0&&t.set("limit",String(e?.limit)),e?.cursor!==void 0&&t.set("cursor",String(e?.cursor));let r=t.toString(),o=`/v1/games/${s(n.gameId())}/game-rooms`+(r?`?${r}`:"");return n.client.get(o,e?.signal)}async function gt(n,e){return n.client.get("/v1/game-room-templates",e?.signal)}async function pt(n,e){let t=new URLSearchParams;e.entity_type!==void 0&&t.set("entity_type",String(e.entity_type)),e.entity_id!==void 0&&t.set("entity_id",String(e.entity_id)),e?.direction!==void 0&&t.set("direction",String(e?.direction)),e?.status!==void 0&&t.set("status",String(e?.status)),e?.cursor!==void 0&&t.set("cursor",String(e?.cursor)),e?.limit!==void 0&&t.set("limit",String(e?.limit));let r=t.toString(),o="/v1/inventory/transfers"+(r?`?${r}`:"");return n.client.get(o,e?.signal)}async function yt(n,e,t,r,o,a){let i=`/v1/inventory/${s(e)}/${s(t)}/progressions/${s(r)}/max`;return n.client.post(i,o,a?.signal)}async function ft(n,e,t,r,o,a){let i=`/v1/settings/${s(e)}/${s(t)}/${s(r)}`;return n.client.put(i,o,a?.signal,{...a?.ifMatch===void 0?{}:{ifMatch:a.ifMatch}})}async function ht(n,e,t,r){let o=`/v1/games/${s(n.gameId())}/game-rooms/${s(e)}/room-args`;return n.client.put(o,t,r?.signal)}async function _t(n,e,t,r,o){let a=`/v1/showcase/players/${s(e)}/${s(t)}`;return n.client.put(a,r,o?.signal)}async function Rt(n,e,t){let r=`/v1/inventory/transfers/${s(e)}/reject`;return n.client.post(r,void 0,t?.signal)}async function bt(n,e,t,r){let o=`/v1/games/${s(n.gameId())}/matches/${s(e)}/players/report`;return n.client.post(o,t,r?.signal)}async function vt(n,e,t,r,o,a){let i=`/v1/saves/${s(e)}/${s(t)}/${s(r)}/upload-url`;return n.client.post(i,o,a?.signal,{replaySafe:true})}async function St(n,e,t,r,o,a){let i=`/v1/inventory/${s(e)}/${s(t)}/progressions/${s(r)}/reset`;return n.client.post(i,o,a?.signal)}async function xt(n,e,t,r){let o=`/v1/games/${s(n.gameId())}/matches/${s(e)}/backfill`;return n.client.put(o,t,r?.signal)}async function wt(n,e,t,r,o){let a=`/v1/inventory/${s(e)}/${s(t)}/orders/simulate`;return n.client.post(a,r,o?.signal)}async function kt(n,e,t,r){let o=`/v2/games/${s(n.gameId())}/game-rooms/${s(e)}/transfer/${s(t)}`;return n.client.post(o,void 0,r?.signal)}async function At(n,e,t,r){let o=`/v2/games/${s(n.gameId())}/game-rooms/${s(e)}`;return n.client.patch(o,t,r?.signal,{...r?.ifMatch===void 0?{}:{ifMatch:r.ifMatch}})}var ye="gem_";function fe(n,e){let t=e?.retryAfterSeconds,r=typeof t=="number"&&Number.isFinite(t)&&t>0?t*1e3:0,o=1e4*2**Math.min(Math.max(0,n-1),16);return Math.min(Math.max(r,o),3e5)}var Gt=1e4,Tt=50,Ct=1e3,It=65536-4*1024,he=n=>typeof n=="number"?n:0,Et=n=>typeof n=="string"?n:"";function _e(){let n=globalThis.crypto;return typeof n?.randomUUID=="function"?n.randomUUID():"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,e=>{let t=Math.floor(Math.random()*16);return (e==="x"?t:t&3|8).toString(16)})}function qt(n){return n?.retryable===true}function Lt(n,e){let t=n??{},r=Array.isArray(t.rejected)?t.rejected.map(o=>{let a=o??{};return {index:he(a.index),code:Et(a.code)}}):[];return {accepted:he(t.accepted),rejected:r,dropped:e,duplicate:t.duplicate===true}}function Re(n,e){return {event_uid:n.uid,name:n.name,offset_ms:Math.round(n.atMs)-e,player_id:n.playerId,dimensions:n.dimensions,measures:n.measures}}function be(n){let e=Math.max(1,Math.floor(n.maxQueue??Ct)),t={client:n.client,gameId:()=>n.gameId},r=[],o=0,a=null,i=false,d=null,u=0,c=0,g=false,S=false,w=_=>{n.log?.(_);},b=()=>{a!==null&&(n.clock.clearTimeout(a),a=null);},y=()=>Math.max(0,c-n.clock.now()),x=()=>{a!==null||i||d!==null||(a=n.clock.setTimeout(()=>{a=null,P().catch(()=>{});},Math.max(Gt,y())));},A=()=>{let _=Math.min(r.length,100),R=128;for(let G=0;G<_;G+=1){let C=r[G];if(C===void 0)break;if(R+=JSON.stringify(Re(C,0)).length+1,R>It)return Math.max(1,G)}return _};async function P(_){for(;d!==null;)await d.catch(()=>{});if(r.length===0)return {accepted:0,rejected:[],dropped:0,duplicate:false};let R=Le(_);d=R;try{return await R}finally{d===R&&(d=null),r.length>0&&x();}}async function Le(_){b();let R=r.splice(0,A()),G=o;o=0;let C=Math.round(n.clock.now()),D={batch_id:_e(),sent_at_ms:C,events:R.map(k=>Re(k,C))};try{let k=await X(t,D,_===void 0?void 0:{signal:_}),I=Lt(k,G);u=0,c=0;for(let Me of I.rejected)w(`[gem] analytics: an event was refused (${Me.code}). See the analytics_events section of your game config.`);return I}catch(k){if(qt(k)){for(r=[...R,...r],o+=G;r.length>e;)r.shift(),o+=1;u+=1,c=n.clock.now()+fe(u,k);}else w(`[gem] analytics: ${R.length} event(s) were discarded \u2014 the platform refused the batch and will refuse it again: ${String(k)}`);throw k}}return {track(_,R,G={}){if(i)return;if(typeof _!="string"||_===""){S||(S=true,w(`[gem] analytics: '${R}' was not recorded \u2014 an event from a server has to name the player it is about. A game-server token names no player, so the platform cannot infer one; pass the id from join() or host.players().`));return}if(R.startsWith(ye)){g||(g=true,w(`[gem] analytics: '${R}' was not recorded \u2014 the gem_ prefix is reserved, and the platform's own events are client-sourced, so a server may not emit one at all. Name your event something else.`));return}let C={},D={};for(let[k,I]of Object.entries(G))typeof I=="string"?C[k]=I:typeof I=="number"&&Number.isFinite(I)&&(D[k]=I);for(;r.length>=e;)r.shift(),o+=1;r.push({uid:_e(),playerId:_,name:R,atMs:n.clock.now(),dimensions:C,measures:D}),r.length>=Tt&&d===null&&y()===0?P().catch(()=>{}):x();},flush:_=>P(_),get pending(){return r.length},dispose(){i=true,b(),r=[],o=0;}}}function Mt(n){return typeof n=="string"&&/^[\w-]{1,64}$/.test(n)}function ve(n,e){if(n===void 0||Mt(n))return n;let t=typeof n=="string"?JSON.stringify(n.slice(0,72)):`a value of type ${typeof n}`;console.warn(`[gem] ${e}: cueId ${t} is not 1 to 64 letters, digits, _ or -, so it was left out. Use one crypto.randomUUID() per award.`);}var jt=new Map([["function_error",false],["function_failed",false],["function_timeout",false],["function_not_published",false],["function_input_too_large",false],["invalid_cue_id",false],["functions_not_configured",false],["forbidden",false],["function_capacity_unavailable",true],["function_host_unreachable",true],["function_host_error",true],["rate_limited",true],["service_unavailable",true]]),F=class extends p{constructor(e,t){super(e.reason,e.status,e.detail,e.retryAfterSeconds,e.code),this.name="GemFunctionError",Object.assign(this,t);}get retryable(){return (this.code===void 0?void 0:jt.get(this.code))??super.retryable}},M=class{#e;constructor(e){this.#e=e;}async invoke(e,t={}){let r=$t(e),o=ve(t.cueId,"functions.invoke"),a;try{a=await this.#e(r,{...t.signal===void 0?{}:{signal:t.signal},...o===void 0?{}:{cue_id:o}});}catch(i){throw i instanceof p?Ft(i):i}return Bt(a)}};function $t(n){if(n instanceof ArrayBuffer)return new Uint8Array(n);if(ArrayBuffer.isView(n))return new Uint8Array(n.buffer,n.byteOffset,n.byteLength);let e;try{e=JSON.stringify(n);}catch(t){throw new f(`the function input could not be serialised to JSON: ${String(t)}. Pass bytes, or a value JSON can carry. This is a bug in the call, not a server failure.`)}if(e===void 0)throw new f(`the function input is ${typeof n}, which JSON cannot carry. Pass bytes \u2014 an empty Uint8Array for no input \u2014 or a JSON value. This is a bug in the call, not a server failure.`);return new TextEncoder().encode(e)}function Bt(n){let{bytes:e}=n,t=()=>new TextDecoder("utf-8",{fatal:true}).decode(e);return {bytes:e,...n.invocationId===void 0?{}:{invocationId:n.invocationId},text:t,json:()=>JSON.parse(t())}}function Ft(n){let{details:e,invocationId:t}=se(n),o=e?.untrusted?.message,a=e?.reason;return new F(n,{...t===void 0?{}:{invocationId:t},...n.code==="function_error"&&typeof o=="string"?{functionMessage:o}:{},...n.code==="function_failed"&&typeof a=="string"?{failure:a}:{}})}var O=n=>typeof n=="string"?n:"",Ut=/(?:Z|[+-]\d{2}:?\d{2})$/i;function Se(n){let e=O(n);if(!Ut.test(e))return 0;let t=Date.parse(e);return Number.isFinite(t)?Math.floor(t/1e3):0}var Dt=/^[0-9a-f]{1,64}$/,Nt=/^[0-9a-f]{16}$/,Ht=/^[A-Za-z][A-Za-z0-9_+\-/]{0,63}$/,Vt=/^(?:[01]\d|2[0-3]):[0-5]\d$/;function Wt(n){let e=O(n),t=/^(\d{4})-(\d{2})-(\d{2})$/.exec(e);if(!t)return;let[r,o,a]=[Number(t[1]),Number(t[2]),Number(t[3])],i=new Date(Date.UTC(r,o-1,a));return i.getUTCFullYear()===r&&i.getUTCMonth()===o-1&&i.getUTCDate()===a?e:void 0}var zt=4096,Kt=new TextEncoder;function Yt(n){let e=O(n.challenge_data),t=O(n.challenge_data_hash);return e===""||!Nt.test(t)?{}:Kt.encode(e).length>zt?{}:{data:e,dataHash:t}}function Jt(n){let e=n??{},t=Se(e.period_start_at),r=Se(e.period_ends_at);if(t===0||r===0)return;let o=O(e.slug),a=O(e.seed),i=Wt(e.period_local_date),d=O(e.boundary),u=O(e.reset_time);return {id:O(e.progression_definition_id),...o===""?{}:{slug:o},window:O(e.window),periodStartAt:t,periodEndsAt:r,...i===void 0?{}:{periodLocalDate:i},boundary:Ht.test(d)?d:"",resetTime:Vt.test(u)?u:"",seed:Dt.test(a)?a:"",...Yt(e)}}function xe(n){if(n!==void 0&&(!Number.isInteger(n)||n<0||n>400))throw new TypeError(`periodsBack must be an integer between 0 and 400, got ${String(n)}`)}function we(n){let e=n??{};return Array.isArray(e.challenges)?e.challenges.map(Jt).filter(t=>t!==void 0):[]}function ke(n){return {async list(e){let{playerId:t,periodsBack:r,signal:o}=e??{};if(typeof t!="string"||t==="")throw new TypeError("gem.challenges.list needs { playerId }: a game-server token names no player, so the platform cannot tell whose period you mean. Pass the id from join() or gem.players().");xe(r);let a=await n({player_id:t,...r===void 0?{}:{periods_back:r},...o===void 0?{}:{signal:o}});return we(a)}}}function Xt(n){let e={};for(let[t,r]of Object.entries(Q))if(typeof r=="function"){let o=r;e[t]=(...a)=>o(n,...a);}return e}function z(n,e={}){let t=e.clock??L,r=e.baseUrl??n.apiBaseUrl;if(!r)throw new Error("this runtime names no gem-api host (host.apiBaseUrl is missing). The server image running this bundle predates token delivery \u2014 the bundle cannot call gem-api on it.");let o=J(n,{clock:t,...e.onAuthStateChange===void 0?{}:{onStateChange:e.onAuthStateChange}}),a=ie({baseUrl:r,tokenSource:o.source,defaultQuery:{game_id:n.gameId,channel:n.channel},...e.fetch===void 0?{}:{fetch:e.fetch}}),i=new q({transport:a,clock:t}),d={gameId:n.gameId,channel:n.channel,matchId:n.matchId,...n.gameRoomId===void 0?{}:{gameRoomId:n.gameRoomId}},u=Xt({client:i,gameId:()=>d.gameId}),c=d.gameRoomId,g=n.endMatch,S=n.log,w=be({client:i,clock:t,gameId:d.gameId,...typeof S=="function"?{log:y=>S.call(n,y)}:{}});return {identity:d,client:i,api:u,match:{end:async()=>{if(g===void 0)throw new Error("this runtime cannot end the match: the server image running this bundle predates host.endMatch, and only the platform half holds the allocation proof an end needs.");await g.call(n);},setBackfill:async(y,x)=>{let A=await u.setMatchBackfill(d.matchId,{open:y.open,...y.seats===void 0?{}:{seats:y.seats}},x===void 0?{}:{signal:x});return {open:A.open,seats:A.seats??null}},reportPlayers:async(y,x)=>(await u.reportMatchPlayers(d.matchId,{players:y.map(P=>({player_id:P.playerId,state:P.state}))},x===void 0?{}:{signal:x})).players.map(P=>({playerId:P.player_id,outcome:P.outcome}))},analytics:w,functions:new M(u.invokeFunction),challenges:ke(u.listChallenges),...c===void 0?{}:{room:{get:y=>u.getGameRoomV2(c,y),args:async y=>{let x=await u.getGameRoomV2(c,y?.signal===void 0?{}:{signal:y.signal}),A=x.modified?x.body:void 0;if(A?.room_args==null||A.room_args_template==null)throw new p("not_found",404,"this room's template declares no room args",void 0,"room_args_not_defined");return {room_args:A.room_args,room_args_template:A.room_args_template}}}},dispose:()=>{w.dispose(),o.dispose();}}}var Qt=["explicit","stale_cleanup","game_room_closed","replaced","migration_failed","host_left","insufficient_players","all_left","expired","migration_rate_exceeded","game_room_gone","failed","idle","reclaimed"],Zt=new Set(Qt);function Ae(n){return typeof n=="string"&&Zt.has(n)?n:"unknown"}var Ge="[gem: use gem.text.toPlain()]",Oe=new Set,Pe;function er(n){try{if(Oe.has(n))return;let e=globalThis.location;if(Pe??=!!e?.port&&ge(e.hostname??""),!Pe)return;Oe.add(n),console.warn(`[gem] ${n} is PlayerText, turned into a string: players see ${Ge}. Render text.toPlain(value) (text is in @indiegems/gem-web-sdk/sdk).
2
+ ${new Error().stack}`);}catch{}}var v=class{#e;#n;constructor(e,t="player text"){this.#e=e,this.#n=t,Object.freeze(this);}toString(){return er(this.#n),Ge}toJSON(){return this.toString()}get[Symbol.toStringTag](){return "PlayerText"}static unwrap(e){return e.#e}};function U(n,e){return new v(n,e)}var Te={toPlain(n){return v.unwrap(n)},compare(n,e,t){let r=n instanceof v?v.unwrap(n):n,o=e instanceof v?v.unwrap(e):e;if(typeof Intl>"u"||typeof Intl.Collator!="function")return r<o?-1:r>o?1:0;let a;try{a=new Intl.Collator(t);}catch{a=new Intl.Collator;}return a.compare(r,o)},equals(n,e){let t=n instanceof v?v.unwrap(n):n,r=e instanceof v?v.unwrap(e):e;return t.normalize("NFC")===r.normalize("NFC")}};var Ce="the match has not started yet: the runtime hands over the host at `init`, and this was read before that. Read it from `init` or later \u2014 a bundle that needs a value at module scope is reading it one call too early.";function Z(n,e={}){let t=e.clock??L,r=()=>{let d=n();if(d===null)throw new Error(Ce);return d},o=null,a=()=>{if(o===null)throw new Error(Ce);return o};return {server:{get identity(){return a().identity},get client(){return a().client},get api(){return a().api},get match(){return a().match},get analytics(){return a().analytics},get functions(){return a().functions},get challenges(){return a().challenges},get room(){return a().room},dispose(){o?.dispose();},get sizeClass(){return r().sizeClass},get roomArgs(){return r().roomArgs},get roster(){return r().roster},players(){return r().players()},profile(d){let c=r().profile?.(d);if(!c)return null;let g=c.displayName;return typeof g!="string"||g===""?null:{displayName:U(g,"profile.displayName"),...typeof c.displayTag=="string"&&c.displayTag!==""?{displayTag:U(c.displayTag,"profile.displayTag")}:{},...typeof c.discriminator=="string"?{discriminator:c.discriminator}:{}}},playerNumber(d){return r().playerNumber?.(d)},send(d,u,c){c===void 0?r().send(d,u):r().send(d,u,c);},broadcast(d,u){u===void 0?r().broadcast(d):r().broadcast(d,u);},kick(d,u){u===void 0?r().kick(d):r().kick(d,u);},log(d){r().log(d);},warn(d){r().warn(d);}},attach:()=>{o=z(r(),{...e,clock:t});}}}function Ie(n,e={}){let{server:t,attach:r}=Z(()=>n,e);return r(),t}function nr(n){if(n===void 0||typeof n.reason!="string"||n.reason==="")return;let e=n.platform_reason??n.endedReason;return {reason:n.reason,...e===void 0?{}:{endedReason:Ae(e)}}}var tr=1e4;function rr(n){let e=false;return t=>{if(e)return;let r;try{r=n.match.reportPlayers([{playerId:t,state:"connected"}],AbortSignal.timeout(tr));}catch{return}r.catch(o=>{o instanceof p&&o.status>=400&&o.status<500&&(e=o.status!==429);});}}function Ee(n,e={}){return ()=>{let t=null,{server:r,attach:o}=Z(()=>t,e),a=n(r),i={async init(u){t=u,o(),await a.init?.();},async shutdown(u){let c=nr(u);try{await a.shutdown?.(c);}finally{r.dispose();}}},d=rr(r);return i.join=(u,c)=>(d(u),a.join?.(u,c)),a.leave&&(i.leave=(u,c)=>a.leave?.(u,c)),a.message&&(i.message=(u,c,g,S)=>a.message?.(u,c,g,S)),i}}var or=new Set(["unlocked","already_unlocked","suppressed"]);function qe(n){let e=n?.changes;if(!Array.isArray(e))return [];let t=[];for(let r of e){let o=r??{};if(o.type!=="achievement_unlocked"||typeof o.outcome!="string"||!or.has(o.outcome)||typeof o.achievement_id!="string"||o.achievement_id==="")continue;let a=o.outcome;t.push({achievementId:o.achievement_id,progressionDefinitionId:typeof o.progression_definition_id=="string"?o.progression_definition_id:"",points:a==="unlocked"&&typeof o.points=="number"&&Number.isFinite(o.points)?o.points:0,outcome:a,...typeof o.reason=="string"?{reason:o.reason}:{}});}return t}export{h as AuthError,H as CONDITIONAL_HEADERS,M as FunctionsApi,p as GemApiError,q as GemClient,F as GemFunctionError,v as PlayerText,f as TransportRefusal,qe as achievementReceipts,U as asPlayerText,z as createGemServer,pe as createHostTokenSource,Ie as createMatchServer,Ee as defineServer,L as systemClock,Te as text,te as toBase64};//# sourceMappingURL=gem-web-sdk.server.js.map
3
3
  //# sourceMappingURL=gem-web-sdk.server.js.map
package/dist/index.d.ts CHANGED
@@ -19,6 +19,7 @@ declare const PARENT_TO_FRAME: readonly [
19
19
  "gem.prefs",
20
20
  "gem.cohorts",
21
21
  "gem.earnAllowanceChanged",
22
+ "gem.inventoryChanged",
22
23
  "gem.viewport",
23
24
  "gem.deviceSettings",
24
25
  "gem.willTerminate",
@@ -49,6 +50,7 @@ declare const PARENT_TO_FRAME: readonly [
49
50
  "gem.momentResult",
50
51
  "gem.signInResult",
51
52
  "gem.friendChallengeResult",
53
+ "gem.playInviteResult",
52
54
  "gem.appLinksResult",
53
55
  "gem.openAppResult",
54
56
  "gem.openGameResult",
@@ -95,6 +97,8 @@ declare const FRAME_TO_PARENT: readonly [
95
97
  "gem.signalMoment",
96
98
  "gem.requestSignIn",
97
99
  "gem.requestFriendChallenge",
100
+ "gem.requestPlayInvite",
101
+ "gem.inviteParams",
98
102
  "gem.requestAppLinks",
99
103
  "gem.requestOpenApp",
100
104
  "gem.requestOpenGame",
@@ -103,7 +107,7 @@ declare const FRAME_TO_PARENT: readonly [
103
107
  "gem.requestStorePurchase",
104
108
  "gem.requestStoreOfferSheet"
105
109
  ];
106
- type GemCapability = "ads" | "signIn" | "purchases" | "purchaseSettled" | "avatar3dPurchases" | "friendChallenges" | "devtools" | "screenshot" | "feedbackContext" | "rooms" | "p2p" | "dedicated" | "clusterTarget" | "graphicsRoutes" | "parties" | "autoStartFailure" | "ticketEvents" | "partySeating" | "socketState" | "audioState" | "rewardCue" | "rewardPresentation" | "frameStats" | "portraitBorders" | "engagement" | "viewport" | "reservedAreas" | "audioChannels" | "walletDisplay" | "localHost" | "cohorts" | "earnAllowance" | "deviceSettings" | "asyncOpponents" | "share" | "shareResult" | "shareRemap" | "avatarPicker" | "vibration" | "gameMenu" | "controls" | "gemCorner" | "gameSettings" | "moments" | "appLinks" | "openGame" | "store" | "storeOfferSheet" | "menuStyle" | "p2pRelayDrain";
110
+ type GemCapability = "ads" | "signIn" | "purchases" | "purchaseSettled" | "avatar3dPurchases" | "friendChallenges" | "playInvites" | "devtools" | "screenshot" | "feedbackContext" | "rooms" | "p2p" | "dedicated" | "clusterTarget" | "graphicsRoutes" | "parties" | "autoStartFailure" | "ticketEvents" | "partySeating" | "socketState" | "audioState" | "rewardCue" | "rewardPresentation" | "frameStats" | "portraitBorders" | "engagement" | "viewport" | "reservedAreas" | "audioChannels" | "walletDisplay" | "localHost" | "cohorts" | "earnAllowance" | "inventoryChanged" | "deviceSettings" | "asyncOpponents" | "share" | "shareResult" | "shareRemap" | "avatarPicker" | "vibration" | "gameMenu" | "controls" | "gemCorner" | "gameSettings" | "moments" | "appLinks" | "openGame" | "store" | "storeOfferSheet" | "menuStyle" | "p2pRelayDrain";
107
111
  declare const CAPABILITY_GATES: Readonly<Record<string, string>>;
108
112
  declare const CAPABILITY_NAMESPACE_GATES: ReadonlyArray<readonly [
109
113
  string,
@@ -229,6 +233,10 @@ interface GemEarnAllowanceChanged {
229
233
  readonly gem: typeof PROTOCOL;
230
234
  readonly type: "gem.earnAllowanceChanged";
231
235
  }
236
+ interface GemInventoryChanged {
237
+ readonly gem: typeof PROTOCOL;
238
+ readonly type: "gem.inventoryChanged";
239
+ }
232
240
  interface GemViewport {
233
241
  readonly gem: typeof PROTOCOL;
234
242
  readonly type: "gem.viewport";
@@ -686,6 +694,29 @@ interface GemFriendChallengeResult {
686
694
  readonly retryAfterMs?: number;
687
695
  readonly detail?: string;
688
696
  }
697
+ interface GemRequestPlayInvite {
698
+ readonly gem: typeof PROTOCOL;
699
+ readonly type: "gem.requestPlayInvite";
700
+ readonly requestId: string;
701
+ readonly params?: {
702
+ key: string;
703
+ value: string;
704
+ }[];
705
+ }
706
+ interface GemPlayInviteResult {
707
+ readonly gem: typeof PROTOCOL;
708
+ readonly type: "gem.playInviteResult";
709
+ readonly requestId: string;
710
+ readonly shown: boolean;
711
+ }
712
+ interface GemInviteParams {
713
+ readonly gem: typeof PROTOCOL;
714
+ readonly type: "gem.inviteParams";
715
+ readonly params?: {
716
+ key: string;
717
+ value: string;
718
+ }[];
719
+ }
689
720
  interface GemRequestAppLinks {
690
721
  readonly gem: typeof PROTOCOL;
691
722
  readonly type: "gem.requestAppLinks";
@@ -813,8 +844,8 @@ interface GemStoreOfferSheetResult {
813
844
  readonly outcome: "ok" | "declined" | "unavailable";
814
845
  readonly reason?: string;
815
846
  }
816
- type ParentMessage = GemHandshake | GemToken | GemTokenDenied | GemPlayer | GemPause | GemPrefs | GemCohorts | GemEarnAllowanceChanged | GemViewport | GemDeviceSettings | GemWillTerminate | GemRoomEvent | GemSocketState | GemSeatedEvent | GemAutoStartFailedEvent | GemTicketEvent | GemSignalEvent | GemRelayDraining | GemDedicatedEvent | GemPartyResult | GemClusterTarget | GemGraphicsRoutes | GemDevtools | GemScreenshot | GemRequestContext | GemLocalServer | GemLocalServerDenied | GemMenuSelect | GemSettingChange | GemShareResult | GemError | GemPurchaseResult | GemPurchaseSettled | GemDeviceSettingsResult | GemAdResult | GemMomentResult | GemSignInResult | GemFriendChallengeResult | GemAppLinksResult | GemOpenAppResult | GemOpenGameResult | GemSimilarGamesResult | GemStoreOffersResult | GemStorePurchaseResult | GemStorePurchaseSettled | GemStoreOfferSheetResult;
817
- type FrameMessage = GemHandshakeAccept | GemScreenshotDenied | GemGameContext | GemSignal | GemDedicatedOffer | GemPartyRequest | GemReady | GemEngaged | GemProgress | GemRequestToken | GemRequestLocalServer | GemExit | GemOpenExternal | GemRequestFullscreen | GemAudioState | GemRewardCue | GemRewardPresentation | GemWalletDisplay | GemControlsDeclare | GemMenu | GemGemCorner | GemMenuStyle | GemSettingsDeclare | GemRequestShare | GemRequestAvatarPicker | GemVibrate | GemFrameStats | GemPortraitBorders | GemError | GemRequestPurchase | GemRequestAvatar3dPurchase | GemDeviceSettingsPut | GemRequestAd | GemSignalMoment | GemRequestSignIn | GemRequestFriendChallenge | GemRequestAppLinks | GemRequestOpenApp | GemRequestOpenGame | GemRequestSimilarGames | GemRequestStoreOffers | GemRequestStorePurchase | GemRequestStoreOfferSheet;
847
+ type ParentMessage = GemHandshake | GemToken | GemTokenDenied | GemPlayer | GemPause | GemPrefs | GemCohorts | GemEarnAllowanceChanged | GemInventoryChanged | GemViewport | GemDeviceSettings | GemWillTerminate | GemRoomEvent | GemSocketState | GemSeatedEvent | GemAutoStartFailedEvent | GemTicketEvent | GemSignalEvent | GemRelayDraining | GemDedicatedEvent | GemPartyResult | GemClusterTarget | GemGraphicsRoutes | GemDevtools | GemScreenshot | GemRequestContext | GemLocalServer | GemLocalServerDenied | GemMenuSelect | GemSettingChange | GemShareResult | GemError | GemPurchaseResult | GemPurchaseSettled | GemDeviceSettingsResult | GemAdResult | GemMomentResult | GemSignInResult | GemFriendChallengeResult | GemPlayInviteResult | GemAppLinksResult | GemOpenAppResult | GemOpenGameResult | GemSimilarGamesResult | GemStoreOffersResult | GemStorePurchaseResult | GemStorePurchaseSettled | GemStoreOfferSheetResult;
848
+ type FrameMessage = GemHandshakeAccept | GemScreenshotDenied | GemGameContext | GemSignal | GemDedicatedOffer | GemPartyRequest | GemReady | GemEngaged | GemProgress | GemRequestToken | GemRequestLocalServer | GemExit | GemOpenExternal | GemRequestFullscreen | GemAudioState | GemRewardCue | GemRewardPresentation | GemWalletDisplay | GemControlsDeclare | GemMenu | GemGemCorner | GemMenuStyle | GemSettingsDeclare | GemRequestShare | GemRequestAvatarPicker | GemVibrate | GemFrameStats | GemPortraitBorders | GemError | GemRequestPurchase | GemRequestAvatar3dPurchase | GemDeviceSettingsPut | GemRequestAd | GemSignalMoment | GemRequestSignIn | GemRequestFriendChallenge | GemRequestPlayInvite | GemInviteParams | GemRequestAppLinks | GemRequestOpenApp | GemRequestOpenGame | GemRequestSimilarGames | GemRequestStoreOffers | GemRequestStorePurchase | GemRequestStoreOfferSheet;
818
849
  type GemMessage = ParentMessage | FrameMessage;
819
850
  type Rejection = string | null;
820
851
  declare function isOrigin(s: string): boolean;
@@ -828,6 +859,7 @@ declare const validateGemPause: (raw: unknown) => Rejection;
828
859
  declare const validateGemPrefs: (raw: unknown) => Rejection;
829
860
  declare const validateGemCohorts: (raw: unknown) => Rejection;
830
861
  declare const validateGemEarnAllowanceChanged: (raw: unknown) => Rejection;
862
+ declare const validateGemInventoryChanged: (raw: unknown) => Rejection;
831
863
  declare const validateGemViewport: (raw: unknown) => Rejection;
832
864
  declare const validateGemDeviceSettings: (raw: unknown) => Rejection;
833
865
  declare const validateGemWillTerminate: (raw: unknown) => Rejection;
@@ -892,6 +924,9 @@ declare const validateGemRequestSignIn: (raw: unknown) => Rejection;
892
924
  declare const validateGemSignInResult: (raw: unknown) => Rejection;
893
925
  declare const validateGemRequestFriendChallenge: (raw: unknown) => Rejection;
894
926
  declare const validateGemFriendChallengeResult: (raw: unknown) => Rejection;
927
+ declare const validateGemRequestPlayInvite: (raw: unknown) => Rejection;
928
+ declare const validateGemPlayInviteResult: (raw: unknown) => Rejection;
929
+ declare const validateGemInviteParams: (raw: unknown) => Rejection;
895
930
  declare const validateGemRequestAppLinks: (raw: unknown) => Rejection;
896
931
  declare const validateGemAppLinksResult: (raw: unknown) => Rejection;
897
932
  declare const validateGemRequestOpenApp: (raw: unknown) => Rejection;
@@ -1077,7 +1112,7 @@ interface TicketEventRelay {
1077
1112
  readonly reason?: string;
1078
1113
  readonly roomId?: string;
1079
1114
  }
1080
- type RelayDestination = "room" | "signal" | "dedicated" | "party" | "ticket";
1115
+ type RelayDestination = "room" | "signal" | "dedicated" | "party" | "ticket" | "inventory";
1081
1116
  type HostState = "idle" | "handshaking" | "connected" | "unsupported" | "closed";
1082
1117
  interface HostCallbacks {
1083
1118
  onReady?(): void;
@@ -1095,6 +1130,7 @@ interface HostCallbacks {
1095
1130
  onGemCorner?(msg: GemGemCorner): void;
1096
1131
  onRewardPresentation?(msg: GemRewardPresentation): void;
1097
1132
  onMenuStyle?(msg: GemMenuStyle): void;
1133
+ onInviteParams?(msg: GemInviteParams): void;
1098
1134
  onSettingsDeclare?(msg: GemSettingsDeclare): void;
1099
1135
  onFrameStats?(msg: GemFrameStats): void;
1100
1136
  onPortraitBorders?(name: string | null): void;
@@ -1115,6 +1151,7 @@ interface HostCallbacks {
1115
1151
  onRequestStoreOffers?(msg: GemRequestStoreOffers): void;
1116
1152
  onRequestStorePurchase?(msg: GemRequestStorePurchase): void;
1117
1153
  onRequestStoreOfferSheet?(msg: GemRequestStoreOfferSheet): void;
1154
+ onRequestPlayInvite?(msg: GemRequestPlayInvite): void;
1118
1155
  onRequestShare?(msg: GemRequestShare): void;
1119
1156
  onRequestAvatarPicker?(request: {
1120
1157
  readonly tab?: "2d" | "3d";
@@ -1150,6 +1187,9 @@ declare class GemHost {
1150
1187
  private localDenials;
1151
1188
  private chainEndsAt;
1152
1189
  private gameId;
1190
+ private grantedChannel;
1191
+ private inventoryHintAt;
1192
+ private inventoryHintTimer;
1153
1193
  private peerCapabilities;
1154
1194
  private lastPrefs;
1155
1195
  private prefsCalls;
@@ -1195,6 +1235,10 @@ declare class GemHost {
1195
1235
  relayAutoStartFailedEvent(raw: unknown): boolean;
1196
1236
  sendTicketEvent(relay: TicketEventRelay): boolean;
1197
1237
  relayTicketEvent(raw: unknown): boolean;
1238
+ relayInventoryEvent(raw: unknown): boolean;
1239
+ sendInventoryChanged(): boolean;
1240
+ private flushInventoryHint;
1241
+ private armInventoryHint;
1198
1242
  relaySocketEvent(raw: unknown): readonly RelayDestination[];
1199
1243
  relaySignalEvent(raw: unknown): boolean;
1200
1244
  sendSignalEvent(relay: RelayedSignal): boolean;
@@ -1245,6 +1289,7 @@ declare class GemHost {
1245
1289
  answerStorePurchase(requestId: string, outcome: ArcadeOutcomeKind, reason?: string): boolean;
1246
1290
  answerStoreOfferSheet(requestId: string, outcome: ArcadeOutcomeKind, reason?: string): boolean;
1247
1291
  sendStorePurchaseSettled(skuId: string): boolean;
1292
+ answerPlayInvite(requestId: string, shown: boolean): boolean;
1248
1293
  denyToken(denial: TokenDenial): void;
1249
1294
  grantLocalServer(grant: LocalServerGrant): boolean;
1250
1295
  denyLocalServer(denial: LocalServerDenial): boolean;
@@ -1414,6 +1459,7 @@ interface FramePlayer extends PlayerIdentity {
1414
1459
  readonly boost: PlayerBoost;
1415
1460
  }
1416
1461
  type GemArcadeAsk = Omit<GemRequestAppLinks, "gem"> | Omit<GemRequestOpenApp, "gem"> | Omit<GemRequestOpenGame, "gem"> | Omit<GemRequestSimilarGames, "gem"> | Omit<GemRequestStoreOffers, "gem"> | Omit<GemRequestStorePurchase, "gem"> | Omit<GemRequestStoreOfferSheet, "gem">;
1462
+ type GemFriendsWindowAsk = Omit<GemRequestPlayInvite, "gem"> | Omit<GemInviteParams, "gem">;
1417
1463
  type GemArcadeAnswer = GemAppLinksResult | GemOpenAppResult | GemOpenGameResult | GemSimilarGamesResult | GemStoreOffersResult | GemStorePurchaseResult | GemStorePurchaseSettled | GemStoreOfferSheetResult;
1418
1464
  interface FrameCallbacks {
1419
1465
  onToken?(msg: GemToken): void;
@@ -1423,6 +1469,7 @@ interface FrameCallbacks {
1423
1469
  onPrefs?(msg: GemPrefs): void;
1424
1470
  onCohorts?(msg: GemCohorts): void;
1425
1471
  onEarnAllowanceChanged?(): void;
1472
+ onInventoryChanged?(msg: GemInventoryChanged): void;
1426
1473
  onViewport?(msg: GemViewport): void;
1427
1474
  onWillTerminate?(msg: GemWillTerminate): void;
1428
1475
  onDevtools?(action: "open" | "close" | "toggle"): void;
@@ -1456,6 +1503,7 @@ interface FrameCallbacks {
1456
1503
  onSignInResult?(msg: GemSignInResult): void;
1457
1504
  onFriendChallengeResult?(msg: GemFriendChallengeResult): void;
1458
1505
  onArcadeAnswer?(msg: GemArcadeAnswer): void;
1506
+ onPlayInviteResult?(msg: GemPlayInviteResult): void;
1459
1507
  onError?(code: GemErrorCode, message?: string): void;
1460
1508
  onDropped?(code: GemErrorCode, message?: string): void;
1461
1509
  onStateChange?(state: FrameState): void;
@@ -1536,7 +1584,7 @@ declare class GemFrame {
1536
1584
  readyCalled(): boolean;
1537
1585
  requestSignIn(requestId: string): boolean;
1538
1586
  requestFriendChallenge(requestId: string, playerId: string, template: string, params?: Readonly<Record<string, string | number>>): boolean;
1539
- requestArcade(msg: GemArcadeAsk): boolean;
1587
+ requestArcade(msg: GemArcadeAsk | GemFriendsWindowAsk): boolean;
1540
1588
  close(): void;
1541
1589
  private transition;
1542
1590
  private refuseMalformed;
@@ -2832,4 +2880,4 @@ interface P2pMatchApi {
2832
2880
  session(matchId: string): P2pSession | null;
2833
2881
  }
2834
2882
  declare function createP2pApi(options: P2pApiOptions): P2pMatchApi;
2835
- export { type ArcadeOutcomeKind, type AutoReconnectOptions, type AwaitMatchOptions, BUILT_IN_GRAPHICS_ROUTES, CAPABILITY_GATES, CAPABILITY_NAMESPACE_GATES, CHANNELS, CHANNEL_KINDS, type ChannelKind, type ClientPlatform, ClientTelemetry, type ClientTelemetryOptions, type ClientVersion, type Clock, type ClusterTarget, type ClusterTargetBridge, type ClusterTargetLike, type ClusterTargetListResolver, type ClusterTargetRefresher, type ClusterTargetResolver, type ClusterTargetSource, type ClusterTargetSourceOptions, type ConnectOptions, type CreateRoomOptions, INBOUND_EVENTS as DEDICATED_INBOUND_EVENTS, DEFAULT_WELCOME_CEILING_MS, DEVICE_SETTINGS_MAX_BYTES, type DataChannelLike$1 as DataChannelLike, type DedicatedServerApi, type DedicatedServerApiOptions, DedicatedServerError, type DedicatedServerFailure, type DedicatedServerSession, type DedicatedSignalTransport, DedicatedSignalingHub, type DedicatedSignalingOptions, type EstablishOptions, FRAME_TO_PARENT, type FailedMatch, type FrameCallbacks, type FrameMessage, type FrameOptions, type FrameState, type GemAdResult, type GemAppLinksResult, type GemArcadeOffer, type GemAudioState, type GemAutoStartFailedEvent, type GemCapability, type GemClusterTarget, type GemCohorts, type GemControlsDeclare, type GemDedicatedEvent, type GemDedicatedOffer, type GemDeviceSettings, type GemDeviceSettingsPut, type GemDeviceSettingsResult, type GemDevtools, type GemEarnAllowanceChanged, type GemEngaged, type GemError, type GemErrorCode, type GemExit, GemFrame, type GemFrameStats, type GemFriendChallengeResult, type GemGameCard, type GemGameContext, type GemGemCorner, type GemGraphicsRouteEntry, type GemGraphicsRoutes, type GemHandshake, type GemHandshakeAccept, GemHost, type GemLocalServer, type GemLocalServerDenied, type GemMenu, type GemMenuSelect, type GemMenuStyle, type GemMessage, type GemMomentResult, type GemOpenAppResult, type GemOpenExternal, type GemOpenGameResult, type GemPartyRequest, type GemPartyResult, type GemPause, type GemPlayer, type GemPortraitBorders, type GemPrefs, type GemProgress, type GemPurchaseResult, type GemPurchaseSettled, type GemReady, type GemRelayDraining, type GemRequestAd, type GemRequestAppLinks, type GemRequestAvatar3dPurchase, type GemRequestAvatarPicker, type GemRequestContext, type GemRequestFriendChallenge, type GemRequestFullscreen, type GemRequestLocalServer, type GemRequestOpenApp, type GemRequestOpenGame, type GemRequestPurchase, type GemRequestShare, type GemRequestSignIn, type GemRequestSimilarGames, type GemRequestStoreOfferSheet, type GemRequestStoreOffers, type GemRequestStorePurchase, type GemRequestToken, type GemRewardCue, type GemRewardPresentation, type GemRoomEvent, type GemScreenshot, type GemScreenshotDenied, type GemSeatedEvent, type GemSettingChange, type GemSettingsDeclare, type GemShareResult, type GemSignInResult, type GemSignal, type GemSignalEvent, type GemSignalMoment, type GemSimilarGamesResult, type GemSocketState, type GemStoreOfferSheetResult, type GemStoreOffersResult, type GemStorePurchaseResult, type GemStorePurchaseSettled, type GemTicketEvent, type GemToken, type GemTokenDenied, type GemVibrate, type GemViewport, type GemWalletDisplay, type GemWillTerminate, HANDSHAKE_TIMEOUT_MS, type HandshakeEvent, type HostCallbacks, HostMigration, type HostOptions, type HostState, type JoinCredential, type JoinExchange, type JoinRoomOptions, type JoinWelcome, type KeySource, type ListRoomsOptions, MALFORMED_INBOUND_KEY, MAX_ARRAY_LENGTH, MAX_CLUSTER_TARGETS, MAX_MESSAGE_BYTES, MAX_MESSAGE_DEPTH, MAX_MESSAGE_NODES, MAX_SIGNALS_PER_SECOND, MAX_SOCKET_FRAME_BYTES, MIGRATION_TIMEOUT_MS, type MatchAutoStartFailed, type MatchConnectionState, type MatchEnded, type MatchOutcome, type MatchOutcomeWaitOptions, type MatchReconnected, type MatchReconnecting, type MatchSession, type MatchSessionPhase, type MatchSuspended, type MatchTicket, type MatchTicketOutcome, type MatchTicketStatus, type MigrationState, type OfferRefusal, type OfferRequest, P2pApi, type P2pConnectOptions, P2pError, type P2pEventMap, type P2pEventName, type P2pFailure, type P2pMatchApi, type P2pPeer, P2pSession, PARENT_TO_FRAME, PROTOCOL, type ParentMessage, type PartyBridge, type PartyEventRelay, type PartyResolver, type PartyResolverOptions, type PartyTicket, type PartyTicketOutcome, type PartyTicketStatus, type PeerConnectionLike$1 as PeerConnectionLike, type PlayWithOutcome, PlayerText, type PortLike, type PortMessageHandler, type PresentCredentialOptions, type PurchaseRefusalCode, type QueueForMatchOptions, type QuickJoinOptions, RATE_LIMITS, RateLimiter, type ReadyMatch, type Rejection, type RelayedDedicatedEvent, type RelayedRoomEvent, type RelayedSignal, type RelayedTicketEvent, type ResolvedClientVersion, type Room, type RoomArgEntry, type RoomArgScalar, type RoomArgType, type RoomArgValue, type RoomArgs, RoomEmitter, type RoomEventMap, type RoomEventName, type RoomManager, type RoomManagerOptions, type RoomMember, type RoomOperationError, type RoomPage, type RoomStatus, type RoomSummary, RoomsApi, type RoomsApiOptions, SUPPORTED_VERSIONS, type SdpType$1 as SdpType, type SendPlayerInput, type SessionDescriptionLike$1 as SessionDescriptionLike, type SignalTransport, type SignalingAnswer, type SignalingChannel, SignalingClient, type SignalingIntent, type StartMatchOptions, type StartedMatch$1 as StartedMatch, TELEMETRY_EVENTS, TRANSPORT_LABELS, type TelemetrySample, type TokenDenial, type TokenGrant, type TransportLabel, type TurnLease, type UpdateRoomOptions, VALIDATORS, type VerifiedCredential, WEBRTC_DEDICATED, WEBRTC_P2P, WEB_ENGINE_VERSION, WEB_PROTOCOL_VERSION, type WindowLike, asPlayerText, awaitMatchOutcome, browserPeerConnection, buildDedicatedOfferFrame, buildSocketFrame, capabilityFor, createClusterTargetSource, createDedicatedServerApi, createKeySource, createP2pApi, createPartyResolver, createRoomManager, deviceSettingsByteLength, establishDataChannel, fingerprintOf, fingerprintsMatch, generateCertificate, isOrigin, listClusterTargets, memberFromWire, negotiateVersion, normaliseClusterTarget, normaliseClusterTargets, normaliseFingerprint, originsEqual, presentJoinCredential, projectDedicatedEvent, projectPartyEvent, projectSignal, roomArgValuesFromWire, roomArgsTemplateFromWire, roomFromWire, startMatch, summaryFromWire, systemClock, text, unavailableSignaling, validateGemAdResult, validateGemAppLinksResult, validateGemAudioState, validateGemAutoStartFailedEvent, validateGemClusterTarget, validateGemCohorts, validateGemControlsDeclare, validateGemDedicatedEvent, validateGemDedicatedOffer, validateGemDeviceSettings, validateGemDeviceSettingsPut, validateGemDeviceSettingsResult, validateGemDevtools, validateGemEarnAllowanceChanged, validateGemEngaged, validateGemError, validateGemExit, validateGemFrameStats, validateGemFriendChallengeResult, validateGemGameContext, validateGemGemCorner, validateGemGraphicsRoutes, validateGemHandshake, validateGemHandshakeAccept, validateGemLocalServer, validateGemLocalServerDenied, validateGemMenu, validateGemMenuSelect, validateGemMenuStyle, validateGemMomentResult, validateGemOpenAppResult, validateGemOpenExternal, validateGemOpenGameResult, validateGemPartyRequest, validateGemPartyResult, validateGemPause, validateGemPlayer, validateGemPortraitBorders, validateGemPrefs, validateGemProgress, validateGemPurchaseResult, validateGemPurchaseSettled, validateGemReady, validateGemRelayDraining, validateGemRequestAd, validateGemRequestAppLinks, validateGemRequestAvatar3dPurchase, validateGemRequestAvatarPicker, validateGemRequestContext, validateGemRequestFriendChallenge, validateGemRequestFullscreen, validateGemRequestLocalServer, validateGemRequestOpenApp, validateGemRequestOpenGame, validateGemRequestPurchase, validateGemRequestShare, validateGemRequestSignIn, validateGemRequestSimilarGames, validateGemRequestStoreOfferSheet, validateGemRequestStoreOffers, validateGemRequestStorePurchase, validateGemRequestToken, validateGemRewardCue, validateGemRewardPresentation, validateGemRoomEvent, validateGemScreenshot, validateGemScreenshotDenied, validateGemSeatedEvent, validateGemSettingChange, validateGemSettingsDeclare, validateGemShareResult, validateGemSignInResult, validateGemSignal, validateGemSignalEvent, validateGemSignalMoment, validateGemSimilarGamesResult, validateGemSocketState, validateGemStoreOfferSheetResult, validateGemStoreOffersResult, validateGemStorePurchaseResult, validateGemStorePurchaseSettled, validateGemTicketEvent, validateGemToken, validateGemTokenDenied, validateGemVibrate, validateGemViewport, validateGemWalletDisplay, validateGemWillTerminate, validateSize, verifyCredential };
2883
+ export { type ArcadeOutcomeKind, type AutoReconnectOptions, type AwaitMatchOptions, BUILT_IN_GRAPHICS_ROUTES, CAPABILITY_GATES, CAPABILITY_NAMESPACE_GATES, CHANNELS, CHANNEL_KINDS, type ChannelKind, type ClientPlatform, ClientTelemetry, type ClientTelemetryOptions, type ClientVersion, type Clock, type ClusterTarget, type ClusterTargetBridge, type ClusterTargetLike, type ClusterTargetListResolver, type ClusterTargetRefresher, type ClusterTargetResolver, type ClusterTargetSource, type ClusterTargetSourceOptions, type ConnectOptions, type CreateRoomOptions, INBOUND_EVENTS as DEDICATED_INBOUND_EVENTS, DEFAULT_WELCOME_CEILING_MS, DEVICE_SETTINGS_MAX_BYTES, type DataChannelLike$1 as DataChannelLike, type DedicatedServerApi, type DedicatedServerApiOptions, DedicatedServerError, type DedicatedServerFailure, type DedicatedServerSession, type DedicatedSignalTransport, DedicatedSignalingHub, type DedicatedSignalingOptions, type EstablishOptions, FRAME_TO_PARENT, type FailedMatch, type FrameCallbacks, type FrameMessage, type FrameOptions, type FrameState, type GemAdResult, type GemAppLinksResult, type GemArcadeOffer, type GemAudioState, type GemAutoStartFailedEvent, type GemCapability, type GemClusterTarget, type GemCohorts, type GemControlsDeclare, type GemDedicatedEvent, type GemDedicatedOffer, type GemDeviceSettings, type GemDeviceSettingsPut, type GemDeviceSettingsResult, type GemDevtools, type GemEarnAllowanceChanged, type GemEngaged, type GemError, type GemErrorCode, type GemExit, GemFrame, type GemFrameStats, type GemFriendChallengeResult, type GemGameCard, type GemGameContext, type GemGemCorner, type GemGraphicsRouteEntry, type GemGraphicsRoutes, type GemHandshake, type GemHandshakeAccept, GemHost, type GemInventoryChanged, type GemInviteParams, type GemLocalServer, type GemLocalServerDenied, type GemMenu, type GemMenuSelect, type GemMenuStyle, type GemMessage, type GemMomentResult, type GemOpenAppResult, type GemOpenExternal, type GemOpenGameResult, type GemPartyRequest, type GemPartyResult, type GemPause, type GemPlayInviteResult, type GemPlayer, type GemPortraitBorders, type GemPrefs, type GemProgress, type GemPurchaseResult, type GemPurchaseSettled, type GemReady, type GemRelayDraining, type GemRequestAd, type GemRequestAppLinks, type GemRequestAvatar3dPurchase, type GemRequestAvatarPicker, type GemRequestContext, type GemRequestFriendChallenge, type GemRequestFullscreen, type GemRequestLocalServer, type GemRequestOpenApp, type GemRequestOpenGame, type GemRequestPlayInvite, type GemRequestPurchase, type GemRequestShare, type GemRequestSignIn, type GemRequestSimilarGames, type GemRequestStoreOfferSheet, type GemRequestStoreOffers, type GemRequestStorePurchase, type GemRequestToken, type GemRewardCue, type GemRewardPresentation, type GemRoomEvent, type GemScreenshot, type GemScreenshotDenied, type GemSeatedEvent, type GemSettingChange, type GemSettingsDeclare, type GemShareResult, type GemSignInResult, type GemSignal, type GemSignalEvent, type GemSignalMoment, type GemSimilarGamesResult, type GemSocketState, type GemStoreOfferSheetResult, type GemStoreOffersResult, type GemStorePurchaseResult, type GemStorePurchaseSettled, type GemTicketEvent, type GemToken, type GemTokenDenied, type GemVibrate, type GemViewport, type GemWalletDisplay, type GemWillTerminate, HANDSHAKE_TIMEOUT_MS, type HandshakeEvent, type HostCallbacks, HostMigration, type HostOptions, type HostState, type JoinCredential, type JoinExchange, type JoinRoomOptions, type JoinWelcome, type KeySource, type ListRoomsOptions, MALFORMED_INBOUND_KEY, MAX_ARRAY_LENGTH, MAX_CLUSTER_TARGETS, MAX_MESSAGE_BYTES, MAX_MESSAGE_DEPTH, MAX_MESSAGE_NODES, MAX_SIGNALS_PER_SECOND, MAX_SOCKET_FRAME_BYTES, MIGRATION_TIMEOUT_MS, type MatchAutoStartFailed, type MatchConnectionState, type MatchEnded, type MatchOutcome, type MatchOutcomeWaitOptions, type MatchReconnected, type MatchReconnecting, type MatchSession, type MatchSessionPhase, type MatchSuspended, type MatchTicket, type MatchTicketOutcome, type MatchTicketStatus, type MigrationState, type OfferRefusal, type OfferRequest, P2pApi, type P2pConnectOptions, P2pError, type P2pEventMap, type P2pEventName, type P2pFailure, type P2pMatchApi, type P2pPeer, P2pSession, PARENT_TO_FRAME, PROTOCOL, type ParentMessage, type PartyBridge, type PartyEventRelay, type PartyResolver, type PartyResolverOptions, type PartyTicket, type PartyTicketOutcome, type PartyTicketStatus, type PeerConnectionLike$1 as PeerConnectionLike, type PlayWithOutcome, PlayerText, type PortLike, type PortMessageHandler, type PresentCredentialOptions, type PurchaseRefusalCode, type QueueForMatchOptions, type QuickJoinOptions, RATE_LIMITS, RateLimiter, type ReadyMatch, type Rejection, type RelayedDedicatedEvent, type RelayedRoomEvent, type RelayedSignal, type RelayedTicketEvent, type ResolvedClientVersion, type Room, type RoomArgEntry, type RoomArgScalar, type RoomArgType, type RoomArgValue, type RoomArgs, RoomEmitter, type RoomEventMap, type RoomEventName, type RoomManager, type RoomManagerOptions, type RoomMember, type RoomOperationError, type RoomPage, type RoomStatus, type RoomSummary, RoomsApi, type RoomsApiOptions, SUPPORTED_VERSIONS, type SdpType$1 as SdpType, type SendPlayerInput, type SessionDescriptionLike$1 as SessionDescriptionLike, type SignalTransport, type SignalingAnswer, type SignalingChannel, SignalingClient, type SignalingIntent, type StartMatchOptions, type StartedMatch$1 as StartedMatch, TELEMETRY_EVENTS, TRANSPORT_LABELS, type TelemetrySample, type TokenDenial, type TokenGrant, type TransportLabel, type TurnLease, type UpdateRoomOptions, VALIDATORS, type VerifiedCredential, WEBRTC_DEDICATED, WEBRTC_P2P, WEB_ENGINE_VERSION, WEB_PROTOCOL_VERSION, type WindowLike, asPlayerText, awaitMatchOutcome, browserPeerConnection, buildDedicatedOfferFrame, buildSocketFrame, capabilityFor, createClusterTargetSource, createDedicatedServerApi, createKeySource, createP2pApi, createPartyResolver, createRoomManager, deviceSettingsByteLength, establishDataChannel, fingerprintOf, fingerprintsMatch, generateCertificate, isOrigin, listClusterTargets, memberFromWire, negotiateVersion, normaliseClusterTarget, normaliseClusterTargets, normaliseFingerprint, originsEqual, presentJoinCredential, projectDedicatedEvent, projectPartyEvent, projectSignal, roomArgValuesFromWire, roomArgsTemplateFromWire, roomFromWire, startMatch, summaryFromWire, systemClock, text, unavailableSignaling, validateGemAdResult, validateGemAppLinksResult, validateGemAudioState, validateGemAutoStartFailedEvent, validateGemClusterTarget, validateGemCohorts, validateGemControlsDeclare, validateGemDedicatedEvent, validateGemDedicatedOffer, validateGemDeviceSettings, validateGemDeviceSettingsPut, validateGemDeviceSettingsResult, validateGemDevtools, validateGemEarnAllowanceChanged, validateGemEngaged, validateGemError, validateGemExit, validateGemFrameStats, validateGemFriendChallengeResult, validateGemGameContext, validateGemGemCorner, validateGemGraphicsRoutes, validateGemHandshake, validateGemHandshakeAccept, validateGemInventoryChanged, validateGemInviteParams, validateGemLocalServer, validateGemLocalServerDenied, validateGemMenu, validateGemMenuSelect, validateGemMenuStyle, validateGemMomentResult, validateGemOpenAppResult, validateGemOpenExternal, validateGemOpenGameResult, validateGemPartyRequest, validateGemPartyResult, validateGemPause, validateGemPlayInviteResult, validateGemPlayer, validateGemPortraitBorders, validateGemPrefs, validateGemProgress, validateGemPurchaseResult, validateGemPurchaseSettled, validateGemReady, validateGemRelayDraining, validateGemRequestAd, validateGemRequestAppLinks, validateGemRequestAvatar3dPurchase, validateGemRequestAvatarPicker, validateGemRequestContext, validateGemRequestFriendChallenge, validateGemRequestFullscreen, validateGemRequestLocalServer, validateGemRequestOpenApp, validateGemRequestOpenGame, validateGemRequestPlayInvite, validateGemRequestPurchase, validateGemRequestShare, validateGemRequestSignIn, validateGemRequestSimilarGames, validateGemRequestStoreOfferSheet, validateGemRequestStoreOffers, validateGemRequestStorePurchase, validateGemRequestToken, validateGemRewardCue, validateGemRewardPresentation, validateGemRoomEvent, validateGemScreenshot, validateGemScreenshotDenied, validateGemSeatedEvent, validateGemSettingChange, validateGemSettingsDeclare, validateGemShareResult, validateGemSignInResult, validateGemSignal, validateGemSignalEvent, validateGemSignalMoment, validateGemSimilarGamesResult, validateGemSocketState, validateGemStoreOfferSheetResult, validateGemStoreOffersResult, validateGemStorePurchaseResult, validateGemStorePurchaseSettled, validateGemTicketEvent, validateGemToken, validateGemTokenDenied, validateGemVibrate, validateGemViewport, validateGemWalletDisplay, validateGemWillTerminate, validateSize, verifyCredential };