@indiegems/gem-web-sdk 21.0.0 → 21.1.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 Me=Object.defineProperty;var $e=(n,e)=>{for(var t in e)Me(n,t,{get:e[t],enumerable:true});};globalThis.__gemWebSdkVersion="[gem-web-sdk:sdkVersion:21.0.0]";var je={initialDelayMs:2e3,maxDelayMs:6e4};function Be(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}=je,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=Fe(o),{retryable:i,retryAfterMs:d}=o??{};throw t===this.generation&&(Be(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 Fe(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 Ue(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"?De(r):r;if(typeof a!="string"||a.length>ee||!Ne(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 De(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 Ne(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 He(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=Ue(o.headers),i=He(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(Ve(e))}function Ve(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 We=new Set([408,429,500,502,503,504]),ze=6e4,Ke=new WeakMap;function re(n){return n!==null&&(n.reason==="rate_limited"||n.retryAfterSeconds!==void 0)}function Ye(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 L=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,...$(o)},o.replaySafe===true,o.retryRateLimited!==false)}async post(e,t,r,o={}){return this.send({method:"POST",path:e,body:t,signal:r,...$(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,...$(o)},o.replaySafe===true,o.retryRateLimited!==false);return {bytes:Je(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,...$(o)},o.replaySafe===true,o.retryRateLimited!==false)}async delete(e,t,r={}){return this.send({method:"DELETE",path:e,signal:t,...$(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?Ye(this.options.maxRetries)+1:1,a=null;if(e.signal?.aborted)throw oe(e.signal);let i=e.signal===void 0?void 0:Ke.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||Xe(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=Qe(u);if(!We.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),ze)}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 Je(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 $(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 Xe(n){let e=n?.name;return e==="AbortError"||e==="TimeoutError"}function Qe(n){let e=en(n),t=tn(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 Ze=new Map([["insufficient_funds","insufficient_funds"]]);function en(n){let{status:e,body:t}=n,r=nn(t),o=n.retryAfterSeconds??on(t),a=rn(t),i=a===void 0?void 0:Ze.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 nn(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 tn(n){let t=n?.error?.details;return t===null?void 0:t}function rn(n){let t=n?.error?.code;return typeof t=="string"&&t.length>0?t:void 0}function on(n){let e=n?.retryAfterSeconds;return typeof e=="number"&&Number.isFinite(e)&&e>=0?e:void 0}function an(n){let e=n.lastIndexOf("@");return (e===-1?n:`***@${n.slice(e+1)}`).slice(0,200)}var sn=new Set(H);function ln(n){if(!n)return {};let e={};for(let[t,r]of Object.entries(n))sn.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"?an(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 R=o.username!==""||o.password!=="",y=a.username!==o.username||a.password!==o.password,x=R?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[R,y]of Object.entries(n.defaultQuery??{}))a.searchParams.has(R)||a.searchParams.set(R,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(R){throw new f(`the body of ${t.method} ${JSON.stringify(a.pathname)} could not be serialised to JSON: ${String(R)}. 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},...ln(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 R=await u.text();if(R.length>0)try{c=JSON.parse(R);}catch{c=R;}}let g=u.headers.get("etag"),S=dn(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 dn(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 un="gem-web-bridge";var cn=65536,le=8,V=5e3,de=1024;var W=Object.create(null);var ue=Object.create(null);function mn(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 gn(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 pn(n){return /^[a-z]{2,8}(-[a-z0-9]{1,8})*$/i.test(n)}function yn(n){return /^[a-z_]+$/.test(n)}function fn(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 hn(n,e=cn){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 _n={origin:[mn,"not a well-formed origin"],url:[gn,"not a safe absolute http(s) URL"],bcp47:[pn,"not a well-formed BCP 47 tag"],code:[yn,"not a code of lower-case letters and underscores"],gameRef:[fn,"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]=_n[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=hn(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!==un?"gem: wrong protocol marker":d.type!==n?`type: expected ${n}`:ce(d,e,"")}}var j=["","s",64],m=["requestId","s",64],B=["matchId","s",64],I=["outcome","e",["ok","declined","unavailable"]],E=["reason","S",64,"code"];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.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],["expected","I",1,1e9],["origin","O",[["x","i",0,16384],["y","i",0,16384]]]],60,"rewardCue");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",[["params","a",16,["","o",[["key","s",64],["value","s",512]]]]],6,"share");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]],12,"purchases");l("gem.requestAvatar3dPurchase",[m,["itemId","s",64],["currencySlug","s",32]],12,"avatar3dPurchases");l("gem.purchaseResult",[m,I,E,["purchaseId","S",64]],30,"purchases");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,I,E,["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,I,E],30,"appLinks");l("gem.requestOpenGame",[m,["ref","s",40,"gameRef"]],6,"openGame");l("gem.openGameResult",[m,I,E],30,"openGame");l("gem.requestSimilarGames",[m,["limit","I",1,24]],12,"openGame");l("gem.similarGamesResult",[m,I,E,["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,I,E,["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,I,E],30,"store");l("gem.storePurchaseSettled",[["skuId","s",64]],30,"store");l("gem.requestStoreOfferSheet",[m,["skuId","s",64]],12,"storeOfferSheet");l("gem.storeOfferSheetResult",[m,I,E],30,"storeOfferSheet");Object.freeze(me);W.__malformed=60;Object.freeze(W);Object.freeze(ue);var q={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:()=>Rn,addEntityProgression:()=>vn,adminAction:()=>Sn,cancelInventoryTransfer:()=>xn,claimEntityProgressionRewards:()=>wn,closeGameRoom:()=>kn,createEntityBatchOrder:()=>An,createEntityOrder:()=>On,createSession:()=>Pn,deleteEntityGameSetting:()=>Gn,deleteEntitySave:()=>Tn,deleteSession:()=>Cn,deleteShowcaseValue:()=>In,executeEntityRecipe:()=>En,finalizeSaveUpload:()=>Ln,getChannelAssignment:()=>qn,getDropRates:()=>Mn,getEntityCurrency:()=>$n,getEntityGameSetting:()=>jn,getEntityInventory:()=>Bn,getEntityInventoryItem:()=>Fn,getEntityLeaderboard:()=>Un,getEntityOrder:()=>Dn,getEntityProgression:()=>Nn,getEntityRecipeAvailability:()=>Hn,getEntityRecipeUsage:()=>Vn,getEntitySave:()=>Wn,getEvent:()=>zn,getGameRoomV2:()=>Kn,getLeaderboard:()=>Yn,getPlayerGameProfile:()=>Jn,getPurchaseCatalog:()=>Xn,getResolvedTemplate:()=>Qn,getRoomArgs:()=>Zn,getShowcaseValue:()=>et,getTransferDetails:()=>nt,ingestAnalyticsEvents:()=>X,initiateInventoryTransfer:()=>tt,invokeFunction:()=>rt,kickPlayer:()=>ot,listChallenges:()=>at,listEntityGameSettings:()=>st,listEntityOrders:()=>it,listEntityProgressions:()=>lt,listEntitySaves:()=>dt,listEvents:()=>ut,listGameRooms:()=>ct,listResolvedTemplates:()=>mt,listTransfers:()=>gt,maxEntityProgression:()=>pt,putEntityGameSetting:()=>yt,putRoomArgs:()=>ft,putShowcaseValue:()=>ht,rejectTransfer:()=>_t,reportMatchPlayers:()=>bt,requestSaveUploadUrl:()=>Rt,resetEntityProgression:()=>vt,setMatchBackfill:()=>St,simulateEntityOrder:()=>xt,transferHostV2:()=>wt,updateGameRoomV2:()=>kt});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 Rn(n,e,t){let r=`/v1/inventory/transfers/${s(e)}/accept`;return n.client.post(r,void 0,t?.signal)}async function vn(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 Sn(n,e,t,r){let o=`/v1/voice/sessions/${s(e)}/admin`;return n.client.post(o,t,r?.signal)}async function xn(n,e,t){let r=`/v1/inventory/transfers/${s(e)}/cancel`;return n.client.post(r,void 0,t?.signal)}async function wn(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 kn(n,e,t){let r=`/v1/games/${s(n.gameId())}/game-rooms/${s(e)}`;return n.client.delete(r,t?.signal)}async function An(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 On(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 Pn(n,e,t){return n.client.post("/v1/voice/sessions",e,t?.signal)}async function Gn(n,e,t,r,o){let a=`/v1/settings/${s(e)}/${s(t)}/${s(r)}`;return n.client.delete(a,o?.signal)}async function Tn(n,e,t,r,o){let a=`/v1/saves/${s(e)}/${s(t)}/${s(r)}`;return n.client.delete(a,o?.signal)}async function Cn(n,e,t){let r=`/v1/voice/sessions/${s(e)}`;return n.client.delete(r,t?.signal)}async function In(n,e,t,r){let o=`/v1/showcase/players/${s(e)}/${s(t)}`;return n.client.delete(o,r?.signal)}async function En(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 qn(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 Mn(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 jn(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 Bn(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 Fn(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 Un(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 Dn(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 Nn(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 Hn(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 Vn(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 Wn(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 zn(n,e,t){let r=`/v1/events/${s(e)}`;return n.client.get(r,t?.signal)}async function Kn(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 Yn(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 Jn(n,e,t){let r=`/v1/profiles/players/${s(e)}`;return n.client.get(r,t?.signal)}async function Xn(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 Qn(n,e,t){let r=`/v1/game-room-templates/${s(e)}`;return n.client.get(r,t?.signal)}async function Zn(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 et(n,e,t,r){let o=`/v1/showcase/players/${s(e)}/${s(t)}`;return n.client.get(o,r?.signal)}async function nt(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 tt(n,e,t){return n.client.post("/v1/inventory/transfers",e,t?.signal)}async function rt(n,e,t){return n.client.postBytes("/v1/functions/invoke",e,t?.signal)}async function ot(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 at(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 st(n,e,t,r){let o=`/v1/settings/${s(e)}/${s(t)}`;return n.client.get(o,r?.signal)}async function it(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 lt(n,e,t,r){let o=`/v1/inventory/${s(e)}/${s(t)}/progressions`;return n.client.get(o,r?.signal)}async function dt(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 ut(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 ct(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 mt(n,e){return n.client.get("/v1/game-room-templates",e?.signal)}async function gt(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 pt(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 yt(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 ft(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 ht(n,e,t,r,o){let a=`/v1/showcase/players/${s(e)}/${s(t)}`;return n.client.put(a,r,o?.signal)}async function _t(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 Rt(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 vt(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 St(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 xt(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 wt(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 kt(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 Pt=1e4,Gt=50,Tt=1e3,Ct=65536-4*1024,he=n=>typeof n=="number"?n:0,It=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 Et(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:It(a.code)}}):[];return {accepted:he(t.accepted),rejected:r,dropped:e,duplicate:t.duplicate===true}}function be(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 Re(n){let e=Math.max(1,Math.floor(n.maxQueue??Tt)),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?.(_);},R=()=>{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(Pt,y())));},A=()=>{let _=Math.min(r.length,100),b=128;for(let G=0;G<_;G+=1){let T=r[G];if(T===void 0)break;if(b+=JSON.stringify(be(T,0)).length+1,b>Ct)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 b=Le(_);d=b;try{return await b}finally{d===b&&(d=null),r.length>0&&x();}}async function Le(_){R();let b=r.splice(0,A()),G=o;o=0;let T=Math.round(n.clock.now()),D={batch_id:_e(),sent_at_ms:T,events:b.map(k=>be(k,T))};try{let k=await X(t,D,_===void 0?void 0:{signal:_}),C=Lt(k,G);u=0,c=0;for(let qe of C.rejected)w(`[gem] analytics: an event was refused (${qe.code}). See the analytics_events section of your game config.`);return C}catch(k){if(Et(k)){for(r=[...b,...r],o+=G;r.length>e;)r.shift(),o+=1;u+=1,c=n.clock.now()+fe(u,k);}else w(`[gem] analytics: ${b.length} event(s) were discarded \u2014 the platform refused the batch and will refuse it again: ${String(k)}`);throw k}}return {track(_,b,G={}){if(i)return;if(typeof _!="string"||_===""){S||(S=true,w(`[gem] analytics: '${b}' 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(b.startsWith(ye)){g||(g=true,w(`[gem] analytics: '${b}' 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 T={},D={};for(let[k,C]of Object.entries(G))typeof C=="string"?T[k]=C:typeof C=="number"&&Number.isFinite(C)&&(D[k]=C);for(;r.length>=e;)r.shift(),o+=1;r.push({uid:_e(),playerId:_,name:b,atMs:n.clock.now(),dimensions:T,measures:D}),r.length>=Gt&&d===null&&y()===0?P().catch(()=>{}):x();},flush:_=>P(_),get pending(){return r.length},dispose(){i=true,R(),r=[],o=0;}}}var qt=new Map([["function_error",false],["function_failed",false],["function_timeout",false],["function_not_published",false],["function_input_too_large",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:qt.get(this.code))??super.retryable}},M=class{#e;constructor(e){this.#e=e;}async invoke(e,t={}){let r=Mt(e),o;try{o=await this.#e(r,t.signal===void 0?{}:{signal:t.signal});}catch(a){throw a instanceof p?jt(a):a}return $t(o)}};function Mt(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 $t(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 jt(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:"",Bt=/(?:Z|[+-]\d{2}:?\d{2})$/i;function ve(n){let e=O(n);if(!Bt.test(e))return 0;let t=Date.parse(e);return Number.isFinite(t)?Math.floor(t/1e3):0}var Ft=/^[0-9a-f]{1,64}$/,Ut=/^[0-9a-f]{16}$/,Dt=/^[A-Za-z][A-Za-z0-9_+\-/]{0,63}$/,Nt=/^(?:[01]\d|2[0-3]):[0-5]\d$/;function Ht(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 Vt=4096,Wt=new TextEncoder;function zt(n){let e=O(n.challenge_data),t=O(n.challenge_data_hash);return e===""||!Ut.test(t)?{}:Wt.encode(e).length>Vt?{}:{data:e,dataHash:t}}function Kt(n){let e=n??{},t=ve(e.period_start_at),r=ve(e.period_ends_at);if(t===0||r===0)return;let o=O(e.slug),a=O(e.seed),i=Ht(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:Dt.test(d)?d:"",resetTime:Nt.test(u)?u:"",seed:Ft.test(a)?a:"",...zt(e)}}function Se(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 xe(n){let e=n??{};return Array.isArray(e.challenges)?e.challenges.map(Kt).filter(t=>t!==void 0):[]}function we(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().");Se(r);let a=await n({player_id:t,...r===void 0?{}:{periods_back:r},...o===void 0?{}:{signal:o}});return xe(a)}}}function Yt(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??q,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 L({transport:a,clock:t}),d={gameId:n.gameId,channel:n.channel,matchId:n.matchId,...n.gameRoomId===void 0?{}:{gameRoomId:n.gameRoomId}},u=Yt({client:i,gameId:()=>d.gameId}),c=d.gameRoomId,g=n.endMatch,S=n.log,w=Re({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:we(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 Jt=["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"],Xt=new Set(Jt);function ke(n){return typeof n=="string"&&Xt.has(n)?n:"unknown"}var Pe="[gem: use gem.text.toPlain()]",Ae=new Set,Oe;function Qt(n){try{if(Ae.has(n))return;let e=globalThis.location;if(Oe??=!!e?.port&&ge(e.hostname??""),!Oe)return;Ae.add(n),console.warn(`[gem] ${n} is PlayerText, turned into a string: players see ${Pe}. 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 Qt(this.#n),Pe}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 Ge={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 Te="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??q,r=()=>{let d=n();if(d===null)throw new Error(Te);return d},o=null,a=()=>{if(o===null)throw new Error(Te);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 Ce(n,e={}){let{server:t,attach:r}=Z(()=>n,e);return r(),t}function Zt(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:ke(e)}}}var er=1e4;function nr(n){let e=false;return t=>{if(e)return;let r;try{r=n.match.reportPlayers([{playerId:t,state:"connected"}],AbortSignal.timeout(er));}catch{return}r.catch(o=>{o instanceof p&&o.status>=400&&o.status<500&&(e=o.status!==429);});}}function Ie(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=Zt(u);try{await a.shutdown?.(c);}finally{r.dispose();}}},d=nr(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 tr=new Set(["unlocked","already_unlocked","suppressed"]);function Ee(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"||!tr.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,L as GemClient,F as GemFunctionError,v as PlayerText,f as TransportRefusal,Ee as achievementReceipts,U as asPlayerText,z as createGemServer,pe as createHostTokenSource,Ce as createMatchServer,Ie as defineServer,q as systemClock,Ge as text,te as toBase64};//# sourceMappingURL=gem-web-sdk.server.js.map
1
+ var Me=Object.defineProperty;var je=(t,e)=>{for(var n in e)Me(t,n,{get:e[n],enumerable:true});};globalThis.__gemWebSdkVersion="[gem-web-sdk:sdkVersion:21.1.0]";var $e={initialDelayMs:2e3,maxDelayMs:6e4};function Be(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}=$e,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=Fe(o),{retryable:i,retryAfterMs:d}=o??{};throw n===this.generation&&(Be(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 Fe(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 Ue(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"?De(r):r;if(typeof a!="string"||a.length>ee||!Ne(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 De(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 Ne(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 He(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=Ue(o.headers),i=He(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(Ve(e))}function Ve(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 We=new Set([408,429,500,502,503,504]),ze=6e4,Ke=new WeakMap;function re(t){return t!==null&&(t.reason==="rate_limited"||t.retryAfterSeconds!==void 0)}function Ye(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,...j(o)},o.replaySafe===true,o.retryRateLimited!==false)}async post(e,n,r,o={}){return this.send({method:"POST",path:e,body:n,signal:r,...j(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,...j(o)},o.replaySafe===true,o.retryRateLimited!==false);return {bytes:Je(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,...j(o)},o.replaySafe===true,o.retryRateLimited!==false)}async delete(e,n,r={}){return this.send({method:"DELETE",path:e,signal:n,...j(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?Ye(this.options.maxRetries)+1:1,a=null;if(e.signal?.aborted)throw oe(e.signal);let i=e.signal===void 0?void 0:Ke.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||Xe(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=Qe(u);if(!We.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),ze)}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 Je(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 j(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 Xe(t){let e=t?.name;return e==="AbortError"||e==="TimeoutError"}function Qe(t){let e=et(t),n=nt(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 Ze=new Map([["insufficient_funds","insufficient_funds"]]);function et(t){let{status:e,body:n}=t,r=tt(n),o=t.retryAfterSeconds??ot(n),a=rt(n),i=a===void 0?void 0:Ze.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 tt(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 nt(t){let n=t?.error?.details;return n===null?void 0:n}function rt(t){let n=t?.error?.code;return typeof n=="string"&&n.length>0?n:void 0}function ot(t){let e=t?.retryAfterSeconds;return typeof e=="number"&&Number.isFinite(e)&&e>=0?e:void 0}function at(t){let e=t.lastIndexOf("@");return (e===-1?t:`***@${t.slice(e+1)}`).slice(0,200)}var st=new Set(H);function it(t){if(!t)return {};let e={};for(let[n,r]of Object.entries(t))st.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"?at(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 R=o.username!==""||o.password!=="",y=a.username!==o.username||a.password!==o.password,x=R?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[R,y]of Object.entries(t.defaultQuery??{}))a.searchParams.has(R)||a.searchParams.set(R,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(R){throw new f(`the body of ${n.method} ${JSON.stringify(a.pathname)} could not be serialised to JSON: ${String(R)}. 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},...it(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 R=await u.text();if(R.length>0)try{c=JSON.parse(R);}catch{c=R;}}let g=u.headers.get("etag"),S=lt(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 lt(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 dt="gem-web-bridge";var ut=65536,le=8,V=5e3,de=1024;var W=Object.create(null);var ue=Object.create(null);function ct(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 mt(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 gt(t){return /^[a-z]{2,8}(-[a-z0-9]{1,8})*$/i.test(t)}function pt(t){return /^[a-z_]+$/.test(t)}function yt(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 ft(t,e=ut){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 ht={origin:[ct,"not a well-formed origin"],url:[mt,"not a safe absolute http(s) URL"],bcp47:[gt,"not a well-formed BCP 47 tag"],code:[pt,"not a code of lower-case letters and underscores"],gameRef:[yt,"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]=ht[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=ft(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!==dt?"gem: wrong protocol marker":d.type!==t?`type: expected ${t}`: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.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],["expected","I",1,1e9],["origin","O",[["x","i",0,16384],["y","i",0,16384]]]],60,"rewardCue");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.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 _t=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??_t);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:()=>Rt,adminAction:()=>vt,cancelInventoryTransfer:()=>St,claimEntityProgressionRewards:()=>xt,closeGameRoom:()=>wt,createEntityBatchOrder:()=>kt,createEntityOrder:()=>At,createSession:()=>Ot,deleteEntityGameSetting:()=>Pt,deleteEntitySave:()=>Gt,deleteSession:()=>Tt,deleteShowcaseValue:()=>Ct,executeEntityRecipe:()=>It,finalizeSaveUpload:()=>Et,getChannelAssignment:()=>Lt,getDropRates:()=>qt,getEntityCurrency:()=>Mt,getEntityGameSetting:()=>jt,getEntityInventory:()=>$t,getEntityInventoryItem:()=>Bt,getEntityLeaderboard:()=>Ft,getEntityOrder:()=>Ut,getEntityProgression:()=>Dt,getEntityRecipeAvailability:()=>Nt,getEntityRecipeUsage:()=>Ht,getEntitySave:()=>Vt,getEvent:()=>Wt,getGameRoomV2:()=>zt,getLeaderboard:()=>Kt,getPlayerGameProfile:()=>Yt,getPurchaseCatalog:()=>Jt,getResolvedTemplate:()=>Xt,getRoomArgs:()=>Qt,getShowcaseValue:()=>Zt,getTransferDetails:()=>en,ingestAnalyticsEvents:()=>X,initiateInventoryTransfer:()=>tn,invokeFunction:()=>nn,kickPlayer:()=>rn,listChallenges:()=>on,listEntityGameSettings:()=>an,listEntityOrders:()=>sn,listEntityProgressions:()=>ln,listEntitySaves:()=>dn,listEvents:()=>un,listGameRooms:()=>cn,listResolvedTemplates:()=>mn,listTransfers:()=>gn,maxEntityProgression:()=>pn,putEntityGameSetting:()=>yn,putRoomArgs:()=>fn,putShowcaseValue:()=>hn,rejectTransfer:()=>_n,reportMatchPlayers:()=>bn,requestSaveUploadUrl:()=>Rn,resetEntityProgression:()=>vn,setMatchBackfill:()=>Sn,simulateEntityOrder:()=>xn,transferHostV2:()=>wn,updateGameRoomV2:()=>kn});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 Rt(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 vt(t,e,n,r){let o=`/v1/voice/sessions/${s(e)}/admin`;return t.client.post(o,n,r?.signal)}async function St(t,e,n){let r=`/v1/inventory/transfers/${s(e)}/cancel`;return t.client.post(r,void 0,n?.signal)}async function xt(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 wt(t,e,n){let r=`/v1/games/${s(t.gameId())}/game-rooms/${s(e)}`;return t.client.delete(r,n?.signal)}async function kt(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 At(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 Ot(t,e,n){return t.client.post("/v1/voice/sessions",e,n?.signal)}async function Pt(t,e,n,r,o){let a=`/v1/settings/${s(e)}/${s(n)}/${s(r)}`;return t.client.delete(a,o?.signal)}async function Gt(t,e,n,r,o){let a=`/v1/saves/${s(e)}/${s(n)}/${s(r)}`;return t.client.delete(a,o?.signal)}async function Tt(t,e,n){let r=`/v1/voice/sessions/${s(e)}`;return t.client.delete(r,n?.signal)}async function Ct(t,e,n,r){let o=`/v1/showcase/players/${s(e)}/${s(n)}`;return t.client.delete(o,r?.signal)}async function It(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 Et(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 Lt(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 qt(t,e,n){let r=`/v1/inventory/loot-tables/${s(e)}/drop-rates`;return t.client.get(r,n?.signal)}async function Mt(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 $t(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 Bt(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 Ft(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 Ut(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 Dt(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 Nt(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 Ht(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 Vt(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 Wt(t,e,n){let r=`/v1/events/${s(e)}`;return t.client.get(r,n?.signal)}async function zt(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 Kt(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 Yt(t,e,n){let r=`/v1/profiles/players/${s(e)}`;return t.client.get(r,n?.signal)}async function Jt(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 Xt(t,e,n){let r=`/v1/game-room-templates/${s(e)}`;return t.client.get(r,n?.signal)}async function Qt(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 Zt(t,e,n,r){let o=`/v1/showcase/players/${s(e)}/${s(n)}`;return t.client.get(o,r?.signal)}async function en(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 tn(t,e,n){return t.client.post("/v1/inventory/transfers",e,n?.signal)}async function nn(t,e,n){return t.client.postBytes("/v1/functions/invoke",e,n?.signal)}async function rn(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 on(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 an(t,e,n,r){let o=`/v1/settings/${s(e)}/${s(n)}`;return t.client.get(o,r?.signal)}async function sn(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 ln(t,e,n,r){let o=`/v1/inventory/${s(e)}/${s(n)}/progressions`;return t.client.get(o,r?.signal)}async function dn(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 un(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 cn(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 mn(t,e){return t.client.get("/v1/game-room-templates",e?.signal)}async function gn(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 pn(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 yn(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 fn(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 hn(t,e,n,r,o){let a=`/v1/showcase/players/${s(e)}/${s(n)}`;return t.client.put(a,r,o?.signal)}async function _n(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 Rn(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 vn(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 Sn(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 xn(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 wn(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 kn(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 Pn=1e4,Gn=50,Tn=1e3,Cn=65536-4*1024,he=t=>typeof t=="number"?t:0,In=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 En(t){return t?.retryable===true}function Ln(t,e){let n=t??{},r=Array.isArray(n.rejected)?n.rejected.map(o=>{let a=o??{};return {index:he(a.index),code:In(a.code)}}):[];return {accepted:he(n.accepted),rejected:r,dropped:e,duplicate:n.duplicate===true}}function be(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 Re(t){let e=Math.max(1,Math.floor(t.maxQueue??Tn)),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?.(_);},R=()=>{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(Pn,y())));},A=()=>{let _=Math.min(r.length,100),b=128;for(let G=0;G<_;G+=1){let C=r[G];if(C===void 0)break;if(b+=JSON.stringify(be(C,0)).length+1,b>Cn)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 b=Le(_);d=b;try{return await b}finally{d===b&&(d=null),r.length>0&&x();}}async function Le(_){R();let b=r.splice(0,A()),G=o;o=0;let C=Math.round(t.clock.now()),D={batch_id:_e(),sent_at_ms:C,events:b.map(k=>be(k,C))};try{let k=await X(n,D,_===void 0?void 0:{signal:_}),I=Ln(k,G);u=0,c=0;for(let qe of I.rejected)w(`[gem] analytics: an event was refused (${qe.code}). See the analytics_events section of your game config.`);return I}catch(k){if(En(k)){for(r=[...b,...r],o+=G;r.length>e;)r.shift(),o+=1;u+=1,c=t.clock.now()+fe(u,k);}else w(`[gem] analytics: ${b.length} event(s) were discarded \u2014 the platform refused the batch and will refuse it again: ${String(k)}`);throw k}}return {track(_,b,G={}){if(i)return;if(typeof _!="string"||_===""){S||(S=true,w(`[gem] analytics: '${b}' 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(b.startsWith(ye)){g||(g=true,w(`[gem] analytics: '${b}' 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:b,atMs:t.clock.now(),dimensions:C,measures:D}),r.length>=Gn&&d===null&&y()===0?P().catch(()=>{}):x();},flush:_=>P(_),get pending(){return r.length},dispose(){i=true,R(),r=[],o=0;}}}var qn=new Map([["function_error",false],["function_failed",false],["function_timeout",false],["function_not_published",false],["function_input_too_large",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:qn.get(this.code))??super.retryable}},M=class{#e;constructor(e){this.#e=e;}async invoke(e,n={}){let r=Mn(e),o;try{o=await this.#e(r,n.signal===void 0?{}:{signal:n.signal});}catch(a){throw a instanceof p?$n(a):a}return jn(o)}};function Mn(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 jn(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 $n(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:"",Bn=/(?:Z|[+-]\d{2}:?\d{2})$/i;function ve(t){let e=O(t);if(!Bn.test(e))return 0;let n=Date.parse(e);return Number.isFinite(n)?Math.floor(n/1e3):0}var Fn=/^[0-9a-f]{1,64}$/,Un=/^[0-9a-f]{16}$/,Dn=/^[A-Za-z][A-Za-z0-9_+\-/]{0,63}$/,Nn=/^(?:[01]\d|2[0-3]):[0-5]\d$/;function Hn(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 Vn=4096,Wn=new TextEncoder;function zn(t){let e=O(t.challenge_data),n=O(t.challenge_data_hash);return e===""||!Un.test(n)?{}:Wn.encode(e).length>Vn?{}:{data:e,dataHash:n}}function Kn(t){let e=t??{},n=ve(e.period_start_at),r=ve(e.period_ends_at);if(n===0||r===0)return;let o=O(e.slug),a=O(e.seed),i=Hn(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:Dn.test(d)?d:"",resetTime:Nn.test(u)?u:"",seed:Fn.test(a)?a:"",...zn(e)}}function Se(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 xe(t){let e=t??{};return Array.isArray(e.challenges)?e.challenges.map(Kn).filter(n=>n!==void 0):[]}function we(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().");Se(r);let a=await t({player_id:n,...r===void 0?{}:{periods_back:r},...o===void 0?{}:{signal:o}});return xe(a)}}}function Yn(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=Yn({client:i,gameId:()=>d.gameId}),c=d.gameRoomId,g=t.endMatch,S=t.log,w=Re({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:we(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 Jn=["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"],Xn=new Set(Jn);function ke(t){return typeof t=="string"&&Xn.has(t)?t:"unknown"}var Pe="[gem: use gem.text.toPlain()]",Ae=new Set,Oe;function Qn(t){try{if(Ae.has(t))return;let e=globalThis.location;if(Oe??=!!e?.port&&ge(e.hostname??""),!Oe)return;Ae.add(t),console.warn(`[gem] ${t} is PlayerText, turned into a string: players see ${Pe}. 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 Qn(this.#t),Pe}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 Ge={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 Te="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(Te);return d},o=null,a=()=>{if(o===null)throw new Error(Te);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 Ce(t,e={}){let{server:n,attach:r}=Z(()=>t,e);return r(),n}function Zn(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:ke(e)}}}var er=1e4;function tr(t){let e=false;return n=>{if(e)return;let r;try{r=t.match.reportPlayers([{playerId:n,state:"connected"}],AbortSignal.timeout(er));}catch{return}r.catch(o=>{o instanceof p&&o.status>=400&&o.status<500&&(e=o.status!==429);});}}function Ie(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=Zn(u);try{await a.shutdown?.(c);}finally{r.dispose();}}},d=tr(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 nr=new Set(["unlocked","already_unlocked","suppressed"]);function Ee(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"||!nr.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,Ee as achievementReceipts,U as asPlayerText,z as createGemServer,pe as createHostTokenSource,Ce as createMatchServer,Ie as defineServer,q as systemClock,Ge as text,ne as toBase64};//# sourceMappingURL=gem-web-sdk.server.js.map
3
3
  //# sourceMappingURL=gem-web-sdk.server.js.map