@indiegems/gem-web-sdk 20.0.0 → 20.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.
- package/CHANGELOG.md +14 -0
- package/dist/game.d.ts +51 -3
- package/dist/gem-web-sdk.bridge.js +2 -2
- package/dist/gem-web-sdk.conformance.js +3 -3
- package/dist/gem-web-sdk.esm.js +3 -3
- package/dist/gem-web-sdk.function.js +3 -3
- package/dist/gem-web-sdk.game.js +3 -3
- package/dist/gem-web-sdk.min.js +3 -3
- package/dist/gem-web-sdk.sdk.js +3 -3
- package/dist/gem-web-sdk.server.js +2 -2
- package/dist/index.d.ts +57 -6
- package/dist/sdk.d.ts +51 -3
- package/docs/api/api-reference-function.md +1 -1
- package/docs/api/api-reference-game.md +9 -8
- package/docs/api/api-reference-server.md +1 -1
- package/docs/api/reference.json +4 -4
- package/docs/changelog.md +14 -0
- package/docs/dedicated-server-flow.md +30 -2
- package/docs/getting-started.md +3 -3
- package/docs/manifest.json +14 -14
- package/docs/match-session.md +9 -0
- package/docs/p2p-and-parties.md +79 -6
- package/docs/server-bundles.md +2 -2
- package/docs/what-a-game-must-do.md +8 -5
- package/package.json +1 -1
- package/schema/bridge.v1.json +67 -2
- package/schema/capabilities.public.json +6 -0
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
globalThis.__gemWebSdkVersion="[gem-web-sdk:sdkVersion:20.0.0]";function dn(){let t=globalThis.__gemWebSdkVersion;if(typeof t!="string")return "";let e=t.lastIndexOf(":"),n=t.lastIndexOf("]");return e<0||n<=e+1?"":t.slice(e+1,n)}function d(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 un(t,e,n){let r=`/v1/inventory/transfers/${d(e)}/accept`;return t.client.post(r,void 0,n?.signal)}async function cn(t,e,n,r,i,a){let s=`/v1/inventory/${d(e)}/${d(n)}/progressions/${d(r)}/add`;return t.client.post(s,i,a?.signal)}async function pn(t,e,n){let r=`/v1/inventory/transfers/${d(e)}/cancel`;return t.client.post(r,void 0,n?.signal)}async function gn(t,e,n,r,i,a){let s=`/v1/inventory/${d(e)}/${d(n)}/progressions/${d(r)}/claim`;return t.client.post(s,i,a?.signal)}async function mn(t,e,n){return t.client.post("/v1/characters",e,n?.signal)}async function yn(t,e,n,r,i){let a=`/v1/inventory/${d(e)}/${d(n)}/orders/batch`;return t.client.post(a,r,i?.signal,{...i?.ifMatch===void 0?{}:{ifMatch:i.ifMatch}})}async function fn(t,e,n,r,i){let a=`/v1/inventory/${d(e)}/${d(n)}/orders`;return t.client.post(a,r,i?.signal,{...i?.ifMatch===void 0?{}:{ifMatch:i.ifMatch}})}async function hn(t,e,n,r,i){let a=`/v1/settings/${d(e)}/${d(n)}/${d(r)}`;return t.client.delete(a,i?.signal)}async function _n(t,e,n,r,i){let a=`/v1/saves/${d(e)}/${d(n)}/${d(r)}`;return t.client.delete(a,i?.signal)}async function bn(t,e,n,r){let i=`/v1/showcase/players/${d(e)}/${d(n)}`;return t.client.delete(i,r?.signal)}async function Rn(t,e,n,r,i){let a=`/v1/inventory/${d(e)}/${d(n)}/recipes/execute`;return t.client.post(a,r,i?.signal,{...i?.ifMatch===void 0?{}:{ifMatch:i.ifMatch}})}async function wn(t,e,n,r,i,a){let s=`/v1/saves/${d(e)}/${d(n)}/${d(r)}/finalize`;return t.client.post(s,i,a?.signal)}async function vn(t,e,n){let r=`/v1/characters/${d(e)}`;return t.client.get(r,n?.signal)}async function xn(t,e,n,r,i){let a=`/v1/settings/${d(e)}/${d(n)}/${d(r)}`;return t.client.getWithEtag(a,{...i?.signal===void 0?{}:{signal:i.signal},...i?.ifNoneMatch===void 0?{}:{ifNoneMatch:i.ifNoneMatch}})}async function Sn(t,e,n,r){let i=new URLSearchParams;r?.include_buckets!==void 0&&i.set("include_buckets",String(r?.include_buckets)),r?.include_custom_data!==void 0&&i.set("include_custom_data",String(r?.include_custom_data)),r?.currency_limit!==void 0&&i.set("currency_limit",String(r?.currency_limit)),r?.currency_cursor!==void 0&&i.set("currency_cursor",String(r?.currency_cursor)),r?.item_limit!==void 0&&i.set("item_limit",String(r?.item_limit)),r?.item_cursor!==void 0&&i.set("item_cursor",String(r?.item_cursor)),r?.progression_limit!==void 0&&i.set("progression_limit",String(r?.progression_limit)),r?.progression_cursor!==void 0&&i.set("progression_cursor",String(r?.progression_cursor));let a=i.toString(),s=`/v1/inventory/${d(e)}/${d(n)}`+(a?`?${a}`:"");return t.client.get(s,r?.signal)}async function kn(t,e,n,r,i){let a=`/v1/inventory/${d(e)}/${d(n)}/items/${d(r)}`;return t.client.get(a,i?.signal)}async function An(t,e,n,r,i){let a=new URLSearchParams;i?.bucket_1!==void 0&&a.set("bucket_1",String(i?.bucket_1)),i?.bucket_2!==void 0&&a.set("bucket_2",String(i?.bucket_2)),i?.limit!==void 0&&a.set("limit",String(i?.limit)),i?.periods_back!==void 0&&a.set("periods_back",String(i?.periods_back)),i?.period!==void 0&&a.set("period",String(i?.period)),i?.player_id!==void 0&&a.set("player_id",String(i?.player_id));let s=a.toString(),l=`/v1/leaderboards/${d(e)}/${d(n)}/${d(r)}`+(s?`?${s}`:"");return t.client.get(l,i?.signal)}async function Pn(t,e,n,r,i){let a=`/v1/inventory/${d(e)}/${d(n)}/orders/${d(r)}`;return t.client.get(a,i?.signal)}async function On(t,e,n,r,i){let a=`/v1/inventory/${d(e)}/${d(n)}/progressions/${d(r)}`;return t.client.get(a,i?.signal)}async function Cn(t,e,n,r,i,a){let s=`/v1/inventory/${d(e)}/${d(n)}/catalogs/${d(r)}/recipes/${d(i)}/availability`;return t.client.get(s,a?.signal)}async function Gn(t,e,n,r){let i=new URLSearchParams;i.set("limit",String(r?.limit));let a=i.toString(),s=`/v1/inventory/${d(e)}/${d(n)}/recipe-usage`+(a?`?${a}`:"");return t.client.get(s,r?.signal)}async function Me(t,e,n,r,i){let a=`/v1/saves/${d(e)}/${d(n)}/${d(r)}`;return t.client.getWithEtag(a,{...i?.signal===void 0?{}:{signal:i.signal},...i?.ifNoneMatch===void 0?{}:{ifNoneMatch:i.ifNoneMatch}})}async function In(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 i=r.toString(),a=`/v1/leaderboards/${d(e)}/friends`+(i?`?${i}`:"");return t.client.get(a,n?.signal)}async function Tn(t,e,n){let r=`/v1/showcase/friends/${d(e)}`;return t.client.get(r,n?.signal)}async function En(t,e,n){let r=`/v1/inbox/friend-challenges/${d(e)}`;return t.client.get(r,n?.signal)}async function Ln(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 i=r.toString(),a=`/v1/leaderboards/${d(e)}`+(i?`?${i}`:"");return t.client.get(a,n?.signal)}async function Mn(t,e){let n=`/v1/games/${d(t.gameId())}/players/me/earn-allowance`;return t.client.get(n,e?.signal)}async function qn(t,e){let n=`/v1/games/${d(t.gameId())}/players/me/passes`;return t.client.get(n,e?.signal)}async function fe(t,e){return t.client.get("/v1/inventory/players/me/platform-currencies",e?.signal)}async function Fn(t,e,n){let r=`/v1/profiles/players/${d(e)}`;return t.client.get(r,n?.signal)}async function $n(t,e){let n=new URLSearchParams;e?.config_version!==void 0&&n.set("config_version",String(e?.config_version));let r=n.toString(),i="/v1/inventory/platform-funded-game-inventory-purchase-catalog"+(r?`?${r}`:"");return t.client.get(i,e?.signal)}async function jn(t,e,n,r){let i=`/v1/showcase/players/${d(e)}/${d(n)}`;return t.client.get(i,r?.signal)}async function Nn(t,e){return t.client.get("/v1/characters/slots",e?.signal)}async function Bn(t,e,n){let r=`/v1/inventory/transfers/${d(e)}`;return t.client.get(r,n?.signal)}async function Dn(t,e,n){let r=`/v1/games/${d(t.gameId())}/analytics/events`;return t.client.post(r,e,n?.signal,{...n?.keepalive===void 0?{}:{keepalive:n.keepalive},replaySafe:true,retryRateLimited:false})}async function Un(t,e,n){return t.client.post("/v1/inventory/transfers",e,n?.signal)}async function Vn(t,e,n,r,i){let a=`/v1/inventory/${d(e)}/${d(n)}/platform-funded-game-inventory-purchases`;return t.client.post(a,r,i?.signal)}async function Wn(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(),i="/v1/challenges"+(r?`?${r}`:"");return t.client.get(i,e?.signal)}async function Hn(t,e){return t.client.get("/v1/characters",e?.signal)}async function Jn(t,e,n,r){let i=`/v1/settings/${d(e)}/${d(n)}`;return t.client.get(i,r?.signal)}async function zn(t,e,n,r){let i=new URLSearchParams;r?.limit!==void 0&&i.set("limit",String(r?.limit)),r?.cursor!==void 0&&i.set("cursor",String(r?.cursor));let a=i.toString(),s=`/v1/inventory/${d(e)}/${d(n)}/orders`+(a?`?${a}`:"");return t.client.get(s,r?.signal)}async function Kn(t,e,n,r){let i=new URLSearchParams;r?.limit!==void 0&&i.set("limit",String(r?.limit)),r?.cursor!==void 0&&i.set("cursor",String(r?.cursor));let a=i.toString(),s=`/v1/saves/${d(e)}/${d(n)}`+(a?`?${a}`:"");return t.client.get(s,r?.signal)}async function Yn(t,e){let n=new URLSearchParams;e?.cursor!==void 0&&n.set("cursor",String(e?.cursor)),e?.limit!==void 0&&n.set("limit",String(e?.limit));let r=n.toString(),i="/v1/inbox/friend-challenges"+(r?`?${r}`:"");return t.client.get(i,e?.signal)}async function Xn(t,e){let n=new URLSearchParams;e?.limit!==void 0&&n.set("limit",String(e?.limit)),e?.cursor!==void 0&&n.set("cursor",String(e?.cursor));let r=n.toString(),i="/v1/friends"+(r?`?${r}`:"");return t.client.get(i,e?.signal)}async function Qn(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(),i="/v1/inventory/transfers"+(r?`?${r}`:"");return t.client.get(i,e?.signal)}async function Zn(t,e,n){let r=`/v1/inbox/friend-challenges/${d(e)}/answered`;return t.client.post(r,void 0,n?.signal)}async function et(t,e,n,r,i,a){let s=`/v1/inventory/${d(e)}/${d(n)}/progressions/${d(r)}/max`;return t.client.post(s,i,a?.signal)}async function nt(t,e,n,r,i,a){let s=`/v1/settings/${d(e)}/${d(n)}/${d(r)}`;return t.client.put(s,i,a?.signal,{...a?.ifMatch===void 0?{}:{ifMatch:a.ifMatch}})}async function tt(t,e,n,r,i){let a=`/v1/showcase/players/${d(e)}/${d(n)}`;return t.client.put(a,r,i?.signal)}async function rt(t,e,n){let r=`/v1/inventory/transfers/${d(e)}/reject`;return t.client.post(r,void 0,n?.signal)}async function it(t,e,n,r){let i=`/v1/characters/${d(e)}`;return t.client.patch(i,n,r?.signal)}async function at(t,e,n,r,i,a){let s=`/v1/saves/${d(e)}/${d(n)}/${d(r)}/upload-url`;return t.client.post(s,i,a?.signal,{replaySafe:true})}async function st(t,e,n,r,i,a){let s=`/v1/inventory/${d(e)}/${d(n)}/progressions/${d(r)}/reset`;return t.client.post(s,i,a?.signal)}async function ot(t,e,n){let r=`/v1/characters/${d(e)}`;return t.client.delete(r,n?.signal)}function lt(t,e){let n=e?.retryAfterSeconds,r=typeof n=="number"&&Number.isFinite(n)&&n>0?n*1e3:0,i=1e4*2**Math.min(Math.max(0,t-1),16);return Math.min(Math.max(r,i),3e5)}var pr="gem_";function qe(t){return t.startsWith(pr)}function gr(t){let e=2166136261;for(let n of new TextEncoder().encode(t))e^=n,e=Math.imul(e,16777619);return e>>>0}function mr(t){let e=t;return e^=e>>>16,e=Math.imul(e,2246822507),e^=e>>>13,e=Math.imul(e,3266489909),e^=e>>>16,e>>>0}function Fe(t,e,n){if($e(t,n),typeof e!="string"||e==="")throw new TypeError("[gem] experiment: playerId must be a non-empty string");let r=typeof n=="number"?n:n.length,i=mr(gr(`${t}:${e}`))%r;return typeof n=="number"?i:n[i]}function $e(t,e){if(typeof t!="string"||t==="")throw new TypeError("[gem] experiment: key must be a non-empty string");if(typeof e=="number"){if(!Number.isInteger(e)||e<1||e>2048)throw new RangeError(`[gem] experiment '${t}': the count must be an integer from 1 to 2048; got ${String(e)}`);return}if(!Array.isArray(e))throw new TypeError(`[gem] experiment '${t}': pass a count or a list of strings; got ${typeof e}`);let n=e;if(n.length<1||n.length>2048)throw new RangeError(`[gem] experiment '${t}': the list must hold 1 to 2048 strings; got ${n.length}`);if(!n.every(r=>typeof r=="string"))throw new TypeError(`[gem] experiment '${t}': every option must be a string`)}var dt=1e4,ut=50,hr=500,_r=65536-4*1024,br=24*1024;function ct(t){let e={},n={};for(let[r,i]of Object.entries(t))typeof i=="string"?e[r]=i:typeof i=="number"&&Number.isFinite(i)&&(n[r]=i);return {dimensions:e,measures:n}}var Rr=6e4;function wr(t){let e=new Map;for(let n of t??[]){let r=new Set;for(let[i,a]of Object.entries(n.dimensions??{})){let s=a?.range;typeof s=="object"&&s!==null&&r.add(i);}r.size>0&&e.set(n.id,r);}return e}function vr(t,e){if(e===void 0)return t;let n=null,r={};for(let[i,a]of Object.entries(t.measures))e.has(i)?(n??={...t.dimensions})[i]=String(a):r[i]=a;return n===null?t:{dimensions:n,measures:r}}var pt=t=>typeof t=="number"?t:0,xr=t=>typeof t=="string"?t:"";function he(t=0){return {accepted:0,rejected:[],dropped:t,duplicate:false}}function Sr(t,e){let n=t??{},r=Array.isArray(n.rejected)?n.rejected.map(i=>{let a=i??{};return {index:pt(a.index),code:xr(a.code)}}):[];return {accepted:pt(n.accepted),rejected:r,dropped:e,duplicate:n.duplicate===true}}function je(){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 kr(t){return t?.retryable===true}var H=class{#e;#t;#a;#h;#n=[];#_={};#s=0;#o=null;#b=false;#R=false;#p=0;#w=0;#v=0;#r=false;#x=null;#l=null;#u=false;#i=false;#g=false;#S=false;#k=false;#m=void 0;#A=false;#P=0;constructor(e){this.#e=e,this.#t=e.options?.enabled!==false,this.#a=Math.max(dt,e.options?.flushIntervalMs??dt),this.#h=Math.max(1,Math.floor(e.options?.maxQueue??hr));}track(e,n={}){if(!this.#t||this.#r)return;if(qe(e)){this.#k||(this.#k=true,this.#f(`[gem] analytics: '${e}' was not recorded \u2014 the gem_ prefix is reserved for the platform's own events, which the SDK emits for you. Name your event something else.`));return}this.#O(e,ct({...this.#_,...n}));let r=this.#I();this.#m===void 0&&!this.#A&&r!==null&&r!==""&&(this.#A=true,this.#T());}setContext(e){this.#_={...this.#_,...e};}async experiment(e,n){$e(e,n);let r=this.#e.awaitPlayerId===void 0?this.#e.playerId():await this.#e.awaitPlayerId();if(r===null)throw new Error(`[gem] experiment '${e}': no player to select for \u2014 this call was not made by a player.`);return typeof n=="number"?Fe(e,r,n):Fe(e,r,n)}get environment(){let e=this.#e.environment;return {...typeof e=="function"?e():e??{}}}async flush(e={}){if(this.#i)return he();let n=this.#I();if(n===null||n==="")return this.#n.length>0&&!this.#S&&(this.#S=true,this.#f("[gem] analytics: events are being recorded but no play session has been established, so nothing is being sent. Outside the arcade this is expected.")),he();let r=e.keepalive===true;if(!r&&this.#e.declarations!==void 0&&this.#n.some(c=>!qe(c.name))&&await this.#T(),this.#G(),this.#n.length===0||this.#p>0&&!r)return he();this.#c();let i=this.#n.splice(0,this.#L(r)),a=this.#s;this.#s=0;let s=Math.round(this.#e.clock.now()),l={batch_id:je(),sent_at_ms:s,events:i.map(c=>gt(c,s,this.#m?.get(c.name)))},o={client:this.#e.client(),gameId:()=>n};this.#p+=1;try{let c=await Dn(o,l,{...e.signal===void 0?{}:{signal:e.signal},...r?{keepalive:!0}:{}}),p=Sr(c,a);return this.#w=0,this.#v=0,this.#M(p),p}catch(c){throw kr(c)?(this.#E(i,a),this.#w+=1,this.#v=this.#e.clock.now()+lt(this.#w,c)):this.#f(`[gem] analytics: ${i.length} event(s) were discarded \u2014 the platform refused the batch and will refuse it again: ${String(c)}`),c}finally{this.#p-=1,this.#n.length>0&&this.#d();}}trackPlatform(e,n={}){this.#r||this.#i&&(e==="gem_pause"||e==="gem_resume")||this.#O(e,ct(n));}hold(){this.#r||this.#l!==null||(this.#i=true,this.#c());}release(){if(!this.#i||this.#r)return;this.#i=false;let e=this.#e.clock.now(),n=this.#n.map(r=>({...r,atMs:e}));this.#n=n,this.#g&&(this.#g=false,this.#l=e,this.#u=false,this.#n.unshift({uid:je(),name:"gem_session_start",atMs:e,dimensions:{},measures:{}})),this.#n.length>=ut?this.#y():this.#n.length>0&&this.#d();}get held(){return this.#i}startSession(){if(!(this.#r||this.#l!==null)){if(this.#i){this.#g=true;return}this.#l=this.#e.clock.now(),this.#u=false,this.trackPlatform("gem_session_start");}}endSession(e){if(this.#r||this.#u)return;if(this.#u=true,this.#i){this.#g=false,this.#n=[],this.#s=0;return}let n=this.#l;this.trackPlatform("gem_session_end",{reason:e,...n===null?{}:{duration_ms:Math.max(0,Math.round(this.#e.clock.now()-n))}}),this.#y({keepalive:true});}setPaused(e){this.#r||e===this.#b||(this.#b=e,this.trackPlatform(e?"gem_pause":"gem_resume"),e?this.#c():this.#n.length>0&&this.#d());}setHidden(e){this.#r||e===this.#R||(this.#R=e,e?this.#c():this.#n.length>0&&this.#d());}dispose(){this.#r=true,this.#c(),this.#n=[],this.#s=0;}get pending(){return this.#n.length}#O(e,n){let{dimensions:r,measures:i}=n;for(this.#G();this.#n.length>=this.#h;)this.#n.shift(),this.#s+=1;this.#n.push({uid:je(),name:e,atMs:this.#e.clock.now(),dimensions:r,measures:i}),this.#n.length>=ut?this.#y():this.#d();}#y(e={}){if(e.keepalive!==true&&this.#C()>0){this.#d();return}this.flush(e).catch(()=>{});}#C(){return Math.max(0,this.#v-this.#e.clock.now())}#E(e,n){for(this.#n=[...e,...this.#n],this.#s+=n;this.#n.length>this.#h;)this.#n.shift(),this.#s+=1;}#L(e){let n=e?br:_r,r=Math.min(this.#n.length,100),i=128;for(let a=0;a<r;a+=1){let s=this.#n[a];if(s===void 0)break;if(i+=JSON.stringify(gt(s,0,this.#m?.get(s.name))).length+1,i>n)return Math.max(1,a)}return r}#d(){this.#o!==null||this.#b||this.#R||this.#i||this.#r||this.#p>0||(this.#o=this.#e.clock.setTimeout(()=>{this.#o=null,this.#y();},Math.max(this.#a,this.#C())));}#c(){this.#o!==null&&(this.#e.clock.clearTimeout(this.#o),this.#o=null);}#G(){let e=this.#q();e===null||e===""||(this.#x!==null&&this.#x!==e&&(this.#n=[],this.#s=0,this.#l=null,this.#u=false),this.#x=e);}#M(e){for(let n of e.rejected)this.#f(`[gem] analytics: an event was refused (${n.code}). `+Ar(n.code));}#f(e){let n=this.#e.log;n!==null&&(n===void 0?console.warn(e):n(e));}#I(){try{return this.#e.gameId()}catch{return null}}#q(){try{return this.#e.playerId()}catch{return null}}async#T(){let e=this.#e.declarations;if(e!==void 0&&!(this.#e.clock.now()<this.#P))try{this.#m=wr(await e());}catch{this.#P=this.#e.clock.now()+Rr;}}};function gt(t,e,n){let{dimensions:r,measures:i}=vr(t,n);return {event_uid:t.uid,name:t.name,offset_ms:Math.round(t.atMs)-e,dimensions:r,measures:i}}function Ar(t){switch(t){case "analytics_not_declared":return "This channel has no analytics_events section at all \u2014 promote a game config that declares one. The gem_* events in the same batch were still recorded.";case "unknown_event":return "This channel declares a set of events and this name is not in it \u2014 check the spelling, or declare it in analytics_events.";case "unknown_dimension":return "A string property on this event is not declared as one of its dimensions.";case "missing_dimension":return "A dimension this event declares was not supplied.";case "dimension_value_not_declared":return "A dimension value is outside the closed set the config declares for it.";case "unknown_measure":return "A numeric property on this event is not declared as one of its measures.";case "measure_wrong_type":return "A measure was the wrong shape \u2014 an int measure refuses a fractional value.";case "source_not_permitted":return "This event is declared for the server only, so a client may not emit it.";default:return "See the analytics_events section of your game config."}}var Pr={initialDelayMs:2e3,maxDelayMs:6e4};function Or(t,e){return e!==void 0?!e:t==="chain_exhausted"}var _e=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 x(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 x("chain_exhausted","the token chain reached its ceiling");if(this.inFlight===null&&this.options.clock.now()<this.notBefore)throw new x(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}=Pr,i=Math.min(r,n*2**(this.failures-1)),a=Math.max(i/2,e??0)+Math.random()*(i/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(i=>{if(n!==this.generation)throw new x("internal","token arrived for a superseded generation");return this.grant=i,this.rejected=false,this.enter("ready"),i.token}).catch(i=>{let a=Cr(i),{retryable:s,retryAfterMs:l}=i??{};throw n===this.generation&&(Or(a,typeof s=="boolean"?s:void 0)?this.enter("lost",a):(this.scheduleRetry(typeof l=="number"&&Number.isFinite(l)&&l>0?l:void 0),this.enter("degraded",a))),i instanceof x?i:new x(a,String(i))}).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)}},x=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 Cr(t){if(t instanceof x)return t.reason;let e=t?.reason;return typeof e=="string"&&["chain_exhausted","unavailable","timeout","internal"].includes(e)?e:"internal"}var v=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}},N=["if-match","if-none-match"],mt=4096;function Gr(t){if(!t)return;let e={};for(let[n,r]of Object.entries(t)){let i=n.toLowerCase();if(!N.includes(i)||r===void 0)continue;let a=typeof r=="string"?Ir(r):r;if(typeof a!="string"||a.length>mt||!Tr(a))throw new v(`the ${i} header value cannot be sent \u2014 it is not a string, is longer than ${mt} 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[i]=a);}return Object.freeze(e)}function Ir(t){let e=i=>i===32||i===9||i===10||i===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 Tr(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 Er(t){let{bytes:e}=t;if(e!==void 0){if(Object.prototype.toString.call(e)!=="[object Uint8Array]")throw new v("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 v("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 yt(t,e){let n=e.replayUnauthorizedOnce??true;return {async request(r){let i={...r},a=Gr(i.headers),s=Er(i),l=Object.freeze({...i,headers:a,...s===void 0?{}:{bytes:s}}),o=await e.tokenSource.get(),c=await t(l,o);if(c.status!==401||!n)return c;e.tokenSource.invalidate(o);let p=await e.tokenSource.get(),g=await t(l,p);if(g.status===401)throw e.tokenSource.close("unavailable"),new x("unavailable","the server refused a freshly minted token");return g}}}function be(t){let e=typeof t=="string"?new TextEncoder().encode(t):t;return btoa(Lr(e))}function ft(t){let e=atob(t),n=new Uint8Array(e.length);for(let r=0;r<e.length;r+=1)n[r]=e.charCodeAt(r);return n}function Ne(t){return new TextDecoder().decode(ft(t))}function Lr(t){let n="";for(let r=0;r<t.length;r+=32768)n+=String.fromCharCode(...t.subarray(r,r+32768));return n}var f=class extends Error{constructor(n,r,i,a,s){super(`${n} (${r}): ${i}`);this.reason=n;this.status=r;this.detail=i;this.retryAfterSeconds=a;this.code=s;this.name="GemApiError";}reason;status;detail;retryAfterSeconds;code;get retryable(){return this.reason==="unavailable"||this.reason==="rate_limited"}},Mr=new WeakMap;var qr=new Set([408,429,500,502,503,504]),Fr=6e4,bt=new WeakMap;function Rt(t,e){bt.set(t,e);}function ht(t){return t!==null&&(t.reason==="rate_limited"||t.retryAfterSeconds!==void 0)}function $r(t){if(t===void 0)return 2;if(!Number.isInteger(t)||t<0||t>10)throw new v(`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 z=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),i=r.etag===void 0?{}:{etag:r.etag};return r.status===304?{modified:false,...i}:{modified:true,body:r.body,...i}}async put(e,n,r,i={}){return this.send({method:"PUT",path:e,body:n,signal:r,...J(i)},i.replaySafe===true,i.retryRateLimited!==false)}async post(e,n,r,i={}){return this.send({method:"POST",path:e,body:n,signal:r,...J(i)},i.replaySafe===true,i.retryRateLimited!==false)}async postBytes(e,n,r,i={}){let a=await this.sendRaw({method:"POST",path:e,bytes:n,responseType:"bytes",signal:r,...J(i)},i.replaySafe===true,i.retryRateLimited!==false);return {bytes:jr(a.body),...a.invocationId===void 0?{}:{invocationId:a.invocationId}}}async patch(e,n,r,i={}){return this.send({method:"PATCH",path:e,body:n,signal:r,...J(i)},i.replaySafe===true,i.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 i=n?$r(this.options.maxRetries)+1:1,a=null;if(e.signal?.aborted)throw _t(e.signal);let s=e.signal===void 0?void 0:bt.get(e.signal);for(let l=0;l<i;l++){if(l>0){let p=this.backoffMs(l,a);if(ht(a)&&s!==void 0&&p>=s())throw a;await this.backoff(p,e.signal);}if(e.signal?.aborted)throw ht(a)&&s!==void 0&&s()<=0?a:_t(e.signal);let o;try{o=await this.options.transport.request(e);}catch(p){if(x.isAuthError(p)||v.isRefusal(p)||e.signal?.aborted||Nr(p))throw p;a=new f("unavailable",0,String(p));continue}if(o.status>=200&&o.status<300||o.status===304)return o;let c=Br(o);if(!qr.has(o.status)||o.status===429&&!r)throw c;a=c;}throw a??new f("unavailable",0,"no attempt was made")}backoffMs(e,n){let r=n?.retryAfterSeconds,i=r!==void 0?r*1e3:2**(e-1)*250,a=2**(e-1)*250;return Math.min(Math.max(i,a),Fr)}backoff(e,n){return n?.aborted?Promise.resolve():new Promise(r=>{let i=this.options.clock,a=false,s=false,l,o=()=>{a||(a=true,s&&i.clearTimeout(l),n?.removeEventListener("abort",o),r());};n?.addEventListener("abort",o,{once:true}),l=i.setTimeout(o,e),s=true,a&&i.clearTimeout(l);})}};function jr(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 _t(t){return t.reason!==void 0?t.reason:new DOMException("The operation was aborted.","AbortError")}function Nr(t){let e=t?.name;return e==="AbortError"||e==="TimeoutError"}function Br(t){let e=Ur(t),n=Wr(t.body),r={...n===void 0?{}:{details:n},...t.invocationId===void 0?{}:{invocationId:t.invocationId}};return Object.keys(r).length>0&&Mr.set(e,r),e}var Dr=new Map([["insufficient_funds","insufficient_funds"]]);function Ur(t){let{status:e,body:n}=t,r=Vr(n),i=t.retryAfterSeconds??Jr(n),a=Hr(n),s=a===void 0?void 0:Dr.get(a);if(s!==void 0)return new f(s,e,r,void 0,a);switch(e){case 304:return new f("not_modified",e,r);case 400:case 422:return new f("invalid",e,r,void 0,a);case 403:return new f("forbidden",e,r,void 0,a);case 404:return new f("not_found",e,r,void 0,a);case 402:return new f("insufficient_funds",e,r,void 0,a);case 409:return new f("conflict",e,r,void 0,a);case 412:return new f("precondition_failed",e,r,void 0,a);case 413:return new f("too_large",e,r,void 0,a);case 429:return new f("rate_limited",e,r,i,a);default:return new f("unavailable",e,r,i,a)}}function Vr(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 Wr(t){let n=t?.error?.details;return n===null?void 0:n}function Hr(t){let n=t?.error?.code;return typeof n=="string"&&n.length>0?n:void 0}function Jr(t){let e=t?.retryAfterSeconds;return typeof e=="number"&&Number.isFinite(e)&&e>=0?e:void 0}function zr(t){let e=t.lastIndexOf("@");return (e===-1?t:`***@${t.slice(e+1)}`).slice(0,200)}var Kr=new Set(N);function Yr(t){if(!t)return {};let e={};for(let[n,r]of Object.entries(t))Kr.has(n.toLowerCase())&&(e[n.toLowerCase()]=r);return e}function wt(t){let e=t.fetch??globalThis.fetch.bind(globalThis);return yt(async(n,r)=>{let i;try{i=new URL(t.baseUrl.replace(/\/+$/,""));}catch{throw new v("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(i.href.replace(/\/+$/,"")+n.path);}catch{throw new v(`${JSON.stringify(typeof n.path=="string"?zr(n.path):"(a non-string path)")} does not form a valid URL against ${i.protocol}//${i.host}. This is a malformed request, not a server failure.`)}if(a.protocol!==i.protocol||a.host!==i.host)throw new v(`${JSON.stringify(a.pathname)} resolves to ${a.protocol}//${a.host}, not ${i.protocol}//${i.host}. A request path may not change the request's origin \u2014 it carries the play token.`);if(a.username!==""||a.password!==""){let y=i.username!==""||i.password!=="",_=a.username!==i.username||a.password!==i.password,j=y?_?"baseUrl (and possibly the request path)":"baseUrl":"request path";throw new v(`the ${j} 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[y,_]of Object.entries(t.defaultQuery??{}))a.searchParams.has(y)||a.searchParams.set(y,_);let s=n.bytes,l=n.bytes===void 0?void 0:"application/octet-stream";try{n.body!==void 0&&(s=JSON.stringify(n.body),l="application/json");}catch(y){throw new v(`the body of ${n.method} ${JSON.stringify(a.pathname)} could not be serialised to JSON: ${String(y)}. This is a bug in the request, not a server failure \u2014 retrying sends the same unserialisable value.`)}let o=await e(a.toString(),{method:n.method,headers:{authorization:`Bearer ${r}`,...l===void 0?{}:{"content-type":l},...Yr(n.headers)},body:s,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"&&o.status>=200&&o.status<300)c=new Uint8Array(await o.arrayBuffer());else {let y=await o.text();if(y.length>0)try{c=JSON.parse(y);}catch{c=y;}}let p=o.headers.get("etag"),g=Be(o.headers.get("retry-after")),h=o.headers.get("x-gem-invocation-id");return {status:o.status,body:c,...p===null?{}:{etag:p},...g===void 0?{}:{retryAfterSeconds:g},...h===null||h===""?{}:{invocationId:h}}},t)}function Be(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 vt=400,P=t=>typeof t=="string"?t:"",Xr=/(?:Z|[+-]\d{2}:?\d{2})$/i;function L(t){let e=P(t);if(!Xr.test(e))return 0;let n=Date.parse(e);return Number.isFinite(n)?Math.floor(n/1e3):0}var Qr=/^[0-9a-f]{1,64}$/,Zr=/^[0-9a-f]{16}$/,ei=/^[A-Za-z][A-Za-z0-9_+\-/]{0,63}$/,ni=/^(?:[01]\d|2[0-3]):[0-5]\d$/;function De(t){let e=P(t),n=/^(\d{4})-(\d{2})-(\d{2})$/.exec(e);if(!n)return;let[r,i,a]=[Number(n[1]),Number(n[2]),Number(n[3])],s=new Date(Date.UTC(r,i-1,a));return s.getUTCFullYear()===r&&s.getUTCMonth()===i-1&&s.getUTCDate()===a?e:void 0}var ti=4096,ri=new TextEncoder;function ii(t){let e=P(t.challenge_data),n=P(t.challenge_data_hash);return e===""||!Zr.test(n)?{}:ri.encode(e).length>ti?{}:{data:e,dataHash:n}}function ai(t){let e=t??{},n=L(e.period_start_at),r=L(e.period_ends_at);if(n===0||r===0)return;let i=P(e.slug),a=P(e.seed),s=De(e.period_local_date),l=P(e.boundary),o=P(e.reset_time);return {id:P(e.progression_definition_id),...i===""?{}:{slug:i},window:P(e.window),periodStartAt:n,periodEndsAt:r,...s===void 0?{}:{periodLocalDate:s},boundary:ei.test(l)?l:"",resetTime:ni.test(o)?o:"",seed:Qr.test(a)?a:"",...ii(e)}}function Re(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 xt(t){let e=t??{};return Array.isArray(e.challenges)?e.challenges.map(ai).filter(n=>n!==void 0):[]}var K=class{#e;constructor(e){this.#e=e;}async list(e={}){let{periodsBack:n}=e;Re(n);let r=await Wn(this.#e,{...n===void 0?{}:{periods_back:n},...e.signal===void 0?{}:{signal:e.signal}});return xt(r)}};var si="gem-web-bridge";var oi=65536,St=8,we=5e3,kt=1024;var ve=Object.create(null);var At=Object.create(null);function li(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 di(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 ui(t){return /^[a-z]{2,8}(-[a-z0-9]{1,8})*$/i.test(t)}function ci(t){return /^[a-z_]+$/.test(t)}function pi(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 Ue(t,e,n){if(e>St)return `nesting deeper than ${St}`;if(++n.nodes>we)return `more than ${we} 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 i=t;if(n.seen.has(i))return "a repeated or cyclic object reference";if(n.seen.add(i),Array.isArray(t)){if(t.length>kt)return `an array of ${t.length} entries, over the ${kt} limit`;n.bytes+=2;for(let l of t){let o=Ue(l,e+1,n);if(o)return o}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 s=t;for(let l in s){if(!Object.prototype.hasOwnProperty.call(s,l))continue;if(++n.nodes>we)return `more than ${we} values`;if(n.bytes+=l.length*3+4,n.bytes>n.cap)return `over the ${n.cap} byte limit`;let o=Ue(s[l],e+1,n);if(o)return o}return null}function gi(t,e=oi){let n={nodes:0,bytes:0,seen:new Set,cap:e},r=Ue(t,0,n);return r?`message contains ${r}`:n.bytes>e?`message is over the ${e} byte limit`:null}var mi={origin:[li,"not a well-formed origin"],url:[di,"not a safe absolute http(s) URL"],bcp47:[ui,"not a well-formed BCP 47 tag"],code:[ci,"not a code of lower-case letters and underscores"],gameRef:[pi,"not a game id or web address"]};function Pt(t,e,n){for(let r of e){let i=n===""?r[0]:`${n}.${r[0]}`,a=t[r[0]];if(a==null){if(r[1]<"a")continue;return `${i}: required`}let s=Ve(a,r,i);if(s)return s}return null}function Ve(t,e,n){let r=e[1].toLowerCase();switch(r){case "u":return typeof t=="boolean"?null:Ve(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[i,a]=mi[e[3]];if(!i(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 i=e[2];return i.includes(t)?null:`${n}: not one of ${i.join("|")}`}case "o":return typeof t!="object"||t===null||Array.isArray(t)?`${n}: expected object`:Pt(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 i=e[3],a=`${n}[]`;for(let s of t){if(s==null){if(i[1]<"a")continue;return `${a}: required`}let l=Ve(s,i,a);if(l)return l}return null}default:return `${n}: unknown kind ${String(r)}`}}var Ot=Object.create(null);function u(t,e,n,r,i){return ve[t]=n,r&&(At[t]=r),Ot[t]=a=>{let s=gi(a,i);if(s)return s;if(typeof a!="object"||a===null||Array.isArray(a))return "message: expected object";let l=a;return l.gem!==si?"gem: wrong protocol marker":l.type!==t?`type: expected ${t}`:Pt(l,e,"")}}var m=["requestId","s",64],T=["outcome","e",["ok","declined","unavailable"]],E=["reason","S",64,"code"];u("gem.handshake",[["versions","o",[["min","i",1,1e3],["max","i",1,1e3]]],["capabilities","A",64,["","s",64]],["embedder","s",2048,"origin"],["unbidden","B"]],30);u("gem.handshake.accept",[["v","i",1,1e3],["capabilities","A",64,["","s",64]]],5);u("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);u("gem.token.denied",[m,["retryable","b"],["retryAfterMs","I",0,36e5],["reason","e",["chain_exhausted","unavailable"]],["correlationId","s",64]],30);u("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);u("gem.pause",[["paused","b"]],120);u("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);u("gem.cohorts",[["cohorts","a",8,["","o",[["experimentId","s",36],["variantKey","s",32]]]]],12,"cohorts");u("gem.earnAllowanceChanged",[],30,"earnAllowance");u("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");u("gem.deviceSettings",[["settings","J"]],12,"deviceSettings");u("gem.willTerminate",[["reason","e",["grant_expiring","session_ended","navigating","kill_switch"]],["graceMs","i",0,6e4]],10);u("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");u("gem.socketState",[["connected","b"],["reason","E",["connecting","dropped","watchdog","terminal"]]],12,"socketState");u("gem.seatedEvent",[["roomId","s",64]],60,"partySeating");u("gem.autoStartFailedEvent",[["roomId","s",64],["code","s",64]],30,"autoStartFailure");u("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");u("gem.signalEvent",[["event","e",["hello","offer","answer","ice","peerJoined","peerLeft","migration","matchEnded","error"]],["matchId","s",64],["data","j"]],1800,"p2p");u("gem.dedicatedEvent",[["event","e",["answer","error","matchEnded"]],["matchId","s",64],["sdp","S",10240],["sessionId","S",64],["code","S",64],["message","S",256],["reason","S",64]],120,"dedicated");u("gem.partyResult",[m,["partyId","S",64]],30,"parties");u("gem.clusterTarget",[["clusterTargetId","s",64],["clusterTargetIds","A",3,["","s",64]]],12,"clusterTarget");u("gem.devtools",[["action","e",["open","close","toggle"]]],30,"devtools");u("gem.screenshot",[["maxWidth","i",1,7680],["maxHeight","i",1,4320]],6,"screenshot");u("gem.screenshot.denied",[["reason","e",["not_wired","no_source","unsupported","unreadable","tainted","too_large","busy","declined","failed"]],["retryable","b"]],12,"screenshot");u("gem.requestContext",[],12,"feedbackContext");u("gem.gameContext",[["context","j"]],12,"feedbackContext");u("gem.signal",[["signal","e",["join","offer","answer","ice","migrationAck","hostUnreachable"]],["matchId","s",64],["data","j"]],1200,"p2p");u("gem.dedicatedOffer",[["matchId","s",64],["sdp","s",10240],["intent","e",["initial","ice_restart","full_reconnect"]]],60,"dedicated");u("gem.partyRequest",[m],12,"parties");u("gem.ready",[],5);u("gem.engaged",[],5,"engagement");u("gem.progress",[["loaded","i",0,1099511627776],["total","i",0,1099511627776]],600);u("gem.requestToken",[m,["reason","e",["initial","expiring","rejected"]]],12);u("gem.requestLocalServer",[m,["gameRoomId","s",64]],6,"localHost");u("gem.localServer",[m,["serverId","S",128]],30,"localHost");u("gem.localServer.denied",[m,["retryable","b"],["reason","e",["refused","unavailable"]]],30,"localHost");u("gem.exit",[["reason","S",64]],5);u("gem.openExternal",[["url","s",2048,"url"]],6);u("gem.requestFullscreen",[["enabled","b"]],30);u("gem.audioState",[["muted","b"]],120,"audioState");u("gem.rewardCue",[["currencySlug","s",32],["expected","I",1,1e9],["origin","O",[["x","i",0,16384],["y","i",0,16384]]]],60,"rewardCue");u("gem.walletDisplay",[["visible","b"],["currencies","A",8,["","s",64]],["score","B"]],60,"walletDisplay");u("gem.controlsDeclare",[["uses","o",[["lookSensitivity","S",16,"code"],["gamepadLookSensitivity","S",16,"code"],["invertLookY","S",16,"code"],["touchMovement","S",16,"code"]]]],60,"controls");u("gem.menu",[["settings","b"],["items","A",4,["","o",[["id","s",32],["label","s",40]]]]],60,"gameMenu");u("gem.menuSelect",[["entry","e",["settings","item"]],["id","S",32]],60,"gameMenu");u("gem.gemCorner",[["corner","e",["top-left","top-right","bottom-left","bottom-right"]]],12,"gemCorner");u("gem.menuStyle",[["ground","S",7],["accent","S",7]],12,"menuStyle");u("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");u("gem.settingChange",[["id","s",40],["value","u",40,-1e6,1e6]],120,"gameSettings");u("gem.requestShare",[["params","a",16,["","o",[["key","s",64],["value","s",512]]]]],6,"share");u("gem.requestAvatarPicker",[["tab","E",["2d","3d"]]],6,"avatarPicker");u("gem.vibrate",[["pattern","a",99,["","i",0,1e4]]],600,"vibration");u("gem.frameStats",[["fps","i",0,1e3],["frameTimeP95Ms","i",0,1e5],["counts","E",["pageFrames","gameDraws"]]],120,"frameStats");u("gem.portraitBorders",[["name","S",40]],60,"portraitBorders");u("gem.error",[["code","e",["version_mismatch","handshake_timeout","handshake_duplicate","invalid_message","rate_limited","token_unavailable","unsupported","unsupported_capability","internal"]],["message","S",256]],60);u("gem.requestPurchase",[m,["purchaseKind","e",["item","recipe"]],["targetId","s",64],["currencySlug","s",32],["quantity","I",1,10],["catalogId","S",64]],12,"purchases");u("gem.requestAvatar3dPurchase",[m,["itemId","s",64],["currencySlug","s",32]],12,"avatar3dPurchases");u("gem.purchaseResult",[m,T,E,["purchaseId","S",64]],30,"purchases");u("gem.deviceSettings.put",[m,["settings","j"]],30,"deviceSettings");u("gem.deviceSettings.result",[m,["outcome","e",["stored","too_large","unavailable"]]],30,"deviceSettings");u("gem.requestAd",[m,["placement","s",32],["format","e",["interstitial","rewarded"]]],6,"ads");u("gem.adResult",[m,["outcome","e",["shown","no_ad","unavailable"]]],12,"ads");u("gem.signalMoment",[m,["kind","e",["level_end","run_end","match_end","menu_return","other_break"]],["placement","S",32],["wall","B"]],6,"moments");u("gem.momentResult",[m,["shown","b"]],12,"moments");u("gem.requestSignIn",[m],6,"signIn");u("gem.signInResult",[m,["outcome","e",["signed_in","declined","unavailable"]]],12,"signIn");u("gem.requestFriendChallenge",[m,["playerId","s",64],["template","s",64],["params","J"]],12,"friendChallenges");u("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");u("gem.requestAppLinks",[m],12,"appLinks");u("gem.appLinksResult",[m,T,E,["arcade","O",[["store","e",["app_store","google_play"]]]],["game","O",[["store","e",["app_store","google_play"]]]]],30,"appLinks");u("gem.requestOpenApp",[m,["target","e",["arcade","game"]]],6,"appLinks");u("gem.openAppResult",[m,T,E],30,"appLinks");u("gem.requestOpenGame",[m,["ref","s",40,"gameRef"]],6,"openGame");u("gem.openGameResult",[m,T,E],30,"openGame");u("gem.requestSimilarGames",[m,["limit","I",1,24]],12,"openGame");u("gem.similarGamesResult",[m,T,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);u("gem.requestStoreOffers",[m],12,"store");u("gem.storeOffersResult",[m,T,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);u("gem.requestStorePurchase",[m,["skuId","s",64]],12,"store");u("gem.storePurchaseResult",[m,T,E],30,"store");u("gem.storePurchaseSettled",[["skuId","s",64]],30,"store");u("gem.requestStoreOfferSheet",[m,["skuId","s",64]],12,"storeOfferSheet");u("gem.storeOfferSheetResult",[m,T,E],30,"storeOfferSheet");Object.freeze(Ot);ve.__malformed=60;Object.freeze(ve);Object.freeze(At);var M={now:()=>Date.now(),setTimeout:(t,e)=>setTimeout(t,e),clearTimeout:t=>clearTimeout(t)};function Ct(t){let e=t.toLowerCase();return e==="localhost"||e.endsWith(".localhost")||e==="[::1]"||e==="::1"?true:/^127(\.\d{1,3}){3}$/.test(e)}var Y=class{constructor(e,n){this.inventory=e;this.resolveCurrencyId=n;}inventory;resolveCurrencyId;async list(e={}){return (await this.inventory.snapshot({buckets:e.buckets})).currencies.data.map(r=>({currencyId:r.currencyId,total:r.total,...r.buckets===void 0?{}:{buckets:r.buckets}}))}async get(e,n={}){let i=(await this.inventory.snapshot({buckets:n.buckets})).currencies.data,a=i.find(l=>l.currencyId===e),s;return !a&&this.resolveCurrencyId&&(s=await this.resolveCurrencyId(e).catch(()=>{}),s!==void 0&&(a=i.find(l=>l.currencyId===s))),{currencyId:a?a.currencyId:s??e,total:a?a.total:null,...a?.buckets===void 0?{}:{buckets:a.buckets}}}};function He(t){let e=Array.isArray(t.achievements)?t.achievements:[],n=[];for(let r of e){let i=r??{};typeof i.id!="string"||i.id===""||typeof i.threshold!="number"||!Number.isFinite(i.threshold)||n.push({id:i.id,threshold:i.threshold,points:typeof i.points=="number"?i.points:0,hidden:i.hidden===true,...typeof i.unlocked_at=="number"&&Number.isFinite(i.unlocked_at)?{unlockedAt:i.unlocked_at}:{},...i.revoked===true?{revoked:true}:{}});}return {...n.length>0?{achievements:n}:{},...t.achievements_unavailable===true?{achievementsUnavailable:true}:{}}}var Gt="inventory",B=t=>typeof t=="number"?t:0,X=t=>typeof t=="string"?t:"";function We(t,e){let n=t??{},r=typeof n.next_cursor=="string"?n.next_cursor:void 0;return {data:Array.isArray(n.data)?n.data.map(e):[],...r===void 0?{}:{nextCursor:r}}}function It(t){let e=t??{};return {itemDefinitionId:X(e.item_definition_id),instanceId:X(e.instance_id),quantity:B(e.quantity),acquiredAt:B(e.acquired_at),...e.properties===void 0?{}:{properties:e.properties},...e.custom_data===void 0?{}:{customData:e.custom_data}}}function yi(t){let e=t??{},n=typeof e.etag=="string"?e.etag:void 0;return {currencies:We(e.currencies,r=>{let i=r??{},a=Array.isArray(i.buckets)?i.buckets.map(s=>{let l=s??{};return {bucket:X(l.bucket),balance:B(l.balance)}}):void 0;return {currencyId:X(i.currency_id),total:B(i.total),...a===void 0?{}:{buckets:a}}}),items:We(e.items,It),progressions:We(e.progressions,r=>{let i=r??{};return {progressionDefinitionId:X(i.progression_definition_id),currentValue:B(i.current_value),completionCount:B(i.completion_count),isCompleted:i.is_completed===true,...He(i)}}),...n===void 0?{}:{etag:n}}}var Q=class{constructor(e,n,r){this.api=e;this.entity=n;this.cache=r;}api;entity;cache;snapshot(e={}){let n=e.buckets?`${Gt}#buckets`:Gt;return this.cache.read(n,[],()=>this.fetch({includeBuckets:e.buckets}))}async instances(e,n){let r=await this.snapshot();if(r.items.nextCursor===void 0){let a=r.items.data.filter(s=>s.itemDefinitionId===e);if(a.length>0)return a}let i=await kn(this.api,this.entity.type,this.entity.id,e,n===void 0?{}:{signal:n});return Array.isArray(i)?i.map(It):[]}page(e){return this.fetch(e)}refresh(){this.invalidate();}onChanged(e){return this.cache.onInvalidate(e)}invalidate(){this.cache.invalidate();}async fetch(e){let n=await Sn(this.api,this.entity.type,this.entity.id,{...e.includeBuckets?{include_buckets:true}:{},...e.currencyCursor===void 0?{}:{currency_cursor:e.currencyCursor},...e.itemCursor===void 0?{}:{item_cursor:e.itemCursor},...e.progressionCursor===void 0?{}:{progression_cursor:e.progressionCursor},...e.currencyLimit===void 0?{}:{currency_limit:e.currencyLimit},...e.itemLimit===void 0?{}:{item_limit:e.itemLimit},...e.progressionLimit===void 0?{}:{progression_limit:e.progressionLimit},...e.signal===void 0?{}:{signal:e.signal}});return yi(n)}};var fi={unknown_currency:1,currency_not_in_game_payable:1,not_purchasable:1,no_price_in_currency:1,busy:1,cancelled:1,insufficient_funds:1,price_mismatch:1,config_version_stale:1,platform_currency_unavailable:1,not_available:1,recipe_locked:1,already_owned:1,recipe_on_cooldown:1,recipe_max_uses_exceeded:1,item_max_stack_exceeded:1,recipe_costs_unmet:1,quantity_invalid:1,error:1};new Set(Object.keys(fi));var q=class extends RangeError{constructor(n,r){super(r);this.code=n;this.name="PurchaseRefusal";}code;retryable=false};var b=t=>typeof t=="string"?t:"",hi=t=>typeof t=="string"?t:b(t&&typeof t=="object"?t.type:void 0),O=t=>typeof t=="number"?t:0;function _i(t){let e=t??{};return {prerequisiteType:b(e.prerequisite_type),referenceId:b(e.reference_id),required:O(e.required),current:O(e.current)}}function Z(t){let e=t??{},n=typeof e.etag=="string"?e.etag:void 0;return {orderId:b(e.order_id),status:b(e.status),...n===void 0?{}:{etag:n}}}function xe(){return crypto.randomUUID()}var bi="recipe-usage",Tt=100;function Se(t){let e=t??{};switch(e.type){case "currency":return {kind:"currency",currencyId:b(e.currency_id),bucket:b(e.bucket),delta:O(e.delta),balanceAfter:O(e.balance_after)};case "item":return {kind:"item",itemDefinitionId:b(e.item_definition_id),instanceId:b(e.instance_id),delta:O(e.delta),quantityAfter:O(e.quantity_after)};case "progression":return {kind:"progression",progressionDefinitionId:b(e.progression_definition_id),delta:O(e.delta),valueAfter:O(e.value_after),completed:e.completed===true};default:return {kind:"other",type:b(e.type)}}}function Ri(t){let e=t??{},n=typeof e.rarity_tier=="string"?e.rarity_tier:void 0;return {entryId:b(e.entry_id),...n===void 0?{}:{rarityTier:n},rollNumber:O(e.roll_number),wasReplacement:e.was_replacement===true,grants:Array.isArray(e.grants)?e.grants.map(Se):[]}}function wi(t){let e=t??{},n=typeof e.etag=="string"?e.etag:void 0,r=Array.isArray(e.loot_results)?e.loot_results.map(Ri):void 0;return {orderId:b(e.order_id),status:b(e.status),...n===void 0?{}:{etag:n},granted:Array.isArray(e.granted)?e.granted.map(Se):[],consumed:Array.isArray(e.consumed)?e.consumed.map(Se):[],autoClaimedRewards:Array.isArray(e.auto_claimed_rewards)?e.auto_claimed_rewards.map(Se):[],...r===void 0||r.length===0?{}:{lootResults:r}}}function vi(t){let e=t??{},n=e.price??{};return {payment:"platform_currency",orderId:b(e.target_order_id)||b(e.source_order_id),status:b(e.status),purchaseId:b(e.purchase_id),sourceOrderId:b(e.source_order_id),price:{currencyId:b(n.platform_currency_id),amount:O(n.price)}}}function xi(t){let e=t??{},n=typeof e.last_used_at=="string"?e.last_used_at:void 0,r=typeof e.cooldown_expires_at=="string"?e.cooldown_expires_at:void 0;return {recipeId:b(e.recipe_id),useCount:typeof e.use_count=="number"?e.use_count:0,isOnCooldown:e.is_on_cooldown===true,...n===void 0?{}:{lastUsedAt:n},...r===void 0?{}:{cooldownExpiresAt:r}}}function Et(t){switch(t.type){case "currency_grant":case "currency_consume":return {type:t.type,currency_id:t.currencyId,amount:t.amount};default:return {type:t.type,item_definition_id:t.itemDefinitionId,quantity:t.quantity}}}var ee=class{constructor(e,n,r){this.api=e;this.entity=n;this.cache=r;}api;entity;cache;async create(e,n={}){let r=await this.write(()=>fn(this.api,this.entity.type,this.entity.id,{operations:e.map(Et),source:n.source??"play",nonce:xe()},{...n.ifMatch===void 0?{}:{ifMatch:n.ifMatch},...n.signal===void 0?{}:{signal:n.signal}}));return Z(r)}async createMany(e,n={}){return this.write(()=>yn(this.api,this.entity.type,this.entity.id,{orders:e.map(r=>({operations:r.map(Et),nonce:xe()})),source:n.source??"play"},{...n.ifMatch===void 0?{}:{ifMatch:n.ifMatch},...n.signal===void 0?{}:{signal:n.signal}}))}async recipeAvailability(e,n,r){let a=await Cn(this.api,this.entity.type,this.entity.id,e,n,r===void 0?{}:{signal:r})??{},s=typeof a.uses_remaining=="number"?a.uses_remaining:void 0,l=typeof a.cooldown_expires_at=="string"?a.cooldown_expires_at:void 0,o=Array.isArray(a.lock_reasons)?a.lock_reasons.map(_i):[];return {canExecute:a.can_execute===true,locked:a.locked===true||o.length>0,lockReasons:o,reasons:Array.isArray(a.reasons)?a.reasons.map(c=>hi(c)):[],...s===void 0?{}:{usesRemaining:s},...l===void 0?{}:{cooldownExpiresAt:l}}}async recipeUsageAll(){return this.cache.read(bi,[],async()=>{let n=await Gn(this.api,this.entity.type,this.entity.id,{limit:Tt})??{},r=Array.isArray(n.usages)?n.usages:[];return {usages:r.map(xi),truncated:r.length>=Tt}})}async recipeUsage(e){return (await this.recipeUsageAll()).usages.find(r=>r.recipeId===e)??null}async purchase(e,n={}){if(e.payment.kind==="configured"){let g=e,h=await this.write(()=>Rn(this.api,this.entity.type,this.entity.id,{catalog_id:g.catalogId,recipe_id:g.targetId,game_id:this.api.gameId(),nonce:xe()},{...n.ifMatch===void 0?{}:{ifMatch:n.ifMatch},...n.signal===void 0?{}:{signal:n.signal}}));return {payment:"configured",...wi(h)}}if(this.entity.type!=="players"||this.entity.id!=="me")throw new TypeError("platform-currency purchases are available only on gem.me.mutations");let[r,i]=await Promise.all([$n(this.api,n.signal===void 0?{}:{signal:n.signal}),fe(this.api,n.signal===void 0?{}:{signal:n.signal})]),a=e.payment.currencySlug.toLowerCase(),s=i.currencies.find(g=>g.currency_id.toLowerCase()===a||g.slug.toLowerCase()===a);if(s===void 0){let g=i.currencies.map(h=>h.slug);throw new q("unknown_currency",`platform currency ${JSON.stringify(e.payment.currencySlug)} is not an active platform currency. Active: ${g.length===0?"none":g.join(", ")}`)}let l=e.kind==="item"?r.items.find(g=>g.item_id===e.targetId):r.recipes.find(g=>g.recipe_id===e.targetId&&g.catalog_id===e.catalogId);if(l===void 0)throw new q("not_purchasable",`purchase target ${JSON.stringify(e.targetId)}`+(e.kind==="recipe"?` in catalog ${JSON.stringify(e.catalogId)}`:"")+` is not purchasable in config version ${r.config_version} on this channel. Send the ${e.kind==="item"?"item":"recipe"} id (not its slug), and check that it has platform_prices and that this config version is promoted`);let o=l.platform_prices.find(g=>g.platform_currency_id===s.currency_id);if(o===void 0){let g=y=>i.currencies.find(_=>_.currency_id===y)?.slug??y,h=l.platform_prices.map(y=>`${g(y.platform_currency_id)} ${y.price}`);throw new q("no_price_in_currency",`purchase target ${JSON.stringify(e.targetId)} has no ${s.slug} price. It is priced in: ${h.length===0?"nothing":h.join(", ")}`)}let c=e.kind==="item"?e.quantity??1:1;if(!Number.isInteger(c)||c<1||c>10)throw new q("quantity_invalid","item purchase quantity must be an integer from 1 through 10");let p=await this.write(()=>Vn(this.api,this.entity.type,this.entity.id,{purchase_kind:e.kind,target_id:e.targetId,...e.kind==="recipe"?{catalog_id:e.catalogId}:{},quantity:c,expected_price:{platform_currency_id:s.currency_id,price:o.price*c},expected_config_version:r.config_version,nonce:xe(),confirmation:"none"},n.signal===void 0?{}:{signal:n.signal}));return vi(p)}async executeRecipe(e,n,r={}){return await this.purchase({kind:"recipe",catalogId:e,targetId:n,payment:{kind:"configured"}},r)}async addProgression(e,n,r){let i=await this.write(()=>cn(this.api,this.entity.type,this.entity.id,e,{amount:n,game_id:this.api.gameId()},r===void 0?{}:{signal:r}));return Z(i)}async maxProgression(e,n,r){let i=await this.write(()=>et(this.api,this.entity.type,this.entity.id,e,{value:n,game_id:this.api.gameId()},r===void 0?{}:{signal:r}));return Z(i)}async claimProgression(e,n){let r=await this.write(()=>gn(this.api,this.entity.type,this.entity.id,e,{game_id:this.api.gameId()},n===void 0?{}:{signal:n}));return Z(r)}async resetProgression(e,n){let r=await this.write(()=>st(this.api,this.entity.type,this.entity.id,e,{game_id:this.api.gameId()},n===void 0?{}:{signal:n}));return Z(r)}async write(e){return this.cache.invalidate(),e()}};var Je=t=>typeof t=="string"?t:"",Si=t=>typeof t=="number"?t:0;function Lt(t){let e=t??{};return {orderId:Je(e.order_id),status:Je(e.status),source:Je(e.source),createdAt:Si(e.created_at)}}var ne=class{constructor(e,n){this.api=e;this.entity=n;}api;entity;async list(e={}){let r=await zn(this.api,this.entity.type,this.entity.id,{...e.limit===void 0?{}:{limit:e.limit},...e.cursor===void 0?{}:{cursor:e.cursor},...e.signal===void 0?{}:{signal:e.signal}})??{},i=typeof r.next_cursor=="string"?r.next_cursor:void 0;return {data:Array.isArray(r.orders)?r.orders.map(Lt):[],...i===void 0?{}:{nextCursor:i}}}async get(e,n){let r=await Pn(this.api,this.entity.type,this.entity.id,e,n===void 0?{}:{signal:n});return Lt(r)}};var ki=["live"],ze=6e4,Mt=864e5;function Ai(t){let e=t?.passes;if(!Array.isArray(e))return Object.freeze([]);let n=e.flatMap(r=>{let i=r??{};if(typeof i.pass!="string"||i.pass==="")return [];let a=i.held===true,s=a&&typeof i.ends_at=="string"?i.ends_at:null;return [Object.freeze({pass:i.pass,held:a,endsAt:s})]});return Object.freeze(n)}function Pi(t){let n=t.flatMap(r=>r.endsAt===null?[]:[Date.parse(r.endsAt)]).filter(r=>Number.isFinite(r));return n.length===0?null:Math.min(...n)}function qt(t,e,n={}){let{watch:r}=n,i=new Set,a=null,s=0,l=null,o=ze,c=()=>{l!==null&&r?.clock.clearTimeout(l.handle),l=null;},p=w=>{c(),!(r===void 0||i.size===0)&&(l={handle:r.clock.setTimeout(ln,w)});},g=w=>{let A=Pi(w);if(A===null||r===void 0){c();return}let k=A-r.clock.now();p(k>0?Math.min(k,Mt):ze);},h=w=>{r?.log?.(`[gem] a passes 'changed' listener threw: ${w instanceof Error?w.message:String(w)}`);},y=w=>{let A=a!==null&&JSON.stringify(a)!==JSON.stringify(w);if(a=w,o=ze,g(w),!!A)for(let k of [...i])try{let ye=k(w);typeof ye?.then=="function"&&ye.then(void 0,h);}catch(ye){h(ye);}},_=()=>{let w=s;return e.read("passes",ki,()=>qn(t)).then(A=>{if(w!==s)return _();let k=Ai(A);return y(k),k})},j=()=>{_().catch(()=>{p(o),o=Math.min(o*2,Mt);});};function ln(){s+=1,e.invalidate(),c(),r!==void 0&&i.size>0&&j();}return {api:{list:_,async get(w){return (await _()).find(k=>k.pass===w)??Object.freeze({pass:w,held:false,endsAt:null})},on(w,A){let k=i.size===0;return i.add(A),k&&r!==void 0&&(a===null?j():g(a)),()=>{i.delete(A),i.size===0&&c();}}},recheck:ln}}var Ft=t=>typeof t=="number"?t:0,Oi=t=>typeof t=="string"?t:"";function Ci(t){let e=t??{};return {progressionDefinitionId:Oi(e.progression_definition_id),currentValue:Ft(e.current_value),completionCount:Ft(e.completion_count),isCompleted:e.is_completed===true,...He(e)}}var te=class{constructor(e,n,r){this.api=e;this.entity=n;this.inventory=r;}api;entity;inventory;async list(){return (await this.inventory.snapshot()).progressions.data}async get(e,n){let i=(await this.inventory.snapshot()).progressions.data.find(a=>a.progressionDefinitionId===e);if(i&&i.achievementsUnavailable!==true)return i;try{let a=await On(this.api,this.entity.type,this.entity.id,e,n===void 0?{}:{signal:n});return Ci(a)}catch{return i??null}}};var re=class{constructor(e,n){this.clock=e;this.identity=n;}clock;identity;generation=0;slots=new Map;listeners=new Set;boundTo=null;read(e,n,r,i){this.rebind();let a=n.length===0,s=a?e:e+"\0"+n.join("\0"),l=this.slots.get(s);if(l){let g=l.filledAt;if(g!==void 0&&(i===void 0||this.clock.now()-g<=i))return Promise.resolve(l.value);if(l.inFlight)return l.inFlight}let o=l??{};this.slots.set(s,o);let c=this.generation,p=r().then(g=>(a&&this.generation===c&&(o.value=g,o.filledAt=this.clock.now()),g)).finally(()=>{o.inFlight===p&&(o.inFlight=void 0,o.filledAt===void 0&&this.slots.get(s)===o&&this.slots.delete(s));});return o.inFlight=p,p}invalidate(){this.slots.clear(),this.generation+=1;for(let e of [...this.listeners])e();}onInvalidate(e){return this.listeners.add(e),()=>{this.listeners.delete(e);}}rebind(){if(!this.identity)return;let e=this.identity();e!==this.boundTo&&(this.boundTo=e,this.invalidate());}};function Gi(t){let e=i=>new RegExp(`<${i}>([^<]{0,300})</${i}>`).exec(t)?.[1]?.trim()||void 0,n=[e("Code"),e("AuthenticationErrorDetail")??e("Message")].filter(Boolean);if(n.length>0)return n.join(" \u2014 ");let r=t.trim();return r?r.slice(0,300):""}async function ke(t){try{let e=Gi(await t.text());return e?`Storage said: ${e}`:""}catch{return ""}}var R=class extends Error{constructor(n,r){super(r);this.reason=n;this.name="GemSaveError";}reason},Ii=3e4,Ti=5e3,$t=6e4,Ei=2**31-1,jt="the save payload could not reach storage. From a browser this is almost always the storage account's CORS rule, which the platform owns and your game cannot change. If every save fails this way, report it rather than working around it",Li=/^[A-Za-z0-9_]{1,64}$/;function G(t){let e=t.length===0?"a save key cannot be empty":t.length>64?`it is ${t.length} characters; a save key is at most 64`:t.startsWith("_")||t.startsWith("$")?`it begins with ${JSON.stringify(t[0])}, and \`_\` and \`$\` are reserved prefixes`:"a save key is ASCII letters, digits and underscores only \u2014 no hyphens, spaces or other punctuation, unlike a template slug";if(!Li.test(t)||t.startsWith("_"))throw new TypeError(`${JSON.stringify(t)} is not a usable save key: ${e}.`);return t}function Nt(t,e){let n=new AbortController,r=Date.now()+e;Rt(n.signal,()=>r-Date.now());let i=AbortSignal.timeout(e),a=()=>n.abort(i.reason),s=()=>n.abort(t?.reason);return t?.aborted?n.abort(t.reason):(i.addEventListener("abort",a,{once:true}),t?.addEventListener("abort",s,{once:true})),{signal:n.signal,release:()=>{i.removeEventListener("abort",a),t?.removeEventListener("abort",s);}}}function Ke(t,e){return t.aborted&&e?.aborted!==true}var Mi=new Set(["x-ms-blob-type"]),qi=/^[ -~]+$/;function Fi(t,e){if(t==null)return {};if(typeof t!="object"||Array.isArray(t))throw new R("save_malformed",`the grant for save ${JSON.stringify(e)} described its upload headers as ${Array.isArray(t)?"a list":typeof t}, which is not a set of headers.`);let n={};for(let[r,i]of Object.entries(t)){let a=r.toLowerCase();if(!Mi.has(a))throw new R("save_malformed",`the grant for save ${JSON.stringify(e)} asked the upload to send ${JSON.stringify(r)}, which this SDK does not put on a storage request. Report it \u2014 a platform that needs a new upload header needs an SDK release too.`);if(typeof i!="string"||!qi.test(i))throw new R("save_malformed",`the grant for save ${JSON.stringify(e)} gave header ${JSON.stringify(r)} a value that is not usable as one.`);if(a in n)throw new R("save_malformed",`the grant for save ${JSON.stringify(e)} named ${JSON.stringify(a)} twice.`);n[a]=i;}return n}function Ye(t){let e=typeof t.metadata=="object"&&t.metadata!==null&&!Array.isArray(t.metadata)?t.metadata:void 0;return {key:t.key,sizeBytes:t.size_bytes,etag:t.etag,...e===void 0?{}:{metadata:e},createdAt:t.created_at,updatedAt:t.updated_at}}function Xe(t){return t?.reason==="not_found"}function $i(t){return t?.code==="save_conflict"}function Bt(t){return t instanceof f&&t.reason==="rate_limited"}async function Dt(t,e){let n=await ke(e);return new f("rate_limited",429,`the save ${t} answered 429: too many save calls. ${n}`.trim(),Be(e.headers.get("retry-after")))}function Ae(t){return t.reason!==void 0?t.reason:new DOMException("The operation was aborted.","AbortError")}function ji(t,e,n,r,i){let a=false,s=()=>a?false:(a=true,l.detach?.(),true),l={signal:n.signal,budget:r,deadlineAt:Date.now()+r,teardown:n.teardown===true,overwrite:n.overwrite===true,identity:i,resolve:o=>{s()&&t(o);},reject:o=>{s()&&e(o);},detach:void 0};return l}function Ut(t,e){return t!==null&&e!==null&&e!==t}function Vt(t){return new R("save_conflict",`save ${JSON.stringify(t)} was not written: the signed-in player changed while it waited for the write before it, and it holds the last player's progress.`)}var ie=class{constructor(e,n,r={},i){this.api=e;this.entity=n;this.options=r;this.identity=i;}api;entity;options;identity;versions=new Map;seq=0;versionsOf=null;writes=new Map;holdUntil=0;async put(e,n,r={}){let i;try{i=JSON.stringify(n);}catch(a){throw new R("save_malformed",`save ${JSON.stringify(e)} could not be serialised to JSON: ${String(a)}. Retrying stores the same unserialisable value.`)}if(i===void 0)throw new R("save_malformed",`save ${JSON.stringify(e)} is undefined, which is not JSON. Use delete() to remove one.`);return this.putBytes(e,new TextEncoder().encode(i),{...r,contentType:"application/json"})}async putBytes(e,n,r={}){if(G(e),r.signal?.aborted)throw Ae(r.signal);let i=this.budget(r.timeoutMs),a=this.slotWrites(e);return new Promise((s,l)=>{let o=a.queued;o?.release();let c=o?.waiters[o.waiters.length-1];c!==void 0&&this.holdOwn(a,c);let p=this.identity?.()??null;for(let g of o?.waiters.slice()??[])Ut(g.identity,p)&&this.drop(a,g,Vt(e));a.queued=this.queue(a,n,r,ji(s,l,r,i,p),o?.waiters??[]),a.wake?.(),this.pump(e,a);})}holdOwn(e,n){let{signal:r}=n,i=n.deadlineAt-Date.now();if(r?.aborted)return this.drop(e,n,Ae(r));if(i<=0)return this.drop(e,n,this.timeout("save",n.budget));let a=AbortSignal.timeout(i),s=()=>this.drop(e,n,this.timeout("save",n.budget)),l=()=>{r&&this.drop(e,n,Ae(r));};a.addEventListener("abort",s,{once:true}),r?.addEventListener("abort",l,{once:true}),n.detach=()=>{a.removeEventListener("abort",s),r?.removeEventListener("abort",l);};}drop(e,n,r){let i=e.queued?.waiters,a=i?.indexOf(n)??-1;a>=0&&i?.splice(a,1),n.reject(r),e.wake?.();}queue(e,n,r,i,a){let{budget:s}=i,l=[...a,i],o=AbortSignal.timeout(s),c=y=>{if(e.queued===h){this.take(e,h);for(let _ of l)_.reject(y);e.wake?.();}},p=()=>c(this.timeout("save",s)),g=()=>{r.signal&&c(Ae(r.signal));};o.addEventListener("abort",p,{once:true}),r.signal?.addEventListener("abort",g,{once:true});let h={bytes:n,options:r,budget:s,deadlineAt:i.deadlineAt,identity:i.identity,waiters:l,release:()=>{o.removeEventListener("abort",p),r.signal?.removeEventListener("abort",g);}};return h}async pump(e,n){if(!n.running){n.running=true;try{for(let r=n.queued;r!==void 0;r=n.queued){let i=Date.now(),a=this.holdUntil-i;if(a>0){if(a>=r.deadlineAt-i){this.take(n,r);for(let o of r.waiters)o.reject(this.held(e,a));continue}for(let o of r.waiters.slice(0,-1))a>=o.deadlineAt-i&&this.drop(n,o,this.held(e,a));}let s=Math.max(a,this.spacing(n,r,i));if(s>0){await this.pause(n,s);continue}this.take(n,r);let l;try{l=this.precondition(e,r);}catch(o){for(let c of r.waiters)c.reject(o);continue}n.lastSentAt=i;try{let o=await this.send(e,r,l);for(let c of r.waiters)c.resolve(o);}catch(o){for(let c of r.waiters)c.reject(o);}}}finally{n.running=false;}}}spacing(e,n,r){if(e.lastSentAt===void 0||n.waiters.some(s=>s.teardown))return 0;let i=this.options.minWriteIntervalMs??Ti,a=Math.min(...n.waiters.map(s=>s.deadlineAt-s.budget/2));return Math.min(e.lastSentAt+i,a)-r}pause(e,n){return new Promise(r=>{let i=()=>{clearTimeout(a),e.wake===i&&(e.wake=void 0),r();},a=setTimeout(i,Math.min(n,Ei));e.wake=i;})}take(e,n){e.queued===n&&(e.queued=void 0),n.release();}slotWrites(e){let n=this.writes.get(e);return n===void 0&&(n={running:false,queued:void 0,lastSentAt:void 0,wake:void 0},this.writes.set(e,n)),n}noteRateLimit(e){if(!Bt(e))return;let n=e.retryAfterSeconds,r=n===void 0?$t:Math.min(n*1e3,$t);this.holdUntil=Math.max(this.holdUntil,Date.now()+r);}held(e,n){let r=Math.ceil(n/1e3);return new f("rate_limited",429,`save ${JSON.stringify(e)} was not sent: the platform refused a save call for the rate, and the wait it asked for ends in ${r}s, after this call's timeoutMs. Keep the state and write once the wait is over.`,r)}async send(e,n,r){let{bytes:i,options:a,budget:s}=n,l=a.contentType??"application/octet-stream",o=Nt(a.signal,Math.max(0,n.deadlineAt-Date.now()));try{let c=await at(this.api,this.entity.type,this.entity.id,e,{size_bytes:i.byteLength,content_type:l,...r,...a.metadata===void 0?{}:{metadata:a.metadata}},{signal:o.signal});if(typeof c.upload_url!="string"||typeof c.session_id!="string")throw new R("save_malformed",`the grant for save ${JSON.stringify(e)} named nowhere to put the bytes.`);let p=Fi(c.upload_headers,e),g,h=this.options.fetch??globalThis.fetch.bind(globalThis);try{g=await h(c.upload_url,{method:"PUT",headers:{"content-type":l,...p},body:i,credentials:"omit",signal:o.signal});}catch(_){throw Ke(o.signal,a.signal)?this.timeout("upload",s):new R("upload_failed",`${jt} for PUT. Underlying error: ${_}`)}if(g.status===429)throw await Dt("upload",g);if(!g.ok){let _=await ke(g);throw new R("upload_failed",g.status===400?"the save upload answered 400. The platform and the service holding the bytes disagree about what this upload must carry, which is not something your game can fix and not worth retrying \u2014 report it. "+_:`the save upload answered ${g.status}. `+(g.status===403?"An upload URL is short-lived, so this is most likely an expired one \u2014 start the save again rather than retrying the upload. ":"")+_)}let y=Ye(await wn(this.api,this.entity.type,this.entity.id,e,{session_id:c.session_id},{signal:o.signal}));return this.remember(e,y.etag?{kind:"etag",etag:y.etag}:void 0),y}catch(c){throw $i(c)?new R("save_conflict",`save ${JSON.stringify(e)} was not written: the stored save changed since this game last loaded or wrote it, so another device or tab saved in between. Load it again and decide what to write from what is stored, rather than resending this write.`):(this.noteRateLimit(c),this.rethrow(c,a.signal,o.signal,"save",s))}finally{o.release();}}async get(e,n={}){let r=await this.getBytes(e,n);if(r===null)return null;try{return JSON.parse(new TextDecoder().decode(r))}catch(i){throw new R("save_malformed",`the stored save ${JSON.stringify(e)} is not JSON, so put() did not write it. Read it with getBytes() and decode it yourself. Underlying error: ${i}`)}}async getBytes(e,n={}){G(e);let r=this.budget(n.timeoutMs),i=Nt(n.signal,r),a=this.seq;try{let s;try{let p=await Me(this.api,this.entity.type,this.entity.id,e,{signal:i.signal});if(!p.modified)return this.remember(e,{kind:"empty"},a),null;s=p.body;}catch(p){if(Xe(p))return this.remember(e,{kind:"empty"},a),null;throw p}if(typeof s.download_url!="string")throw new R("save_malformed",`the record for save ${JSON.stringify(e)} named no link to its stored bytes.`);let l=this.options.fetch??globalThis.fetch.bind(globalThis),o;try{o=await l(s.download_url,{credentials:"omit",signal:i.signal});}catch(p){throw Ke(i.signal,n.signal)?this.timeout("download",r):new R("download_failed",`${jt} for GET. Underlying error: ${p}`)}if(o.status===429)throw await Dt("download",o);if(!o.ok){let p=await ke(o);throw new R("download_failed",`the save download answered ${o.status}. `+(o.status===403?"A download link lasts 15 minutes, so this is most likely an expired one \u2014 call get() again for a fresh one. ":"")+p)}let c=new Uint8Array(await o.arrayBuffer());return this.remember(e,s.etag?{kind:"etag",etag:s.etag}:void 0,a),c}catch(s){throw this.slots().get(e)===void 0&&this.remember(e,{kind:"failed"}),this.noteRateLimit(s),this.rethrow(s,n.signal,i.signal,"load",r)}finally{i.release();}}async describe(e,n={}){try{let r=await Me(this.api,this.entity.type,this.entity.id,G(e),{...n.signal===void 0?{}:{signal:n.signal},...n.ifNoneMatch===void 0?{}:{ifNoneMatch:n.ifNoneMatch}});return r.modified?Ye(r.body):null}catch(r){if(Xe(r))return null;throw r}}async list(e={}){let n=await Kn(this.api,this.entity.type,this.entity.id,{...e.limit===void 0?{}:{limit:e.limit},...e.cursor===void 0?{}:{cursor:e.cursor},...e.signal===void 0?{}:{signal:e.signal}}),r=n.next_cursor;return {saves:(n.data??[]).map(Ye),...typeof r=="string"&&r.length>0?{nextCursor:r}:{}}}async delete(e,n){try{await _n(this.api,this.entity.type,this.entity.id,G(e),{...n===void 0?{}:{signal:n}});}catch(r){if(!Xe(r))throw r}this.remember(e,{kind:"empty"});}precondition(e,n){if(Ut(n.identity,this.identity?.()??null))throw Vt(e);if(n.waiters.some(i=>i.overwrite))return {};let r=this.slots().get(e);if(r===void 0)return {};if(r.kind==="etag")return {if_match:r.etag};if(r.kind==="empty")return {if_none_match:"*"};throw new R("load_failed",`save ${JSON.stringify(e)} was not written: the last load of this slot failed, so what this write would replace is unknown, and it could be the player's real progress. Load it again before saving, or pass overwrite: true if replacing whatever is stored is what you mean.`)}remember(e,n,r){let i=this.slots(),a=i.get(e);r!==void 0&&a!==void 0&&a.kind!=="failed"&&a.seq>r||(this.seq+=1,n===void 0?i.delete(e):i.set(e,{...n,seq:this.seq}));}slots(){let e=this.identity?.()??null;return e!==null&&e!==this.versionsOf&&(this.versionsOf!==null&&this.versions.clear(),this.versionsOf=e),this.versions}budget(e){return e??this.options.timeoutMs??Ii}timeout(e,n){return new R("save_timeout",`the save ${e} did not finish within ${n}ms`)}rethrow(e,n,r,i,a){return e instanceof R||Bt(e)?e:Ke(r,n)?this.timeout(i,a):e}};function Ni(t){try{return Ne(t)}catch{return t}}function Qe(t,e){let n=t??{},r=typeof n.etag=="string"?n.etag:e;return {key:typeof n.key=="string"?n.key:"",value:typeof n.value=="string"?Ni(n.value):"",...r===void 0?{}:{etag:r},updatedAt:typeof n.updated_at=="number"?n.updated_at:0}}var ae=class{constructor(e,n){this.api=e;this.entity=n;}api;entity;async list(e){let r=(await Jn(this.api,this.entity.type,this.entity.id,e===void 0?{}:{signal:e}))?.settings;return Array.isArray(r)?r.map(i=>Qe(i)):[]}async get(e,n={}){try{let r=await xn(this.api,this.entity.type,this.entity.id,e,{...n.signal===void 0?{}:{signal:n.signal},...n.ifNoneMatch===void 0?{}:{ifNoneMatch:n.ifNoneMatch}});return r.modified?Qe(r.body,r.etag):null}catch(r){if(Wt(r))return null;throw r}}async put(e,n,r={}){let i=await nt(this.api,this.entity.type,this.entity.id,e,{value:be(n)},{...r.signal===void 0?{}:{signal:r.signal},...r.ifMatch===void 0?{}:{ifMatch:r.ifMatch}});return Qe(i)}async delete(e,n){try{await hn(this.api,this.entity.type,this.entity.id,e,n===void 0?{}:{signal:n});}catch(r){if(!Wt(r))throw r}}};function Wt(t){return t?.reason==="not_found"}function Ze(t,e,n={}){let r=new re(M,n.identity);n.onInventoryChanged&&r.onInvalidate(n.onInventoryChanged);let i=new Q(t,e,r);return {settings:new ae(t,e),inventory:i,saves:new ie(t,e,n.saves??{},n.identity),currencies:new Y(i,n.resolveCurrencyId),mutations:new ee(t,e,r),orders:new ne(t,e),progressions:new te(t,e,i)}}function Ht(t,e,n={}){let r=new re(M,n.identity),i=qt(t,r,n);return {scope:{...Ze(t,e,n),passes:i.api},recheckPasses:i.recheck}}var F=t=>typeof t=="string"?t:"",D=t=>typeof t=="number"?t:0;function Pe(t,e){let n=e??{},r=F(n.character_id);if(r==="")throw new Error("[gem] a character response carried no character_id");return {...t(r),id:r,playerId:F(n.player_id),gameId:F(n.game_id),channel:F(n.channel)||"release",name:F(n.name),slotIndex:D(n.slot_index),isActive:n.is_active!==false,createdAt:F(n.created_at),updatedAt:F(n.updated_at)}}var se=class{constructor(e,n,r,i){this.api=e;this.saves=n;this.identity=r;this.resolveCurrencyId=i;}api;saves;identity;resolveCurrencyId;scopes=new Map;scope=e=>{let n=this.scopes.get(e);return n||(n=Ze(this.api,{type:"characters",id:e},{saves:this.saves,identity:this.identity,resolveCurrencyId:this.resolveCurrencyId}),this.scopes.set(e,n)),n};async list(e){let r=(await Hn(this.api,e===void 0?{}:{signal:e}))?.characters;return Array.isArray(r)?r.map(i=>Pe(this.scope,i)):[]}async get(e,n){let r=await vn(this.api,e,n===void 0?{}:{signal:n});return Pe(this.scope,r)}async create(e){let n=await mn(this.api,{name:e.name},e.signal===void 0?{}:{signal:e.signal});return Pe(this.scope,n)}async update(e,n,r){let i=await it(this.api,e,{name:n},r===void 0?{}:{signal:r});return Pe(this.scope,i)}async delete(e,n){await ot(this.api,e,n===void 0?{}:{signal:n});}async slots(e){let r=await Nn(this.api,e===void 0?{}:{signal:e})??{};return {totalSlots:D(r?.total_slots),availableSlots:D(r?.available_slots),activeCharacterCount:D(r?.active_character_count),defaultMaxSlots:D(r?.default_max_slots),purchasedExtraSlots:D(r?.purchased_extra_slots),canPurchaseMore:r?.can_purchase_more===true}}};var Kt="[gem: use gem.text.toPlain()]",Jt=new Set,zt;function Bi(t){try{if(Jt.has(t))return;let e=globalThis.location;if(zt??=!!e?.port&&Ct(e.hostname??""),!zt)return;Jt.add(t),console.warn(`[gem] ${t} is PlayerText, turned into a string: players see ${Kt}. Render text.toPlain(value) (text is in @indiegems/gem-web-sdk/sdk).
|
|
2
|
-
${new Error().stack}`);}catch{}}var S=class{#e;#t;constructor(e,n="player text"){this.#e=e,this.#t=n,Object.freeze(this);}toString(){return Bi(this.#t),Kt}toJSON(){return this.toString()}get[Symbol.toStringTag](){return "PlayerText"}static unwrap(e){return e.#e}};function U(t,e){return new S(t,e)}var Di={toPlain(t){return S.unwrap(t)},compare(t,e,n){let r=t instanceof S?S.unwrap(t):t,i=e instanceof S?S.unwrap(e):e;if(typeof Intl>"u"||typeof Intl.Collator!="function")return r<i?-1:r>i?1:0;let a;try{a=new Intl.Collator(n);}catch{a=new Intl.Collator;}return a.compare(r,i)},equals(t,e){let n=t instanceof S?S.unwrap(t):t,r=e instanceof S?S.unwrap(e):e;return n.normalize("NFC")===r.normalize("NFC")}};var V=t=>typeof t=="string"?t:"";function Oe(t){let e=t??{},n=typeof e.message=="string"&&e.message.length>0?e.message:void 0,r=typeof e.resolved_at=="string"?e.resolved_at:void 0;return {id:V(e.transfer_id),status:V(e.status),sourceEntityId:V(e.source_entity_id),targetEntityId:V(e.target_entity_id),...n===void 0?{}:{message:U(n,"transfer.message")},createdAt:V(e.created_at),expiresAt:V(e.expires_at),...r===void 0?{}:{resolvedAt:r}}}function Ui(){return crypto.randomUUID()}var oe=class{constructor(e,n,r){this.api=e;this.self=n;this.inventory=r;}api;self;inventory;async initiate(e){this.inventory.invalidate();let n=await Un(this.api,{source_entity_type:this.self.type,source_entity_id:this.self.id,target_entity_type:e.to.type,target_entity_id:e.to.id,items:(e.items??[]).map(r=>({item_definition_id:r.itemDefinitionId,quantity:r.quantity})),currencies:(e.currencies??[]).map(r=>({currency_id:r.currencyId,amount:r.amount})),...e.message===void 0?{}:{message:e.message},nonce:Ui()},e.signal===void 0?{}:{signal:e.signal});return Oe(n)}async list(e={}){let r=await Qn(this.api,{entity_type:this.self.type,entity_id:this.self.id,...e.direction===void 0?{}:{direction:e.direction},...e.status===void 0?{}:{status:e.status},...e.cursor===void 0?{}:{cursor:e.cursor},...e.limit===void 0?{}:{limit:e.limit},...e.signal===void 0?{}:{signal:e.signal}})??{},i=typeof r.next_cursor=="string"?r.next_cursor:void 0;return {transfers:Array.isArray(r.transfers)?r.transfers.map(Oe):[],...i===void 0?{}:{nextCursor:i}}}async get(e,n){let r=await Bn(this.api,e,n===void 0?{}:{signal:n});return Oe(r)}async accept(e,n){return this.resolve(()=>un(this.api,e,n===void 0?{}:{signal:n}))}async reject(e,n){return this.resolve(()=>rt(this.api,e,n===void 0?{}:{signal:n}))}async cancel(e,n){return this.resolve(()=>pn(this.api,e,n===void 0?{}:{signal:n}))}async resolve(e){return this.inventory.invalidate(),Oe(await e())}};function C(t){return typeof t=="string"&&t!==""?t:void 0}var Yt=new Set(["localhost","127.0.0.1","[::1]"]);function $(t){return Vi(t)}function Vi(t){let e=C(t);if(e===void 0)return;let n;try{n=new URL(e);}catch{return}if(!(n.username!==""||n.password!=="")&&(n.protocol==="https:"||n.protocol==="http:"&&Yt.has(n.hostname)))return e}var Wi=/^[\da-f]{8}(-[\da-f]{4}){3}-[\da-f]{12}$/i,Hi=/^[a-z][a-z0-9_]{0,31}$/;function Ji(t){if(!Array.isArray(t))return;let e=[],n=new Set;for(let r of t.slice(0,8)){let i=r??{},a=C(i.family),s=C(i.avatar_3d_id),l=$(i.model_url),o=$(i.icon_url);a===void 0||!Hi.test(a)||n.has(a)||s===void 0||!Wi.test(s)||l===void 0||o===void 0||(n.add(a),e.push({family:a,id:s,modelUrl:l,iconUrl:o}));}return e}function zi(t){if(!Array.isArray(t))return [];let e=[];for(let n of t){let r=n??{},i=C(r.item_id),a=$(r.icon_url);i!==void 0&&a!==void 0&&e.push({itemId:i,iconUrl:a});}return e}function I(t){let e=t??{},n=C(e.player_id),r=C(e.display_name),i=C(e.discriminator),a=C(e.display_tag),s=C(e.avatar_icon_id),l=$(e.avatar_icon_url),o=C(e.avatar_3d_id),c=$(e.avatar_3d_model_url),p=$(e.avatar_3d_icon_url),g=Ji(e.avatars_3d);return {...n===void 0?{}:{playerId:n},...r===void 0?{}:{displayName:U(r,"displayName")},...i===void 0?{}:{discriminator:i},...a===void 0?{}:{displayTag:U(a,"displayTag")},...s===void 0?{}:{avatarIconId:s},...l===void 0?{}:{avatarIconUrl:l},...o===void 0?{}:{avatar3dId:o},...c===void 0?{}:{avatar3dModelUrl:c},...p===void 0?{}:{avatar3dIconUrl:p},...g===void 0?{}:{avatars3d:g},badges:zi(e.badges)}}var Ki=new Set(["https://downloads.gemarcade.com","https://cdn.gemarcade.com"]);function Yi(t){if(t===void 0)return;let e=$(t);if(e===void 0)return;let n=new URL(e);return Yt.has(n.hostname)||Ki.has(n.origin)?e:void 0}var Xt=/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;var nn=class extends f{constructor(e,n={}){super(e.reason,e.status,e.detail,e.retryAfterSeconds,e.code),this.name="FriendChallengeError";for(let[r,i]of Object.entries(n))i!==void 0&&Object.assign(this,{[r]:i});}},Ce=t=>typeof t=="string"?t:void 0;function Qt(t){let e=t??{};return {...I(e),playerId:Ce(e.player_id)??""}}function Zt(t){let e=t.has_more===true?Ce(t.next_cursor):void 0;return e===void 0?{}:{nextCursor:e}}function Xi(t){let e=t??{};return {friends:Array.isArray(e.data)?e.data.map(Qt):[],...Zt(e)}}var en=t=>typeof t=="number"&&Number.isFinite(t)?t:void 0;function Qi(t){return typeof t!="object"||t===null||Array.isArray(t)?{}:Object.fromEntries(Object.entries(t).filter(e=>typeof e[1]=="string"||typeof e[1]=="number"&&Number.isFinite(e[1])))}function er(t){let e=t??{},n=en(e.opened_at),r=en(e.answered_at);return {id:Ce(e.item_id)??"",from:Qt(e.sender),template:Ce(e.template)??"",params:Qi(e.params),createdAt:en(e.created_at)??0,...n===void 0?{}:{openedAt:n},...r===void 0?{}:{answeredAt:r}}}function Zi(t){let e=t??{};return {challenges:Array.isArray(e.data)?e.data.map(er):[],...Zt(e)}}function ea(t){let e=t;return e?.reason==="not_found"&&e.code==="inbox_item_not_found"}var le=class{#e;#t;#a;constructor(e,n={}){this.#e=e,this.#t=n.challenge,this.#a=n.launchedChallengeId;}async list(e={}){let n=await Xn(this.#e,{...e.limit===void 0?{}:{limit:e.limit},...e.cursor===void 0?{}:{cursor:e.cursor},...e.signal===void 0?{}:{signal:e.signal}});return Xi(n)}challenge(e){return this.#t===void 0?Promise.resolve({outcome:"unavailable"}):this.#t(e)}async inbox(e={}){let n=await Yn(this.#e,{...e.limit===void 0?{}:{limit:e.limit},...e.cursor===void 0?{}:{cursor:e.cursor},...e.signal===void 0?{}:{signal:e.signal}});return Zi(n)}async launchedChallenge(e={}){let n=this.#a;if(n===void 0||!Xt.test(n))return null;try{return er(await En(this.#e,n,{...e.signal===void 0?{}:{signal:e.signal}}))}catch(r){if(ea(r))return null;throw r}}async markAnswered(e){if(typeof e!="string"||!Xt.test(e))throw new f("invalid",400,"id must be a FriendChallenge.id, as gem.friends.launchedChallenge() or inbox() returned it",void 0,"bad_request");await Zn(this.#e,e);}};var nr=100,ir=/^\d{4}-\d{2}-\d{2}(?:T\d{2}:\d{2}:\d{2}Z)?$/;function tn(t){let{periodsBack:e,period:n,playerId:r}=t;if(Re(e),e!==void 0&&n!==void 0)throw new TypeError("pass periodsBack or period, not both");if(n!==void 0&&(typeof n!="string"||!ir.test(n)))throw new TypeError(`period must be a period id such as 2026-10-02 (a result's period.id), got ${String(n)}`);if(r!==void 0&&(typeof r!="string"||r===""))throw new TypeError("playerId must be a player id");return {...e===void 0?{}:{periods_back:e},...n===void 0?{}:{period:n},...r===void 0?{}:{player_id:r}}}function ar(t){let e=typeof t.period_id=="string"?t.period_id:"";if(!ir.test(e))return;let n=De(t.period_local_date),r=L(t.period_start_at),i=L(t.period_ends_at),a=r>0&&i>0;return {id:e,...n===void 0?{}:{localDate:n},...a?{startAt:r,endsAt:i}:{},opensAt:L(t.opens_at),closesAt:L(t.closes_at),final:t.final===true}}var de=t=>typeof t=="string"?t:"",W=t=>typeof t=="number"?t:0,ue=t=>typeof t=="string"?t:void 0,na=t=>typeof t=="number"?t:void 0,sr={player:"players",character:"characters"};function ta(t,e){let n=t??{},r=ue(n.entity_id),i=typeof n.entity_type=="string"&&Object.hasOwn(sr,n.entity_type)?n.entity_type:void 0,a=or(n.stats),s=n.properties!==null&&typeof n.properties=="object"?n.properties:void 0,l=e?n.is_viewer===true:void 0;return {...I(n),rank:W(n.rank),occurredAt:W(n.occurred_at),...l===void 0?{}:{isViewer:l},...r===void 0?{}:{entityId:r},...i===void 0?{}:{entityType:i},...a===void 0?{}:{stats:a},...s===void 0?{}:{properties:s}}}function tr(t,e){let n=t??{},r=ue(n.bucket_1),i=ue(n.bucket_2),a=na(n.update_frequency_seconds),s=ar(n);return {leaderboardType:de(n.leaderboard_type),runType:de(n.run_type),...r===void 0?{}:{bucket1:r},...i===void 0?{}:{bucket2:i},entries:Array.isArray(n.entries)?n.entries.map(l=>ta(l,e)):[],generatedAt:W(n.generated_at),...a===void 0?{}:{updateFrequencySeconds:a},...s===void 0?{}:{period:s}}}function rr(t){if(t===null||typeof t!="object"||Array.isArray(t))return;let e=t;if(!Number.isFinite(e.rank))return;let n=or(e.stats),r=e.properties!==null&&typeof e.properties=="object"?e.properties:void 0;return {rank:e.rank,occurredAt:W(e.occurred_at),...n===void 0?{}:{stats:n},...r===void 0?{}:{properties:r}}}function or(t){if(t===null||typeof t!="object")return;let e={};for(let[n,r]of Object.entries(t))typeof r=="number"&&(e[n]=r);return e}function ra(t,e,n){let r=t??{},i=ue(r.bucket_1),a=ue(r.bucket_2),s=ar(r);return {leaderboardType:de(r.leaderboard_type),runType:de(r.run_type),entityType:e,entityId:n,...i===void 0?{}:{bucket1:i},...a===void 0?{}:{bucket2:a},entries:Array.isArray(r.entries)?r.entries.map(rr).filter(l=>l!==void 0):[],personalBest:rr(r.personal_best)??null,totalRuns:W(r.total_runs),totalRunsExact:r.total_runs_exact!==false,generatedAt:W(r.generated_at),...s===void 0?{}:{period:s}}}var ce=class{#e;constructor(e){this.#e=e;}async get(e,n={}){let r=tn(n),i=await Ln(this.#e,e,{...r,...n.bucket1===void 0?{}:{bucket_1:n.bucket1},...n.bucket2===void 0?{}:{bucket_2:n.bucket2},...n.signal===void 0?{}:{signal:n.signal}});return tr(i,false)}async friends(e,n={}){let r=tn(n),i=await In(this.#e,e,{...r,...n.bucket1===void 0?{}:{bucket_1:n.bucket1},...n.bucket2===void 0?{}:{bucket_2:n.bucket2},...n.signal===void 0?{}:{signal:n.signal}});return tr(i,true)}async mine(e,n={}){return this.#t(e,"player","me",n)}async character(e,n,r={}){return this.#t(e,"character",n,r)}async#t(e,n,r,i){if(i.limit!==void 0){let{limit:o}=i;if(!Number.isInteger(o)||o<1||o>nr)throw new TypeError(`limit must be an integer between 1 and ${nr}, got ${String(o)}`)}let a=tn(i),s=await An(this.#e,e,sr[n],r,{...a,...i.bucket1===void 0?{}:{bucket_1:i.bucket1},...i.bucket2===void 0?{}:{bucket_2:i.bucket2},...i.limit===void 0?{}:{limit:i.limit},...i.signal===void 0?{}:{signal:i.signal}}),l=n==="player"&&r==="me"&&de((s??{}).entity_id)||r;return ra(s,n,l)}};var Ge=t=>typeof t=="string"?t:void 0;function ia(t){let e=t??{},n=Ge(e.currency_id);if(n===void 0||n==="")return;let r=typeof e.balance=="number"&&Number.isFinite(e.balance)?e.balance:0;return {slug:Ge(e.slug)??"",currencyId:n,balance:r,access:e.access==="spend"?"spend":"read"}}var Ie=class{#e;constructor(e){this.#e=e;}async get(e={}){let r=(await fe(this.#e,e))?.currencies;if(!Array.isArray(r))return [];let i=[];for(let a of r){let s=ia(a);s!==void 0&&i.push(s);}return i}},rn=t=>typeof t=="number"&&Number.isFinite(t)&&t>=0?Math.floor(t):0;function aa(t){let e=t??{},n=Ge(e.currency_id);if(n===void 0||n==="")return;let r=rn(e.limit),i=Math.min(rn(e.earned),r),a=Math.min(rn(e.remaining),r-i),s=e.period_days,l=typeof s=="number"&&Number.isInteger(s)&&s>=1?s:1,o=e.resets_at,c=typeof o=="number"&&Number.isFinite(o)&&o>0?Math.round(o*1e3):void 0;return {currencySlug:Ge(e.currency_slug)??"",currencyId:n,limit:r,earned:i,remaining:a,period:e.period==="day"?"day":"window",periodDays:l,...c===void 0?{}:{resetsAt:c}}}var Te=class{#e;#t;#a;constructor(e,n,r){this.#e=e,this.#t=n,this.#a=r;}async get(e={}){let r=(await Mn(this.#e,e))?.currencies;if(!Array.isArray(r))return [];let i=[];for(let a of r){let s=aa(a);s!==void 0&&i.push(s);}return i}on(e,n){return e!=="changed"?(this.#a?.(`[gem] unknown earnAllowance event '${String(e)}'; the only event is 'changed'`),()=>{}):this.#t?.on(n)??(()=>{})}},pe=class{currencies;earnAllowance;constructor(e,n,r){this.currencies=new Ie(e),this.earnAllowance=new Te(e,n,r);}};var an=t=>typeof t=="string"?t:"",lr=t=>typeof t=="number"?t:0;function sa(t){let e=t??{};return {key:an(e.key),visibility:an(e.visibility),value:e.value,updatedAt:lr(e.updated_at)}}function oa(t){let e=t??{};return {...I(e),playerId:an(e.player_id),showcase:Array.isArray(e.showcase)?e.showcase.map(sa):[],generatedAt:lr(e.generated_at)}}function la(t){return t?.reason==="not_found"}var ge=class{#e;constructor(e){this.#e=e;}async of(e,n={}){try{return oa(await Fn(this.#e,e,{...n.signal===void 0?{}:{signal:n.signal}}))}catch(r){if(la(r))return null;throw r}}};var Ee=t=>typeof t=="string"?t:"",sn=t=>typeof t=="number"?t:0;function dr(t){let e=t??{};return {playerId:Ee(e.player_id),key:Ee(e.key),value:e.value,updatedAt:sn(e.updated_at)}}function da(t){let e=t??{};return {...I(e),playerId:Ee(e.player_id),value:e.value,isViewer:e.is_viewer===true,updatedAt:sn(e.updated_at)}}function ua(t){return t?.reason==="not_found"}var me=class{constructor(e,n){this.api=e;this.selfPlayerId=n;}api;selfPlayerId;async friends(e,n={}){let i=await Tn(this.api,G(e),{...n.signal===void 0?{}:{signal:n.signal}})??{};return {key:Ee(i.key),entries:Array.isArray(i.entries)?i.entries.map(da):[],generatedAt:sn(i.generated_at)}}async of(e,n,r={}){try{return dr(await jn(this.api,e,G(n),{...r.signal===void 0?{}:{signal:r.signal}}))}catch(i){if(ua(i))return null;throw i}}async set(e,n,r={}){if(G(e),n===void 0)throw new TypeError(`showcase value for ${JSON.stringify(e)} is undefined, which is not JSON. Use clear() to remove one.`);try{JSON.stringify(n);}catch(a){throw new TypeError(`showcase value for ${JSON.stringify(e)} could not be serialised to JSON: ${String(a)}.`,{cause:a})}let i=await this.selfPlayerId();return dr(await tt(this.api,i,e,{value:n},{...r.signal===void 0?{}:{signal:r.signal}}))}async clear(e,n={}){let r=await this.selfPlayerId();await bn(this.api,r,G(e),{...n.signal===void 0?{}:{signal:n.signal}});}};var ca="https://function.gem.invalid",ur={token:"function",expiresAt:Number.POSITIVE_INFINITY,chainEndsAt:Number.POSITIVE_INFINITY},pa="createGem() from @indiegems/gem-web-sdk/function only runs inside a serverless function; in a browser import @indiegems/gem-web-sdk/sdk",Le="gem.me is unavailable: this function was invoked by a game server, not a player",ga="gem.functions is unavailable inside a serverless function",ma="gem.gameConfig is unavailable inside a serverless function",ya="conditional requests are unavailable inside a serverless function: the platform call carries no headers, so an ifMatch or ifNoneMatch cannot travel. Drop the option, or keep the compare-and-set in the browser.";function fa(t){let e=new Set(N);return {async request(n){let r={...n},i=r.headers;if(i){for(let[a,s]of Object.entries(i))if(s!==void 0&&e.has(a.toLowerCase()))throw new v(ya)}return t.request(r)}}}function cr(t,e,n){Object.defineProperty(t,e,{get(){throw new Error(n)},enumerable:false});}function ha(t){let e=globalThis.__gemFunctionHost;if(e===void 0)throw new Error(pa);let n=e.context(),r=new _e({clock:M,request:()=>Promise.resolve(ur)});r.accept(ur);let i=fa(wt({baseUrl:ca,tokenSource:r,defaultQuery:{game_id:n.gameId,channel:n.channel}})),a=new z({transport:i,clock:M,maxRetries:0}),s={client:a,gameId:()=>n.gameId},l=n.caller.type==="player"?n.caller.playerId:null,o=l===null?null:{playerId:l,gameId:n.gameId,channel:n.channel},c=l===null?null:{type:"players",id:l},p=c===null?null:Ht(s,c).scope,g=c===null||p===null?null:new oe(s,c,p.inventory),h=j=>console.info(j),y=new H({client:()=>a,clock:M,gameId:()=>n.gameId,playerId:()=>l,environment:{sdk_version:dn()},log:h}),_={context:n,identity:o,awaitIdentity:()=>o===null?Promise.reject(new Error(Le)):Promise.resolve(o),awaitBridge:()=>Promise.resolve("connected"),client:a,get me(){if(p===null)throw new Error(Le);return p},characters:new se(s),get transfers(){if(g===null)throw new Error(Le);return g},analytics:y,leaderboards:new ce(s),challenges:new K(s),showcase:new me(s,()=>l===null?Promise.reject(new Error(Le)):Promise.resolve(l)),friends:new le(s),platform:new pe(s,void 0,h),profiles:new ge(s)};return cr(_,"functions",ga),cr(_,"gameConfig",ma),_}var _a=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]]),on=class extends f{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:_a.get(this.code))??super.retryable}};
|
|
3
|
-
export{H as AnalyticsApi,x as AuthError,N as CONDITIONAL_HEADERS,K as ChallengesApi,
|
|
1
|
+
globalThis.__gemWebSdkVersion="[gem-web-sdk:sdkVersion:20.1.0]";function cn(){let t=globalThis.__gemWebSdkVersion;if(typeof t!="string")return "";let e=t.lastIndexOf(":"),n=t.lastIndexOf("]");return e<0||n<=e+1?"":t.slice(e+1,n)}function d(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 pn(t,e,n){let r=`/v1/inventory/transfers/${d(e)}/accept`;return t.client.post(r,void 0,n?.signal)}async function gn(t,e,n,r,i,a){let s=`/v1/inventory/${d(e)}/${d(n)}/progressions/${d(r)}/add`;return t.client.post(s,i,a?.signal)}async function mn(t,e,n){let r=`/v1/inventory/transfers/${d(e)}/cancel`;return t.client.post(r,void 0,n?.signal)}async function yn(t,e,n,r,i,a){let s=`/v1/inventory/${d(e)}/${d(n)}/progressions/${d(r)}/claim`;return t.client.post(s,i,a?.signal)}async function fn(t,e,n){return t.client.post("/v1/characters",e,n?.signal)}async function hn(t,e,n,r,i){let a=`/v1/inventory/${d(e)}/${d(n)}/orders/batch`;return t.client.post(a,r,i?.signal,{...i?.ifMatch===void 0?{}:{ifMatch:i.ifMatch}})}async function _n(t,e,n,r,i){let a=`/v1/inventory/${d(e)}/${d(n)}/orders`;return t.client.post(a,r,i?.signal,{...i?.ifMatch===void 0?{}:{ifMatch:i.ifMatch}})}async function bn(t,e,n,r,i){let a=`/v1/settings/${d(e)}/${d(n)}/${d(r)}`;return t.client.delete(a,i?.signal)}async function Rn(t,e,n,r,i){let a=`/v1/saves/${d(e)}/${d(n)}/${d(r)}`;return t.client.delete(a,i?.signal)}async function wn(t,e,n,r){let i=`/v1/showcase/players/${d(e)}/${d(n)}`;return t.client.delete(i,r?.signal)}async function vn(t,e,n,r,i){let a=`/v1/inventory/${d(e)}/${d(n)}/recipes/execute`;return t.client.post(a,r,i?.signal,{...i?.ifMatch===void 0?{}:{ifMatch:i.ifMatch}})}async function xn(t,e,n,r,i,a){let s=`/v1/saves/${d(e)}/${d(n)}/${d(r)}/finalize`;return t.client.post(s,i,a?.signal)}async function Sn(t,e,n){let r=`/v1/characters/${d(e)}`;return t.client.get(r,n?.signal)}async function kn(t,e,n,r,i){let a=`/v1/settings/${d(e)}/${d(n)}/${d(r)}`;return t.client.getWithEtag(a,{...i?.signal===void 0?{}:{signal:i.signal},...i?.ifNoneMatch===void 0?{}:{ifNoneMatch:i.ifNoneMatch}})}async function An(t,e,n,r){let i=new URLSearchParams;r?.include_buckets!==void 0&&i.set("include_buckets",String(r?.include_buckets)),r?.include_custom_data!==void 0&&i.set("include_custom_data",String(r?.include_custom_data)),r?.currency_limit!==void 0&&i.set("currency_limit",String(r?.currency_limit)),r?.currency_cursor!==void 0&&i.set("currency_cursor",String(r?.currency_cursor)),r?.item_limit!==void 0&&i.set("item_limit",String(r?.item_limit)),r?.item_cursor!==void 0&&i.set("item_cursor",String(r?.item_cursor)),r?.progression_limit!==void 0&&i.set("progression_limit",String(r?.progression_limit)),r?.progression_cursor!==void 0&&i.set("progression_cursor",String(r?.progression_cursor));let a=i.toString(),s=`/v1/inventory/${d(e)}/${d(n)}`+(a?`?${a}`:"");return t.client.get(s,r?.signal)}async function Pn(t,e,n,r,i){let a=`/v1/inventory/${d(e)}/${d(n)}/items/${d(r)}`;return t.client.get(a,i?.signal)}async function On(t,e,n,r,i){let a=new URLSearchParams;i?.bucket_1!==void 0&&a.set("bucket_1",String(i?.bucket_1)),i?.bucket_2!==void 0&&a.set("bucket_2",String(i?.bucket_2)),i?.limit!==void 0&&a.set("limit",String(i?.limit)),i?.periods_back!==void 0&&a.set("periods_back",String(i?.periods_back)),i?.period!==void 0&&a.set("period",String(i?.period)),i?.player_id!==void 0&&a.set("player_id",String(i?.player_id));let s=a.toString(),l=`/v1/leaderboards/${d(e)}/${d(n)}/${d(r)}`+(s?`?${s}`:"");return t.client.get(l,i?.signal)}async function Cn(t,e,n,r,i){let a=`/v1/inventory/${d(e)}/${d(n)}/orders/${d(r)}`;return t.client.get(a,i?.signal)}async function Gn(t,e,n,r,i){let a=`/v1/inventory/${d(e)}/${d(n)}/progressions/${d(r)}`;return t.client.get(a,i?.signal)}async function In(t,e,n,r,i,a){let s=`/v1/inventory/${d(e)}/${d(n)}/catalogs/${d(r)}/recipes/${d(i)}/availability`;return t.client.get(s,a?.signal)}async function Tn(t,e,n,r){let i=new URLSearchParams;i.set("limit",String(r?.limit));let a=i.toString(),s=`/v1/inventory/${d(e)}/${d(n)}/recipe-usage`+(a?`?${a}`:"");return t.client.get(s,r?.signal)}async function Fe(t,e,n,r,i){let a=`/v1/saves/${d(e)}/${d(n)}/${d(r)}`;return t.client.getWithEtag(a,{...i?.signal===void 0?{}:{signal:i.signal},...i?.ifNoneMatch===void 0?{}:{ifNoneMatch:i.ifNoneMatch}})}async function En(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 i=r.toString(),a=`/v1/leaderboards/${d(e)}/friends`+(i?`?${i}`:"");return t.client.get(a,n?.signal)}async function Ln(t,e,n){let r=`/v1/showcase/friends/${d(e)}`;return t.client.get(r,n?.signal)}async function Mn(t,e,n){let r=`/v1/inbox/friend-challenges/${d(e)}`;return t.client.get(r,n?.signal)}async function qn(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 i=r.toString(),a=`/v1/leaderboards/${d(e)}`+(i?`?${i}`:"");return t.client.get(a,n?.signal)}async function Fn(t,e){let n=`/v1/games/${d(t.gameId())}/players/me/earn-allowance`;return t.client.get(n,e?.signal)}async function $n(t,e){let n=`/v1/games/${d(t.gameId())}/players/me/passes`;return t.client.get(n,e?.signal)}async function _e(t,e){return t.client.get("/v1/inventory/players/me/platform-currencies",e?.signal)}async function jn(t,e,n){let r=`/v1/profiles/players/${d(e)}`;return t.client.get(r,n?.signal)}async function Nn(t,e){let n=new URLSearchParams;e?.config_version!==void 0&&n.set("config_version",String(e?.config_version));let r=n.toString(),i="/v1/inventory/platform-funded-game-inventory-purchase-catalog"+(r?`?${r}`:"");return t.client.get(i,e?.signal)}async function Dn(t,e,n,r){let i=`/v1/showcase/players/${d(e)}/${d(n)}`;return t.client.get(i,r?.signal)}async function Bn(t,e){return t.client.get("/v1/characters/slots",e?.signal)}async function Un(t,e,n){let r=`/v1/inventory/transfers/${d(e)}`;return t.client.get(r,n?.signal)}async function Vn(t,e,n){let r=`/v1/games/${d(t.gameId())}/analytics/events`;return t.client.post(r,e,n?.signal,{...n?.keepalive===void 0?{}:{keepalive:n.keepalive},replaySafe:true,retryRateLimited:false})}async function Wn(t,e,n){return t.client.post("/v1/inventory/transfers",e,n?.signal)}async function Hn(t,e,n,r,i){let a=`/v1/inventory/${d(e)}/${d(n)}/platform-funded-game-inventory-purchases`;return t.client.post(a,r,i?.signal)}async function Jn(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(),i="/v1/challenges"+(r?`?${r}`:"");return t.client.get(i,e?.signal)}async function zn(t,e){return t.client.get("/v1/characters",e?.signal)}async function Kn(t,e,n,r){let i=`/v1/settings/${d(e)}/${d(n)}`;return t.client.get(i,r?.signal)}async function Yn(t,e,n,r){let i=new URLSearchParams;r?.limit!==void 0&&i.set("limit",String(r?.limit)),r?.cursor!==void 0&&i.set("cursor",String(r?.cursor));let a=i.toString(),s=`/v1/inventory/${d(e)}/${d(n)}/orders`+(a?`?${a}`:"");return t.client.get(s,r?.signal)}async function Xn(t,e,n,r){let i=new URLSearchParams;r?.limit!==void 0&&i.set("limit",String(r?.limit)),r?.cursor!==void 0&&i.set("cursor",String(r?.cursor));let a=i.toString(),s=`/v1/saves/${d(e)}/${d(n)}`+(a?`?${a}`:"");return t.client.get(s,r?.signal)}async function Qn(t,e){let n=new URLSearchParams;e?.cursor!==void 0&&n.set("cursor",String(e?.cursor)),e?.limit!==void 0&&n.set("limit",String(e?.limit));let r=n.toString(),i="/v1/inbox/friend-challenges"+(r?`?${r}`:"");return t.client.get(i,e?.signal)}async function Zn(t,e){let n=new URLSearchParams;e?.limit!==void 0&&n.set("limit",String(e?.limit)),e?.cursor!==void 0&&n.set("cursor",String(e?.cursor));let r=n.toString(),i="/v1/friends"+(r?`?${r}`:"");return t.client.get(i,e?.signal)}async function et(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(),i="/v1/inventory/transfers"+(r?`?${r}`:"");return t.client.get(i,e?.signal)}async function nt(t,e,n){let r=`/v1/inbox/friend-challenges/${d(e)}/answered`;return t.client.post(r,void 0,n?.signal)}async function tt(t,e,n,r,i,a){let s=`/v1/inventory/${d(e)}/${d(n)}/progressions/${d(r)}/max`;return t.client.post(s,i,a?.signal)}async function rt(t,e,n,r,i,a){let s=`/v1/settings/${d(e)}/${d(n)}/${d(r)}`;return t.client.put(s,i,a?.signal,{...a?.ifMatch===void 0?{}:{ifMatch:a.ifMatch}})}async function it(t,e,n,r,i){let a=`/v1/showcase/players/${d(e)}/${d(n)}`;return t.client.put(a,r,i?.signal)}async function at(t,e,n){let r=`/v1/inventory/transfers/${d(e)}/reject`;return t.client.post(r,void 0,n?.signal)}async function st(t,e,n,r){let i=`/v1/characters/${d(e)}`;return t.client.patch(i,n,r?.signal)}async function ot(t,e,n,r,i,a){let s=`/v1/saves/${d(e)}/${d(n)}/${d(r)}/upload-url`;return t.client.post(s,i,a?.signal,{replaySafe:true})}async function lt(t,e,n,r,i,a){let s=`/v1/inventory/${d(e)}/${d(n)}/progressions/${d(r)}/reset`;return t.client.post(s,i,a?.signal)}async function dt(t,e,n){let r=`/v1/characters/${d(e)}`;return t.client.delete(r,n?.signal)}function ut(t,e){let n=e?.retryAfterSeconds,r=typeof n=="number"&&Number.isFinite(n)&&n>0?n*1e3:0,i=1e4*2**Math.min(Math.max(0,t-1),16);return Math.min(Math.max(r,i),3e5)}var mr="gem_";function $e(t){return t.startsWith(mr)}function yr(t){let e=2166136261;for(let n of new TextEncoder().encode(t))e^=n,e=Math.imul(e,16777619);return e>>>0}function fr(t){let e=t;return e^=e>>>16,e=Math.imul(e,2246822507),e^=e>>>13,e=Math.imul(e,3266489909),e^=e>>>16,e>>>0}function je(t,e,n){if(Ne(t,n),typeof e!="string"||e==="")throw new TypeError("[gem] experiment: playerId must be a non-empty string");let r=typeof n=="number"?n:n.length,i=fr(yr(`${t}:${e}`))%r;return typeof n=="number"?i:n[i]}function Ne(t,e){if(typeof t!="string"||t==="")throw new TypeError("[gem] experiment: key must be a non-empty string");if(typeof e=="number"){if(!Number.isInteger(e)||e<1||e>2048)throw new RangeError(`[gem] experiment '${t}': the count must be an integer from 1 to 2048; got ${String(e)}`);return}if(!Array.isArray(e))throw new TypeError(`[gem] experiment '${t}': pass a count or a list of strings; got ${typeof e}`);let n=e;if(n.length<1||n.length>2048)throw new RangeError(`[gem] experiment '${t}': the list must hold 1 to 2048 strings; got ${n.length}`);if(!n.every(r=>typeof r=="string"))throw new TypeError(`[gem] experiment '${t}': every option must be a string`)}var ct=1e4,pt=50,br=500,Rr=65536-4*1024,wr=24*1024;function gt(t){let e={},n={};for(let[r,i]of Object.entries(t))typeof i=="string"?e[r]=i:typeof i=="number"&&Number.isFinite(i)&&(n[r]=i);return {dimensions:e,measures:n}}var vr=6e4;function xr(t){let e=new Map;for(let n of t??[]){let r=new Set;for(let[i,a]of Object.entries(n.dimensions??{})){let s=a?.range;typeof s=="object"&&s!==null&&r.add(i);}r.size>0&&e.set(n.id,r);}return e}function Sr(t,e){if(e===void 0)return t;let n=null,r={};for(let[i,a]of Object.entries(t.measures))e.has(i)?(n??={...t.dimensions})[i]=String(a):r[i]=a;return n===null?t:{dimensions:n,measures:r}}var mt=t=>typeof t=="number"?t:0,kr=t=>typeof t=="string"?t:"";function be(t=0){return {accepted:0,rejected:[],dropped:t,duplicate:false}}function Ar(t,e){let n=t??{},r=Array.isArray(n.rejected)?n.rejected.map(i=>{let a=i??{};return {index:mt(a.index),code:kr(a.code)}}):[];return {accepted:mt(n.accepted),rejected:r,dropped:e,duplicate:n.duplicate===true}}function De(){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 Pr(t){return t?.retryable===true}var H=class{#e;#t;#a;#h;#n=[];#_={};#s=0;#o=null;#b=false;#R=false;#p=0;#w=0;#v=0;#r=false;#x=null;#l=null;#u=false;#i=false;#g=false;#S=false;#k=false;#m=void 0;#A=false;#P=0;constructor(e){this.#e=e,this.#t=e.options?.enabled!==false,this.#a=Math.max(ct,e.options?.flushIntervalMs??ct),this.#h=Math.max(1,Math.floor(e.options?.maxQueue??br));}track(e,n={}){if(!this.#t||this.#r)return;if($e(e)){this.#k||(this.#k=true,this.#f(`[gem] analytics: '${e}' was not recorded \u2014 the gem_ prefix is reserved for the platform's own events, which the SDK emits for you. Name your event something else.`));return}this.#O(e,gt({...this.#_,...n}));let r=this.#I();this.#m===void 0&&!this.#A&&r!==null&&r!==""&&(this.#A=true,this.#T());}setContext(e){this.#_={...this.#_,...e};}async experiment(e,n){Ne(e,n);let r=this.#e.awaitPlayerId===void 0?this.#e.playerId():await this.#e.awaitPlayerId();if(r===null)throw new Error(`[gem] experiment '${e}': no player to select for \u2014 this call was not made by a player.`);return typeof n=="number"?je(e,r,n):je(e,r,n)}get environment(){let e=this.#e.environment;return {...typeof e=="function"?e():e??{}}}async flush(e={}){if(this.#i)return be();let n=this.#I();if(n===null||n==="")return this.#n.length>0&&!this.#S&&(this.#S=true,this.#f("[gem] analytics: events are being recorded but no play session has been established, so nothing is being sent. Outside the arcade this is expected.")),be();let r=e.keepalive===true;if(!r&&this.#e.declarations!==void 0&&this.#n.some(c=>!$e(c.name))&&await this.#T(),this.#G(),this.#n.length===0||this.#p>0&&!r)return be();this.#c();let i=this.#n.splice(0,this.#L(r)),a=this.#s;this.#s=0;let s=Math.round(this.#e.clock.now()),l={batch_id:De(),sent_at_ms:s,events:i.map(c=>yt(c,s,this.#m?.get(c.name)))},o={client:this.#e.client(),gameId:()=>n};this.#p+=1;try{let c=await Vn(o,l,{...e.signal===void 0?{}:{signal:e.signal},...r?{keepalive:!0}:{}}),p=Ar(c,a);return this.#w=0,this.#v=0,this.#M(p),p}catch(c){throw Pr(c)?(this.#E(i,a),this.#w+=1,this.#v=this.#e.clock.now()+ut(this.#w,c)):this.#f(`[gem] analytics: ${i.length} event(s) were discarded \u2014 the platform refused the batch and will refuse it again: ${String(c)}`),c}finally{this.#p-=1,this.#n.length>0&&this.#d();}}trackPlatform(e,n={}){this.#r||this.#i&&(e==="gem_pause"||e==="gem_resume")||this.#O(e,gt(n));}hold(){this.#r||this.#l!==null||(this.#i=true,this.#c());}release(){if(!this.#i||this.#r)return;this.#i=false;let e=this.#e.clock.now(),n=this.#n.map(r=>({...r,atMs:e}));this.#n=n,this.#g&&(this.#g=false,this.#l=e,this.#u=false,this.#n.unshift({uid:De(),name:"gem_session_start",atMs:e,dimensions:{},measures:{}})),this.#n.length>=pt?this.#y():this.#n.length>0&&this.#d();}get held(){return this.#i}startSession(){if(!(this.#r||this.#l!==null)){if(this.#i){this.#g=true;return}this.#l=this.#e.clock.now(),this.#u=false,this.trackPlatform("gem_session_start");}}endSession(e){if(this.#r||this.#u)return;if(this.#u=true,this.#i){this.#g=false,this.#n=[],this.#s=0;return}let n=this.#l;this.trackPlatform("gem_session_end",{reason:e,...n===null?{}:{duration_ms:Math.max(0,Math.round(this.#e.clock.now()-n))}}),this.#y({keepalive:true});}setPaused(e){this.#r||e===this.#b||(this.#b=e,this.trackPlatform(e?"gem_pause":"gem_resume"),e?this.#c():this.#n.length>0&&this.#d());}setHidden(e){this.#r||e===this.#R||(this.#R=e,e?this.#c():this.#n.length>0&&this.#d());}dispose(){this.#r=true,this.#c(),this.#n=[],this.#s=0;}get pending(){return this.#n.length}#O(e,n){let{dimensions:r,measures:i}=n;for(this.#G();this.#n.length>=this.#h;)this.#n.shift(),this.#s+=1;this.#n.push({uid:De(),name:e,atMs:this.#e.clock.now(),dimensions:r,measures:i}),this.#n.length>=pt?this.#y():this.#d();}#y(e={}){if(e.keepalive!==true&&this.#C()>0){this.#d();return}this.flush(e).catch(()=>{});}#C(){return Math.max(0,this.#v-this.#e.clock.now())}#E(e,n){for(this.#n=[...e,...this.#n],this.#s+=n;this.#n.length>this.#h;)this.#n.shift(),this.#s+=1;}#L(e){let n=e?wr:Rr,r=Math.min(this.#n.length,100),i=128;for(let a=0;a<r;a+=1){let s=this.#n[a];if(s===void 0)break;if(i+=JSON.stringify(yt(s,0,this.#m?.get(s.name))).length+1,i>n)return Math.max(1,a)}return r}#d(){this.#o!==null||this.#b||this.#R||this.#i||this.#r||this.#p>0||(this.#o=this.#e.clock.setTimeout(()=>{this.#o=null,this.#y();},Math.max(this.#a,this.#C())));}#c(){this.#o!==null&&(this.#e.clock.clearTimeout(this.#o),this.#o=null);}#G(){let e=this.#q();e===null||e===""||(this.#x!==null&&this.#x!==e&&(this.#n=[],this.#s=0,this.#l=null,this.#u=false),this.#x=e);}#M(e){for(let n of e.rejected)this.#f(`[gem] analytics: an event was refused (${n.code}). `+Or(n.code));}#f(e){let n=this.#e.log;n!==null&&(n===void 0?console.warn(e):n(e));}#I(){try{return this.#e.gameId()}catch{return null}}#q(){try{return this.#e.playerId()}catch{return null}}async#T(){let e=this.#e.declarations;if(e!==void 0&&!(this.#e.clock.now()<this.#P))try{this.#m=xr(await e());}catch{this.#P=this.#e.clock.now()+vr;}}};function yt(t,e,n){let{dimensions:r,measures:i}=Sr(t,n);return {event_uid:t.uid,name:t.name,offset_ms:Math.round(t.atMs)-e,dimensions:r,measures:i}}function Or(t){switch(t){case "analytics_not_declared":return "This channel has no analytics_events section at all \u2014 promote a game config that declares one. The gem_* events in the same batch were still recorded.";case "unknown_event":return "This channel declares a set of events and this name is not in it \u2014 check the spelling, or declare it in analytics_events.";case "unknown_dimension":return "A string property on this event is not declared as one of its dimensions.";case "missing_dimension":return "A dimension this event declares was not supplied.";case "dimension_value_not_declared":return "A dimension value is outside the closed set the config declares for it.";case "unknown_measure":return "A numeric property on this event is not declared as one of its measures.";case "measure_wrong_type":return "A measure was the wrong shape \u2014 an int measure refuses a fractional value.";case "source_not_permitted":return "This event is declared for the server only, so a client may not emit it.";default:return "See the analytics_events section of your game config."}}var Cr={initialDelayMs:2e3,maxDelayMs:6e4};function Gr(t,e){return e!==void 0?!e:t==="chain_exhausted"}var Re=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 x(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 x("chain_exhausted","the token chain reached its ceiling");if(this.inFlight===null&&this.options.clock.now()<this.notBefore)throw new x(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}=Cr,i=Math.min(r,n*2**(this.failures-1)),a=Math.max(i/2,e??0)+Math.random()*(i/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(i=>{if(n!==this.generation)throw new x("internal","token arrived for a superseded generation");return this.grant=i,this.rejected=false,this.enter("ready"),i.token}).catch(i=>{let a=Ir(i),{retryable:s,retryAfterMs:l}=i??{};throw n===this.generation&&(Gr(a,typeof s=="boolean"?s:void 0)?this.enter("lost",a):(this.scheduleRetry(typeof l=="number"&&Number.isFinite(l)&&l>0?l:void 0),this.enter("degraded",a))),i instanceof x?i:new x(a,String(i))}).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)}},x=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 Ir(t){if(t instanceof x)return t.reason;let e=t?.reason;return typeof e=="string"&&["chain_exhausted","unavailable","timeout","internal"].includes(e)?e:"internal"}var v=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}},N=["if-match","if-none-match"],ft=4096;function Tr(t){if(!t)return;let e={};for(let[n,r]of Object.entries(t)){let i=n.toLowerCase();if(!N.includes(i)||r===void 0)continue;let a=typeof r=="string"?Er(r):r;if(typeof a!="string"||a.length>ft||!Lr(a))throw new v(`the ${i} header value cannot be sent \u2014 it is not a string, is longer than ${ft} 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[i]=a);}return Object.freeze(e)}function Er(t){let e=i=>i===32||i===9||i===10||i===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 Lr(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 Mr(t){let{bytes:e}=t;if(e!==void 0){if(Object.prototype.toString.call(e)!=="[object Uint8Array]")throw new v("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 v("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 ht(t,e){let n=e.replayUnauthorizedOnce??true;return {async request(r){let i={...r},a=Tr(i.headers),s=Mr(i),l=Object.freeze({...i,headers:a,...s===void 0?{}:{bytes:s}}),o=await e.tokenSource.get(),c=await t(l,o);if(c.status!==401||!n)return c;e.tokenSource.invalidate(o);let p=await e.tokenSource.get(),g=await t(l,p);if(g.status===401)throw e.tokenSource.close("unavailable"),new x("unavailable","the server refused a freshly minted token");return g}}}function we(t){let e=typeof t=="string"?new TextEncoder().encode(t):t;return btoa(qr(e))}function _t(t){let e=atob(t),n=new Uint8Array(e.length);for(let r=0;r<e.length;r+=1)n[r]=e.charCodeAt(r);return n}function Be(t){return new TextDecoder().decode(_t(t))}function qr(t){let n="";for(let r=0;r<t.length;r+=32768)n+=String.fromCharCode(...t.subarray(r,r+32768));return n}var f=class extends Error{constructor(n,r,i,a,s){super(`${n} (${r}): ${i}`);this.reason=n;this.status=r;this.detail=i;this.retryAfterSeconds=a;this.code=s;this.name="GemApiError";}reason;status;detail;retryAfterSeconds;code;get retryable(){return this.reason==="unavailable"||this.reason==="rate_limited"}},Fr=new WeakMap;var $r=new Set([408,429,500,502,503,504]),jr=6e4,wt=new WeakMap;function vt(t,e){wt.set(t,e);}function bt(t){return t!==null&&(t.reason==="rate_limited"||t.retryAfterSeconds!==void 0)}function Nr(t){if(t===void 0)return 2;if(!Number.isInteger(t)||t<0||t>10)throw new v(`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 z=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),i=r.etag===void 0?{}:{etag:r.etag};return r.status===304?{modified:false,...i}:{modified:true,body:r.body,...i}}async put(e,n,r,i={}){return this.send({method:"PUT",path:e,body:n,signal:r,...J(i)},i.replaySafe===true,i.retryRateLimited!==false)}async post(e,n,r,i={}){return this.send({method:"POST",path:e,body:n,signal:r,...J(i)},i.replaySafe===true,i.retryRateLimited!==false)}async postBytes(e,n,r,i={}){let a=await this.sendRaw({method:"POST",path:e,bytes:n,responseType:"bytes",signal:r,...J(i)},i.replaySafe===true,i.retryRateLimited!==false);return {bytes:Dr(a.body),...a.invocationId===void 0?{}:{invocationId:a.invocationId}}}async patch(e,n,r,i={}){return this.send({method:"PATCH",path:e,body:n,signal:r,...J(i)},i.replaySafe===true,i.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 i=n?Nr(this.options.maxRetries)+1:1,a=null;if(e.signal?.aborted)throw Rt(e.signal);let s=e.signal===void 0?void 0:wt.get(e.signal);for(let l=0;l<i;l++){if(l>0){let p=this.backoffMs(l,a);if(bt(a)&&s!==void 0&&p>=s())throw a;await this.backoff(p,e.signal);}if(e.signal?.aborted)throw bt(a)&&s!==void 0&&s()<=0?a:Rt(e.signal);let o;try{o=await this.options.transport.request(e);}catch(p){if(x.isAuthError(p)||v.isRefusal(p)||e.signal?.aborted||Br(p))throw p;a=new f("unavailable",0,String(p));continue}if(o.status>=200&&o.status<300||o.status===304)return o;let c=Ur(o);if(!$r.has(o.status)||o.status===429&&!r)throw c;a=c;}throw a??new f("unavailable",0,"no attempt was made")}backoffMs(e,n){let r=n?.retryAfterSeconds,i=r!==void 0?r*1e3:2**(e-1)*250,a=2**(e-1)*250;return Math.min(Math.max(i,a),jr)}backoff(e,n){return n?.aborted?Promise.resolve():new Promise(r=>{let i=this.options.clock,a=false,s=false,l,o=()=>{a||(a=true,s&&i.clearTimeout(l),n?.removeEventListener("abort",o),r());};n?.addEventListener("abort",o,{once:true}),l=i.setTimeout(o,e),s=true,a&&i.clearTimeout(l);})}};function Dr(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 Rt(t){return t.reason!==void 0?t.reason:new DOMException("The operation was aborted.","AbortError")}function Br(t){let e=t?.name;return e==="AbortError"||e==="TimeoutError"}function Ur(t){let e=Wr(t),n=Jr(t.body),r={...n===void 0?{}:{details:n},...t.invocationId===void 0?{}:{invocationId:t.invocationId}};return Object.keys(r).length>0&&Fr.set(e,r),e}var Vr=new Map([["insufficient_funds","insufficient_funds"]]);function Wr(t){let{status:e,body:n}=t,r=Hr(n),i=t.retryAfterSeconds??Kr(n),a=zr(n),s=a===void 0?void 0:Vr.get(a);if(s!==void 0)return new f(s,e,r,void 0,a);switch(e){case 304:return new f("not_modified",e,r);case 400:case 422:return new f("invalid",e,r,void 0,a);case 403:return new f("forbidden",e,r,void 0,a);case 404:return new f("not_found",e,r,void 0,a);case 402:return new f("insufficient_funds",e,r,void 0,a);case 409:return new f("conflict",e,r,void 0,a);case 412:return new f("precondition_failed",e,r,void 0,a);case 413:return new f("too_large",e,r,void 0,a);case 429:return new f("rate_limited",e,r,i,a);default:return new f("unavailable",e,r,i,a)}}function Hr(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 Jr(t){let n=t?.error?.details;return n===null?void 0:n}function zr(t){let n=t?.error?.code;return typeof n=="string"&&n.length>0?n:void 0}function Kr(t){let e=t?.retryAfterSeconds;return typeof e=="number"&&Number.isFinite(e)&&e>=0?e:void 0}function Yr(t){let e=t.lastIndexOf("@");return (e===-1?t:`***@${t.slice(e+1)}`).slice(0,200)}var Xr=new Set(N);function Qr(t){if(!t)return {};let e={};for(let[n,r]of Object.entries(t))Xr.has(n.toLowerCase())&&(e[n.toLowerCase()]=r);return e}function xt(t){let e=t.fetch??globalThis.fetch.bind(globalThis);return ht(async(n,r)=>{let i;try{i=new URL(t.baseUrl.replace(/\/+$/,""));}catch{throw new v("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(i.href.replace(/\/+$/,"")+n.path);}catch{throw new v(`${JSON.stringify(typeof n.path=="string"?Yr(n.path):"(a non-string path)")} does not form a valid URL against ${i.protocol}//${i.host}. This is a malformed request, not a server failure.`)}if(a.protocol!==i.protocol||a.host!==i.host)throw new v(`${JSON.stringify(a.pathname)} resolves to ${a.protocol}//${a.host}, not ${i.protocol}//${i.host}. A request path may not change the request's origin \u2014 it carries the play token.`);if(a.username!==""||a.password!==""){let y=i.username!==""||i.password!=="",_=a.username!==i.username||a.password!==i.password,j=y?_?"baseUrl (and possibly the request path)":"baseUrl":"request path";throw new v(`the ${j} 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[y,_]of Object.entries(t.defaultQuery??{}))a.searchParams.has(y)||a.searchParams.set(y,_);let s=n.bytes,l=n.bytes===void 0?void 0:"application/octet-stream";try{n.body!==void 0&&(s=JSON.stringify(n.body),l="application/json");}catch(y){throw new v(`the body of ${n.method} ${JSON.stringify(a.pathname)} could not be serialised to JSON: ${String(y)}. This is a bug in the request, not a server failure \u2014 retrying sends the same unserialisable value.`)}let o=await e(a.toString(),{method:n.method,headers:{authorization:`Bearer ${r}`,...l===void 0?{}:{"content-type":l},...Qr(n.headers)},body:s,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"&&o.status>=200&&o.status<300)c=new Uint8Array(await o.arrayBuffer());else {let y=await o.text();if(y.length>0)try{c=JSON.parse(y);}catch{c=y;}}let p=o.headers.get("etag"),g=Ue(o.headers.get("retry-after")),h=o.headers.get("x-gem-invocation-id");return {status:o.status,body:c,...p===null?{}:{etag:p},...g===void 0?{}:{retryAfterSeconds:g},...h===null||h===""?{}:{invocationId:h}}},t)}function Ue(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 St=400,P=t=>typeof t=="string"?t:"",Zr=/(?:Z|[+-]\d{2}:?\d{2})$/i;function L(t){let e=P(t);if(!Zr.test(e))return 0;let n=Date.parse(e);return Number.isFinite(n)?Math.floor(n/1e3):0}var ei=/^[0-9a-f]{1,64}$/,ni=/^[0-9a-f]{16}$/,ti=/^[A-Za-z][A-Za-z0-9_+\-/]{0,63}$/,ri=/^(?:[01]\d|2[0-3]):[0-5]\d$/;function Ve(t){let e=P(t),n=/^(\d{4})-(\d{2})-(\d{2})$/.exec(e);if(!n)return;let[r,i,a]=[Number(n[1]),Number(n[2]),Number(n[3])],s=new Date(Date.UTC(r,i-1,a));return s.getUTCFullYear()===r&&s.getUTCMonth()===i-1&&s.getUTCDate()===a?e:void 0}var ii=4096,ai=new TextEncoder;function si(t){let e=P(t.challenge_data),n=P(t.challenge_data_hash);return e===""||!ni.test(n)?{}:ai.encode(e).length>ii?{}:{data:e,dataHash:n}}function oi(t){let e=t??{},n=L(e.period_start_at),r=L(e.period_ends_at);if(n===0||r===0)return;let i=P(e.slug),a=P(e.seed),s=Ve(e.period_local_date),l=P(e.boundary),o=P(e.reset_time);return {id:P(e.progression_definition_id),...i===""?{}:{slug:i},window:P(e.window),periodStartAt:n,periodEndsAt:r,...s===void 0?{}:{periodLocalDate:s},boundary:ti.test(l)?l:"",resetTime:ri.test(o)?o:"",seed:ei.test(a)?a:"",...si(e)}}function ve(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 kt(t){let e=t??{};return Array.isArray(e.challenges)?e.challenges.map(oi).filter(n=>n!==void 0):[]}var K=class{#e;constructor(e){this.#e=e;}async list(e={}){let{periodsBack:n}=e;ve(n);let r=await Jn(this.#e,{...n===void 0?{}:{periods_back:n},...e.signal===void 0?{}:{signal:e.signal}});return kt(r)}};var li="gem-web-bridge";var di=65536,At=8,xe=5e3,Pt=1024;var Se=Object.create(null);var Ot=Object.create(null);function ui(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 ci(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 pi(t){return /^[a-z]{2,8}(-[a-z0-9]{1,8})*$/i.test(t)}function gi(t){return /^[a-z_]+$/.test(t)}function mi(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 We(t,e,n){if(e>At)return `nesting deeper than ${At}`;if(++n.nodes>xe)return `more than ${xe} 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 i=t;if(n.seen.has(i))return "a repeated or cyclic object reference";if(n.seen.add(i),Array.isArray(t)){if(t.length>Pt)return `an array of ${t.length} entries, over the ${Pt} limit`;n.bytes+=2;for(let l of t){let o=We(l,e+1,n);if(o)return o}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 s=t;for(let l in s){if(!Object.prototype.hasOwnProperty.call(s,l))continue;if(++n.nodes>xe)return `more than ${xe} values`;if(n.bytes+=l.length*3+4,n.bytes>n.cap)return `over the ${n.cap} byte limit`;let o=We(s[l],e+1,n);if(o)return o}return null}function yi(t,e=di){let n={nodes:0,bytes:0,seen:new Set,cap:e},r=We(t,0,n);return r?`message contains ${r}`:n.bytes>e?`message is over the ${e} byte limit`:null}var fi={origin:[ui,"not a well-formed origin"],url:[ci,"not a safe absolute http(s) URL"],bcp47:[pi,"not a well-formed BCP 47 tag"],code:[gi,"not a code of lower-case letters and underscores"],gameRef:[mi,"not a game id or web address"]};function Ct(t,e,n){for(let r of e){let i=n===""?r[0]:`${n}.${r[0]}`,a=t[r[0]];if(a==null){if(r[1]<"a")continue;return `${i}: required`}let s=He(a,r,i);if(s)return s}return null}function He(t,e,n){let r=e[1].toLowerCase();switch(r){case "u":return typeof t=="boolean"?null:He(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[i,a]=fi[e[3]];if(!i(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 i=e[2];return i.includes(t)?null:`${n}: not one of ${i.join("|")}`}case "o":return typeof t!="object"||t===null||Array.isArray(t)?`${n}: expected object`:Ct(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 i=e[3],a=`${n}[]`;for(let s of t){if(s==null){if(i[1]<"a")continue;return `${a}: required`}let l=He(s,i,a);if(l)return l}return null}default:return `${n}: unknown kind ${String(r)}`}}var Gt=Object.create(null);function u(t,e,n,r,i){return Se[t]=n,r&&(Ot[t]=r),Gt[t]=a=>{let s=yi(a,i);if(s)return s;if(typeof a!="object"||a===null||Array.isArray(a))return "message: expected object";let l=a;return l.gem!==li?"gem: wrong protocol marker":l.type!==t?`type: expected ${t}`:Ct(l,e,"")}}var Y=["","s",64],m=["requestId","s",64],X=["matchId","s",64],T=["outcome","e",["ok","declined","unavailable"]],E=["reason","S",64,"code"];u("gem.handshake",[["versions","o",[["min","i",1,1e3],["max","i",1,1e3]]],["capabilities","A",64,Y],["embedder","s",2048,"origin"],["unbidden","B"]],30);u("gem.handshake.accept",[["v","i",1,1e3],["capabilities","A",64,Y]],5);u("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);u("gem.token.denied",[m,["retryable","b"],["retryAfterMs","I",0,36e5],["reason","e",["chain_exhausted","unavailable"]],["correlationId","s",64]],30);u("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);u("gem.pause",[["paused","b"]],120);u("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);u("gem.cohorts",[["cohorts","a",8,["","o",[["experimentId","s",36],["variantKey","s",32]]]]],12,"cohorts");u("gem.earnAllowanceChanged",[],30,"earnAllowance");u("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");u("gem.deviceSettings",[["settings","J"]],12,"deviceSettings");u("gem.willTerminate",[["reason","e",["grant_expiring","session_ended","navigating","kill_switch"]],["graceMs","i",0,6e4]],10);u("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");u("gem.socketState",[["connected","b"],["reason","E",["connecting","dropped","watchdog","terminal"]]],12,"socketState");u("gem.seatedEvent",[["roomId","s",64]],60,"partySeating");u("gem.autoStartFailedEvent",[["roomId","s",64],["code","s",64]],30,"autoStartFailure");u("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");u("gem.signalEvent",[["event","e",["hello","offer","answer","ice","peerJoined","peerLeft","migration","matchEnded","error"]],X,["data","j"]],1800,"p2p");u("gem.relayDraining",[X,["clusterTargetId","s",64],["relayIps","a",16,Y],["drainingSince","s",40],["deadline","s",40]],60,"p2pRelayDrain");u("gem.dedicatedEvent",[["event","e",["answer","error","matchEnded"]],X,["sdp","S",10240],["sessionId","S",64],["code","S",64],["message","S",256],["reason","S",64]],120,"dedicated");u("gem.partyResult",[m,["partyId","S",64]],30,"parties");u("gem.clusterTarget",[["clusterTargetId","s",64],["clusterTargetIds","A",3,Y]],12,"clusterTarget");u("gem.devtools",[["action","e",["open","close","toggle"]]],30,"devtools");u("gem.screenshot",[["maxWidth","i",1,7680],["maxHeight","i",1,4320]],6,"screenshot");u("gem.screenshot.denied",[["reason","e",["not_wired","no_source","unsupported","unreadable","tainted","too_large","busy","declined","failed"]],["retryable","b"]],12,"screenshot");u("gem.requestContext",[],12,"feedbackContext");u("gem.gameContext",[["context","j"]],12,"feedbackContext");u("gem.signal",[["signal","e",["join","offer","answer","ice","migrationAck","hostUnreachable"]],X,["data","j"]],1200,"p2p");u("gem.dedicatedOffer",[X,["sdp","s",10240],["intent","e",["initial","ice_restart","full_reconnect"]]],60,"dedicated");u("gem.partyRequest",[m],12,"parties");u("gem.ready",[],5);u("gem.engaged",[],5,"engagement");u("gem.progress",[["loaded","i",0,1099511627776],["total","i",0,1099511627776]],600);u("gem.requestToken",[m,["reason","e",["initial","expiring","rejected"]]],12);u("gem.requestLocalServer",[m,["gameRoomId","s",64]],6,"localHost");u("gem.localServer",[m,["serverId","S",128]],30,"localHost");u("gem.localServer.denied",[m,["retryable","b"],["reason","e",["refused","unavailable"]]],30,"localHost");u("gem.exit",[["reason","S",64]],5);u("gem.openExternal",[["url","s",2048,"url"]],6);u("gem.requestFullscreen",[["enabled","b"]],30);u("gem.audioState",[["muted","b"]],120,"audioState");u("gem.rewardCue",[["currencySlug","s",32],["expected","I",1,1e9],["origin","O",[["x","i",0,16384],["y","i",0,16384]]]],60,"rewardCue");u("gem.walletDisplay",[["visible","b"],["currencies","A",8,Y],["score","B"]],60,"walletDisplay");u("gem.controlsDeclare",[["uses","o",[["lookSensitivity","S",16,"code"],["gamepadLookSensitivity","S",16,"code"],["invertLookY","S",16,"code"],["touchMovement","S",16,"code"]]]],60,"controls");u("gem.menu",[["settings","b"],["items","A",4,["","o",[["id","s",32],["label","s",40]]]]],60,"gameMenu");u("gem.menuSelect",[["entry","e",["settings","item"]],["id","S",32]],60,"gameMenu");u("gem.gemCorner",[["corner","e",["top-left","top-right","bottom-left","bottom-right"]]],12,"gemCorner");u("gem.menuStyle",[["ground","S",7],["accent","S",7]],12,"menuStyle");u("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");u("gem.settingChange",[["id","s",40],["value","u",40,-1e6,1e6]],120,"gameSettings");u("gem.requestShare",[["params","a",16,["","o",[["key","s",64],["value","s",512]]]]],6,"share");u("gem.requestAvatarPicker",[["tab","E",["2d","3d"]]],6,"avatarPicker");u("gem.vibrate",[["pattern","a",99,["","i",0,1e4]]],600,"vibration");u("gem.frameStats",[["fps","i",0,1e3],["frameTimeP95Ms","i",0,1e5],["counts","E",["pageFrames","gameDraws"]]],120,"frameStats");u("gem.portraitBorders",[["name","S",40]],60,"portraitBorders");u("gem.error",[["code","e",["version_mismatch","handshake_timeout","handshake_duplicate","invalid_message","rate_limited","token_unavailable","unsupported","unsupported_capability","internal"]],["message","S",256]],60);u("gem.requestPurchase",[m,["purchaseKind","e",["item","recipe"]],["targetId","s",64],["currencySlug","s",32],["quantity","I",1,10],["catalogId","S",64]],12,"purchases");u("gem.requestAvatar3dPurchase",[m,["itemId","s",64],["currencySlug","s",32]],12,"avatar3dPurchases");u("gem.purchaseResult",[m,T,E,["purchaseId","S",64]],30,"purchases");u("gem.deviceSettings.put",[m,["settings","j"]],30,"deviceSettings");u("gem.deviceSettings.result",[m,["outcome","e",["stored","too_large","unavailable"]]],30,"deviceSettings");u("gem.requestAd",[m,["placement","s",32],["format","e",["interstitial","rewarded"]]],6,"ads");u("gem.adResult",[m,["outcome","e",["shown","no_ad","unavailable"]]],12,"ads");u("gem.signalMoment",[m,["kind","e",["level_end","run_end","match_end","menu_return","other_break"]],["placement","S",32],["wall","B"]],6,"moments");u("gem.momentResult",[m,["shown","b"]],12,"moments");u("gem.requestSignIn",[m],6,"signIn");u("gem.signInResult",[m,["outcome","e",["signed_in","declined","unavailable"]]],12,"signIn");u("gem.requestFriendChallenge",[m,["playerId","s",64],["template","s",64],["params","J"]],12,"friendChallenges");u("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");u("gem.requestAppLinks",[m],12,"appLinks");u("gem.appLinksResult",[m,T,E,["arcade","O",[["store","e",["app_store","google_play"]]]],["game","O",[["store","e",["app_store","google_play"]]]]],30,"appLinks");u("gem.requestOpenApp",[m,["target","e",["arcade","game"]]],6,"appLinks");u("gem.openAppResult",[m,T,E],30,"appLinks");u("gem.requestOpenGame",[m,["ref","s",40,"gameRef"]],6,"openGame");u("gem.openGameResult",[m,T,E],30,"openGame");u("gem.requestSimilarGames",[m,["limit","I",1,24]],12,"openGame");u("gem.similarGamesResult",[m,T,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);u("gem.requestStoreOffers",[m],12,"store");u("gem.storeOffersResult",[m,T,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);u("gem.requestStorePurchase",[m,["skuId","s",64]],12,"store");u("gem.storePurchaseResult",[m,T,E],30,"store");u("gem.storePurchaseSettled",[["skuId","s",64]],30,"store");u("gem.requestStoreOfferSheet",[m,["skuId","s",64]],12,"storeOfferSheet");u("gem.storeOfferSheetResult",[m,T,E],30,"storeOfferSheet");Object.freeze(Gt);Se.__malformed=60;Object.freeze(Se);Object.freeze(Ot);var M={now:()=>Date.now(),setTimeout:(t,e)=>setTimeout(t,e),clearTimeout:t=>clearTimeout(t)};function It(t){let e=t.toLowerCase();return e==="localhost"||e.endsWith(".localhost")||e==="[::1]"||e==="::1"?true:/^127(\.\d{1,3}){3}$/.test(e)}var Q=class{constructor(e,n){this.inventory=e;this.resolveCurrencyId=n;}inventory;resolveCurrencyId;async list(e={}){return (await this.inventory.snapshot({buckets:e.buckets})).currencies.data.map(r=>({currencyId:r.currencyId,total:r.total,...r.buckets===void 0?{}:{buckets:r.buckets}}))}async get(e,n={}){let i=(await this.inventory.snapshot({buckets:n.buckets})).currencies.data,a=i.find(l=>l.currencyId===e),s;return !a&&this.resolveCurrencyId&&(s=await this.resolveCurrencyId(e).catch(()=>{}),s!==void 0&&(a=i.find(l=>l.currencyId===s))),{currencyId:a?a.currencyId:s??e,total:a?a.total:null,...a?.buckets===void 0?{}:{buckets:a.buckets}}}};function ze(t){let e=Array.isArray(t.achievements)?t.achievements:[],n=[];for(let r of e){let i=r??{};typeof i.id!="string"||i.id===""||typeof i.threshold!="number"||!Number.isFinite(i.threshold)||n.push({id:i.id,threshold:i.threshold,points:typeof i.points=="number"?i.points:0,hidden:i.hidden===true,...typeof i.unlocked_at=="number"&&Number.isFinite(i.unlocked_at)?{unlockedAt:i.unlocked_at}:{},...i.revoked===true?{revoked:true}:{}});}return {...n.length>0?{achievements:n}:{},...t.achievements_unavailable===true?{achievementsUnavailable:true}:{}}}var Tt="inventory",D=t=>typeof t=="number"?t:0,Z=t=>typeof t=="string"?t:"";function Je(t,e){let n=t??{},r=typeof n.next_cursor=="string"?n.next_cursor:void 0;return {data:Array.isArray(n.data)?n.data.map(e):[],...r===void 0?{}:{nextCursor:r}}}function Et(t){let e=t??{};return {itemDefinitionId:Z(e.item_definition_id),instanceId:Z(e.instance_id),quantity:D(e.quantity),acquiredAt:D(e.acquired_at),...e.properties===void 0?{}:{properties:e.properties},...e.custom_data===void 0?{}:{customData:e.custom_data}}}function hi(t){let e=t??{},n=typeof e.etag=="string"?e.etag:void 0;return {currencies:Je(e.currencies,r=>{let i=r??{},a=Array.isArray(i.buckets)?i.buckets.map(s=>{let l=s??{};return {bucket:Z(l.bucket),balance:D(l.balance)}}):void 0;return {currencyId:Z(i.currency_id),total:D(i.total),...a===void 0?{}:{buckets:a}}}),items:Je(e.items,Et),progressions:Je(e.progressions,r=>{let i=r??{};return {progressionDefinitionId:Z(i.progression_definition_id),currentValue:D(i.current_value),completionCount:D(i.completion_count),isCompleted:i.is_completed===true,...ze(i)}}),...n===void 0?{}:{etag:n}}}var ee=class{constructor(e,n,r){this.api=e;this.entity=n;this.cache=r;}api;entity;cache;snapshot(e={}){let n=e.buckets?`${Tt}#buckets`:Tt;return this.cache.read(n,[],()=>this.fetch({includeBuckets:e.buckets}))}async instances(e,n){let r=await this.snapshot();if(r.items.nextCursor===void 0){let a=r.items.data.filter(s=>s.itemDefinitionId===e);if(a.length>0)return a}let i=await Pn(this.api,this.entity.type,this.entity.id,e,n===void 0?{}:{signal:n});return Array.isArray(i)?i.map(Et):[]}page(e){return this.fetch(e)}refresh(){this.invalidate();}onChanged(e){return this.cache.onInvalidate(e)}invalidate(){this.cache.invalidate();}async fetch(e){let n=await An(this.api,this.entity.type,this.entity.id,{...e.includeBuckets?{include_buckets:true}:{},...e.currencyCursor===void 0?{}:{currency_cursor:e.currencyCursor},...e.itemCursor===void 0?{}:{item_cursor:e.itemCursor},...e.progressionCursor===void 0?{}:{progression_cursor:e.progressionCursor},...e.currencyLimit===void 0?{}:{currency_limit:e.currencyLimit},...e.itemLimit===void 0?{}:{item_limit:e.itemLimit},...e.progressionLimit===void 0?{}:{progression_limit:e.progressionLimit},...e.signal===void 0?{}:{signal:e.signal}});return hi(n)}};var _i={unknown_currency:1,currency_not_in_game_payable:1,not_purchasable:1,no_price_in_currency:1,busy:1,cancelled:1,insufficient_funds:1,price_mismatch:1,config_version_stale:1,platform_currency_unavailable:1,not_available:1,recipe_locked:1,already_owned:1,recipe_on_cooldown:1,recipe_max_uses_exceeded:1,item_max_stack_exceeded:1,recipe_costs_unmet:1,quantity_invalid:1,error:1};new Set(Object.keys(_i));var q=class extends RangeError{constructor(n,r){super(r);this.code=n;this.name="PurchaseRefusal";}code;retryable=false};var b=t=>typeof t=="string"?t:"",bi=t=>typeof t=="string"?t:b(t&&typeof t=="object"?t.type:void 0),O=t=>typeof t=="number"?t:0;function Ri(t){let e=t??{};return {prerequisiteType:b(e.prerequisite_type),referenceId:b(e.reference_id),required:O(e.required),current:O(e.current)}}function ne(t){let e=t??{},n=typeof e.etag=="string"?e.etag:void 0;return {orderId:b(e.order_id),status:b(e.status),...n===void 0?{}:{etag:n}}}function ke(){return crypto.randomUUID()}var wi="recipe-usage",Lt=100;function Ae(t){let e=t??{};switch(e.type){case "currency":return {kind:"currency",currencyId:b(e.currency_id),bucket:b(e.bucket),delta:O(e.delta),balanceAfter:O(e.balance_after)};case "item":return {kind:"item",itemDefinitionId:b(e.item_definition_id),instanceId:b(e.instance_id),delta:O(e.delta),quantityAfter:O(e.quantity_after)};case "progression":return {kind:"progression",progressionDefinitionId:b(e.progression_definition_id),delta:O(e.delta),valueAfter:O(e.value_after),completed:e.completed===true};default:return {kind:"other",type:b(e.type)}}}function vi(t){let e=t??{},n=typeof e.rarity_tier=="string"?e.rarity_tier:void 0;return {entryId:b(e.entry_id),...n===void 0?{}:{rarityTier:n},rollNumber:O(e.roll_number),wasReplacement:e.was_replacement===true,grants:Array.isArray(e.grants)?e.grants.map(Ae):[]}}function xi(t){let e=t??{},n=typeof e.etag=="string"?e.etag:void 0,r=Array.isArray(e.loot_results)?e.loot_results.map(vi):void 0;return {orderId:b(e.order_id),status:b(e.status),...n===void 0?{}:{etag:n},granted:Array.isArray(e.granted)?e.granted.map(Ae):[],consumed:Array.isArray(e.consumed)?e.consumed.map(Ae):[],autoClaimedRewards:Array.isArray(e.auto_claimed_rewards)?e.auto_claimed_rewards.map(Ae):[],...r===void 0||r.length===0?{}:{lootResults:r}}}function Si(t){let e=t??{},n=e.price??{};return {payment:"platform_currency",orderId:b(e.target_order_id)||b(e.source_order_id),status:b(e.status),purchaseId:b(e.purchase_id),sourceOrderId:b(e.source_order_id),price:{currencyId:b(n.platform_currency_id),amount:O(n.price)}}}function ki(t){let e=t??{},n=typeof e.last_used_at=="string"?e.last_used_at:void 0,r=typeof e.cooldown_expires_at=="string"?e.cooldown_expires_at:void 0;return {recipeId:b(e.recipe_id),useCount:typeof e.use_count=="number"?e.use_count:0,isOnCooldown:e.is_on_cooldown===true,...n===void 0?{}:{lastUsedAt:n},...r===void 0?{}:{cooldownExpiresAt:r}}}function Mt(t){switch(t.type){case "currency_grant":case "currency_consume":return {type:t.type,currency_id:t.currencyId,amount:t.amount};default:return {type:t.type,item_definition_id:t.itemDefinitionId,quantity:t.quantity}}}var te=class{constructor(e,n,r){this.api=e;this.entity=n;this.cache=r;}api;entity;cache;async create(e,n={}){let r=await this.write(()=>_n(this.api,this.entity.type,this.entity.id,{operations:e.map(Mt),source:n.source??"play",nonce:ke()},{...n.ifMatch===void 0?{}:{ifMatch:n.ifMatch},...n.signal===void 0?{}:{signal:n.signal}}));return ne(r)}async createMany(e,n={}){return this.write(()=>hn(this.api,this.entity.type,this.entity.id,{orders:e.map(r=>({operations:r.map(Mt),nonce:ke()})),source:n.source??"play"},{...n.ifMatch===void 0?{}:{ifMatch:n.ifMatch},...n.signal===void 0?{}:{signal:n.signal}}))}async recipeAvailability(e,n,r){let a=await In(this.api,this.entity.type,this.entity.id,e,n,r===void 0?{}:{signal:r})??{},s=typeof a.uses_remaining=="number"?a.uses_remaining:void 0,l=typeof a.cooldown_expires_at=="string"?a.cooldown_expires_at:void 0,o=Array.isArray(a.lock_reasons)?a.lock_reasons.map(Ri):[];return {canExecute:a.can_execute===true,locked:a.locked===true||o.length>0,lockReasons:o,reasons:Array.isArray(a.reasons)?a.reasons.map(c=>bi(c)):[],...s===void 0?{}:{usesRemaining:s},...l===void 0?{}:{cooldownExpiresAt:l}}}async recipeUsageAll(){return this.cache.read(wi,[],async()=>{let n=await Tn(this.api,this.entity.type,this.entity.id,{limit:Lt})??{},r=Array.isArray(n.usages)?n.usages:[];return {usages:r.map(ki),truncated:r.length>=Lt}})}async recipeUsage(e){return (await this.recipeUsageAll()).usages.find(r=>r.recipeId===e)??null}async purchase(e,n={}){if(e.payment.kind==="configured"){let g=e,h=await this.write(()=>vn(this.api,this.entity.type,this.entity.id,{catalog_id:g.catalogId,recipe_id:g.targetId,game_id:this.api.gameId(),nonce:ke()},{...n.ifMatch===void 0?{}:{ifMatch:n.ifMatch},...n.signal===void 0?{}:{signal:n.signal}}));return {payment:"configured",...xi(h)}}if(this.entity.type!=="players"||this.entity.id!=="me")throw new TypeError("platform-currency purchases are available only on gem.me.mutations");let[r,i]=await Promise.all([Nn(this.api,n.signal===void 0?{}:{signal:n.signal}),_e(this.api,n.signal===void 0?{}:{signal:n.signal})]),a=e.payment.currencySlug.toLowerCase(),s=i.currencies.find(g=>g.currency_id.toLowerCase()===a||g.slug.toLowerCase()===a);if(s===void 0){let g=i.currencies.map(h=>h.slug);throw new q("unknown_currency",`platform currency ${JSON.stringify(e.payment.currencySlug)} is not an active platform currency. Active: ${g.length===0?"none":g.join(", ")}`)}let l=e.kind==="item"?r.items.find(g=>g.item_id===e.targetId):r.recipes.find(g=>g.recipe_id===e.targetId&&g.catalog_id===e.catalogId);if(l===void 0)throw new q("not_purchasable",`purchase target ${JSON.stringify(e.targetId)}`+(e.kind==="recipe"?` in catalog ${JSON.stringify(e.catalogId)}`:"")+` is not purchasable in config version ${r.config_version} on this channel. Send the ${e.kind==="item"?"item":"recipe"} id (not its slug), and check that it has platform_prices and that this config version is promoted`);let o=l.platform_prices.find(g=>g.platform_currency_id===s.currency_id);if(o===void 0){let g=y=>i.currencies.find(_=>_.currency_id===y)?.slug??y,h=l.platform_prices.map(y=>`${g(y.platform_currency_id)} ${y.price}`);throw new q("no_price_in_currency",`purchase target ${JSON.stringify(e.targetId)} has no ${s.slug} price. It is priced in: ${h.length===0?"nothing":h.join(", ")}`)}let c=e.kind==="item"?e.quantity??1:1;if(!Number.isInteger(c)||c<1||c>10)throw new q("quantity_invalid","item purchase quantity must be an integer from 1 through 10");let p=await this.write(()=>Hn(this.api,this.entity.type,this.entity.id,{purchase_kind:e.kind,target_id:e.targetId,...e.kind==="recipe"?{catalog_id:e.catalogId}:{},quantity:c,expected_price:{platform_currency_id:s.currency_id,price:o.price*c},expected_config_version:r.config_version,nonce:ke(),confirmation:"none"},n.signal===void 0?{}:{signal:n.signal}));return Si(p)}async executeRecipe(e,n,r={}){return await this.purchase({kind:"recipe",catalogId:e,targetId:n,payment:{kind:"configured"}},r)}async addProgression(e,n,r){let i=await this.write(()=>gn(this.api,this.entity.type,this.entity.id,e,{amount:n,game_id:this.api.gameId()},r===void 0?{}:{signal:r}));return ne(i)}async maxProgression(e,n,r){let i=await this.write(()=>tt(this.api,this.entity.type,this.entity.id,e,{value:n,game_id:this.api.gameId()},r===void 0?{}:{signal:r}));return ne(i)}async claimProgression(e,n){let r=await this.write(()=>yn(this.api,this.entity.type,this.entity.id,e,{game_id:this.api.gameId()},n===void 0?{}:{signal:n}));return ne(r)}async resetProgression(e,n){let r=await this.write(()=>lt(this.api,this.entity.type,this.entity.id,e,{game_id:this.api.gameId()},n===void 0?{}:{signal:n}));return ne(r)}async write(e){return this.cache.invalidate(),e()}};var Ke=t=>typeof t=="string"?t:"",Ai=t=>typeof t=="number"?t:0;function qt(t){let e=t??{};return {orderId:Ke(e.order_id),status:Ke(e.status),source:Ke(e.source),createdAt:Ai(e.created_at)}}var re=class{constructor(e,n){this.api=e;this.entity=n;}api;entity;async list(e={}){let r=await Yn(this.api,this.entity.type,this.entity.id,{...e.limit===void 0?{}:{limit:e.limit},...e.cursor===void 0?{}:{cursor:e.cursor},...e.signal===void 0?{}:{signal:e.signal}})??{},i=typeof r.next_cursor=="string"?r.next_cursor:void 0;return {data:Array.isArray(r.orders)?r.orders.map(qt):[],...i===void 0?{}:{nextCursor:i}}}async get(e,n){let r=await Cn(this.api,this.entity.type,this.entity.id,e,n===void 0?{}:{signal:n});return qt(r)}};var Pi=["live"],Ye=6e4,Ft=864e5;function Oi(t){let e=t?.passes;if(!Array.isArray(e))return Object.freeze([]);let n=e.flatMap(r=>{let i=r??{};if(typeof i.pass!="string"||i.pass==="")return [];let a=i.held===true,s=a&&typeof i.ends_at=="string"?i.ends_at:null;return [Object.freeze({pass:i.pass,held:a,endsAt:s})]});return Object.freeze(n)}function Ci(t){let n=t.flatMap(r=>r.endsAt===null?[]:[Date.parse(r.endsAt)]).filter(r=>Number.isFinite(r));return n.length===0?null:Math.min(...n)}function $t(t,e,n={}){let{watch:r}=n,i=new Set,a=null,s=0,l=null,o=Ye,c=()=>{l!==null&&r?.clock.clearTimeout(l.handle),l=null;},p=w=>{c(),!(r===void 0||i.size===0)&&(l={handle:r.clock.setTimeout(un,w)});},g=w=>{let A=Ci(w);if(A===null||r===void 0){c();return}let k=A-r.clock.now();p(k>0?Math.min(k,Ft):Ye);},h=w=>{r?.log?.(`[gem] a passes 'changed' listener threw: ${w instanceof Error?w.message:String(w)}`);},y=w=>{let A=a!==null&&JSON.stringify(a)!==JSON.stringify(w);if(a=w,o=Ye,g(w),!!A)for(let k of [...i])try{let he=k(w);typeof he?.then=="function"&&he.then(void 0,h);}catch(he){h(he);}},_=()=>{let w=s;return e.read("passes",Pi,()=>$n(t)).then(A=>{if(w!==s)return _();let k=Oi(A);return y(k),k})},j=()=>{_().catch(()=>{p(o),o=Math.min(o*2,Ft);});};function un(){s+=1,e.invalidate(),c(),r!==void 0&&i.size>0&&j();}return {api:{list:_,async get(w){return (await _()).find(k=>k.pass===w)??Object.freeze({pass:w,held:false,endsAt:null})},on(w,A){let k=i.size===0;return i.add(A),k&&r!==void 0&&(a===null?j():g(a)),()=>{i.delete(A),i.size===0&&c();}}},recheck:un}}var jt=t=>typeof t=="number"?t:0,Gi=t=>typeof t=="string"?t:"";function Ii(t){let e=t??{};return {progressionDefinitionId:Gi(e.progression_definition_id),currentValue:jt(e.current_value),completionCount:jt(e.completion_count),isCompleted:e.is_completed===true,...ze(e)}}var ie=class{constructor(e,n,r){this.api=e;this.entity=n;this.inventory=r;}api;entity;inventory;async list(){return (await this.inventory.snapshot()).progressions.data}async get(e,n){let i=(await this.inventory.snapshot()).progressions.data.find(a=>a.progressionDefinitionId===e);if(i&&i.achievementsUnavailable!==true)return i;try{let a=await Gn(this.api,this.entity.type,this.entity.id,e,n===void 0?{}:{signal:n});return Ii(a)}catch{return i??null}}};var ae=class{constructor(e,n){this.clock=e;this.identity=n;}clock;identity;generation=0;slots=new Map;listeners=new Set;boundTo=null;read(e,n,r,i){this.rebind();let a=n.length===0,s=a?e:e+"\0"+n.join("\0"),l=this.slots.get(s);if(l){let g=l.filledAt;if(g!==void 0&&(i===void 0||this.clock.now()-g<=i))return Promise.resolve(l.value);if(l.inFlight)return l.inFlight}let o=l??{};this.slots.set(s,o);let c=this.generation,p=r().then(g=>(a&&this.generation===c&&(o.value=g,o.filledAt=this.clock.now()),g)).finally(()=>{o.inFlight===p&&(o.inFlight=void 0,o.filledAt===void 0&&this.slots.get(s)===o&&this.slots.delete(s));});return o.inFlight=p,p}invalidate(){this.slots.clear(),this.generation+=1;for(let e of [...this.listeners])e();}onInvalidate(e){return this.listeners.add(e),()=>{this.listeners.delete(e);}}rebind(){if(!this.identity)return;let e=this.identity();e!==this.boundTo&&(this.boundTo=e,this.invalidate());}};function Ti(t){let e=i=>new RegExp(`<${i}>([^<]{0,300})</${i}>`).exec(t)?.[1]?.trim()||void 0,n=[e("Code"),e("AuthenticationErrorDetail")??e("Message")].filter(Boolean);if(n.length>0)return n.join(" \u2014 ");let r=t.trim();return r?r.slice(0,300):""}async function Pe(t){try{let e=Ti(await t.text());return e?`Storage said: ${e}`:""}catch{return ""}}var R=class extends Error{constructor(n,r){super(r);this.reason=n;this.name="GemSaveError";}reason},Ei=3e4,Li=5e3,Nt=6e4,Mi=2**31-1,Dt="the save payload could not reach storage. From a browser this is almost always the storage account's CORS rule, which the platform owns and your game cannot change. If every save fails this way, report it rather than working around it",qi=/^[A-Za-z0-9_]{1,64}$/;function G(t){let e=t.length===0?"a save key cannot be empty":t.length>64?`it is ${t.length} characters; a save key is at most 64`:t.startsWith("_")||t.startsWith("$")?`it begins with ${JSON.stringify(t[0])}, and \`_\` and \`$\` are reserved prefixes`:"a save key is ASCII letters, digits and underscores only \u2014 no hyphens, spaces or other punctuation, unlike a template slug";if(!qi.test(t)||t.startsWith("_"))throw new TypeError(`${JSON.stringify(t)} is not a usable save key: ${e}.`);return t}function Bt(t,e){let n=new AbortController,r=Date.now()+e;vt(n.signal,()=>r-Date.now());let i=AbortSignal.timeout(e),a=()=>n.abort(i.reason),s=()=>n.abort(t?.reason);return t?.aborted?n.abort(t.reason):(i.addEventListener("abort",a,{once:true}),t?.addEventListener("abort",s,{once:true})),{signal:n.signal,release:()=>{i.removeEventListener("abort",a),t?.removeEventListener("abort",s);}}}function Xe(t,e){return t.aborted&&e?.aborted!==true}var Fi=new Set(["x-ms-blob-type"]),$i=/^[ -~]+$/;function ji(t,e){if(t==null)return {};if(typeof t!="object"||Array.isArray(t))throw new R("save_malformed",`the grant for save ${JSON.stringify(e)} described its upload headers as ${Array.isArray(t)?"a list":typeof t}, which is not a set of headers.`);let n={};for(let[r,i]of Object.entries(t)){let a=r.toLowerCase();if(!Fi.has(a))throw new R("save_malformed",`the grant for save ${JSON.stringify(e)} asked the upload to send ${JSON.stringify(r)}, which this SDK does not put on a storage request. Report it \u2014 a platform that needs a new upload header needs an SDK release too.`);if(typeof i!="string"||!$i.test(i))throw new R("save_malformed",`the grant for save ${JSON.stringify(e)} gave header ${JSON.stringify(r)} a value that is not usable as one.`);if(a in n)throw new R("save_malformed",`the grant for save ${JSON.stringify(e)} named ${JSON.stringify(a)} twice.`);n[a]=i;}return n}function Qe(t){let e=typeof t.metadata=="object"&&t.metadata!==null&&!Array.isArray(t.metadata)?t.metadata:void 0;return {key:t.key,sizeBytes:t.size_bytes,etag:t.etag,...e===void 0?{}:{metadata:e},createdAt:t.created_at,updatedAt:t.updated_at}}function Ze(t){return t?.reason==="not_found"}function Ni(t){return t?.code==="save_conflict"}function Ut(t){return t instanceof f&&t.reason==="rate_limited"}async function Vt(t,e){let n=await Pe(e);return new f("rate_limited",429,`the save ${t} answered 429: too many save calls. ${n}`.trim(),Ue(e.headers.get("retry-after")))}function Oe(t){return t.reason!==void 0?t.reason:new DOMException("The operation was aborted.","AbortError")}function Di(t,e,n,r,i){let a=false,s=()=>a?false:(a=true,l.detach?.(),true),l={signal:n.signal,budget:r,deadlineAt:Date.now()+r,teardown:n.teardown===true,overwrite:n.overwrite===true,identity:i,resolve:o=>{s()&&t(o);},reject:o=>{s()&&e(o);},detach:void 0};return l}function Wt(t,e){return t!==null&&e!==null&&e!==t}function Ht(t){return new R("save_conflict",`save ${JSON.stringify(t)} was not written: the signed-in player changed while it waited for the write before it, and it holds the last player's progress.`)}var se=class{constructor(e,n,r={},i){this.api=e;this.entity=n;this.options=r;this.identity=i;}api;entity;options;identity;versions=new Map;seq=0;versionsOf=null;writes=new Map;holdUntil=0;async put(e,n,r={}){let i;try{i=JSON.stringify(n);}catch(a){throw new R("save_malformed",`save ${JSON.stringify(e)} could not be serialised to JSON: ${String(a)}. Retrying stores the same unserialisable value.`)}if(i===void 0)throw new R("save_malformed",`save ${JSON.stringify(e)} is undefined, which is not JSON. Use delete() to remove one.`);return this.putBytes(e,new TextEncoder().encode(i),{...r,contentType:"application/json"})}async putBytes(e,n,r={}){if(G(e),r.signal?.aborted)throw Oe(r.signal);let i=this.budget(r.timeoutMs),a=this.slotWrites(e);return new Promise((s,l)=>{let o=a.queued;o?.release();let c=o?.waiters[o.waiters.length-1];c!==void 0&&this.holdOwn(a,c);let p=this.identity?.()??null;for(let g of o?.waiters.slice()??[])Wt(g.identity,p)&&this.drop(a,g,Ht(e));a.queued=this.queue(a,n,r,Di(s,l,r,i,p),o?.waiters??[]),a.wake?.(),this.pump(e,a);})}holdOwn(e,n){let{signal:r}=n,i=n.deadlineAt-Date.now();if(r?.aborted)return this.drop(e,n,Oe(r));if(i<=0)return this.drop(e,n,this.timeout("save",n.budget));let a=AbortSignal.timeout(i),s=()=>this.drop(e,n,this.timeout("save",n.budget)),l=()=>{r&&this.drop(e,n,Oe(r));};a.addEventListener("abort",s,{once:true}),r?.addEventListener("abort",l,{once:true}),n.detach=()=>{a.removeEventListener("abort",s),r?.removeEventListener("abort",l);};}drop(e,n,r){let i=e.queued?.waiters,a=i?.indexOf(n)??-1;a>=0&&i?.splice(a,1),n.reject(r),e.wake?.();}queue(e,n,r,i,a){let{budget:s}=i,l=[...a,i],o=AbortSignal.timeout(s),c=y=>{if(e.queued===h){this.take(e,h);for(let _ of l)_.reject(y);e.wake?.();}},p=()=>c(this.timeout("save",s)),g=()=>{r.signal&&c(Oe(r.signal));};o.addEventListener("abort",p,{once:true}),r.signal?.addEventListener("abort",g,{once:true});let h={bytes:n,options:r,budget:s,deadlineAt:i.deadlineAt,identity:i.identity,waiters:l,release:()=>{o.removeEventListener("abort",p),r.signal?.removeEventListener("abort",g);}};return h}async pump(e,n){if(!n.running){n.running=true;try{for(let r=n.queued;r!==void 0;r=n.queued){let i=Date.now(),a=this.holdUntil-i;if(a>0){if(a>=r.deadlineAt-i){this.take(n,r);for(let o of r.waiters)o.reject(this.held(e,a));continue}for(let o of r.waiters.slice(0,-1))a>=o.deadlineAt-i&&this.drop(n,o,this.held(e,a));}let s=Math.max(a,this.spacing(n,r,i));if(s>0){await this.pause(n,s);continue}this.take(n,r);let l;try{l=this.precondition(e,r);}catch(o){for(let c of r.waiters)c.reject(o);continue}n.lastSentAt=i;try{let o=await this.send(e,r,l);for(let c of r.waiters)c.resolve(o);}catch(o){for(let c of r.waiters)c.reject(o);}}}finally{n.running=false;}}}spacing(e,n,r){if(e.lastSentAt===void 0||n.waiters.some(s=>s.teardown))return 0;let i=this.options.minWriteIntervalMs??Li,a=Math.min(...n.waiters.map(s=>s.deadlineAt-s.budget/2));return Math.min(e.lastSentAt+i,a)-r}pause(e,n){return new Promise(r=>{let i=()=>{clearTimeout(a),e.wake===i&&(e.wake=void 0),r();},a=setTimeout(i,Math.min(n,Mi));e.wake=i;})}take(e,n){e.queued===n&&(e.queued=void 0),n.release();}slotWrites(e){let n=this.writes.get(e);return n===void 0&&(n={running:false,queued:void 0,lastSentAt:void 0,wake:void 0},this.writes.set(e,n)),n}noteRateLimit(e){if(!Ut(e))return;let n=e.retryAfterSeconds,r=n===void 0?Nt:Math.min(n*1e3,Nt);this.holdUntil=Math.max(this.holdUntil,Date.now()+r);}held(e,n){let r=Math.ceil(n/1e3);return new f("rate_limited",429,`save ${JSON.stringify(e)} was not sent: the platform refused a save call for the rate, and the wait it asked for ends in ${r}s, after this call's timeoutMs. Keep the state and write once the wait is over.`,r)}async send(e,n,r){let{bytes:i,options:a,budget:s}=n,l=a.contentType??"application/octet-stream",o=Bt(a.signal,Math.max(0,n.deadlineAt-Date.now()));try{let c=await ot(this.api,this.entity.type,this.entity.id,e,{size_bytes:i.byteLength,content_type:l,...r,...a.metadata===void 0?{}:{metadata:a.metadata}},{signal:o.signal});if(typeof c.upload_url!="string"||typeof c.session_id!="string")throw new R("save_malformed",`the grant for save ${JSON.stringify(e)} named nowhere to put the bytes.`);let p=ji(c.upload_headers,e),g,h=this.options.fetch??globalThis.fetch.bind(globalThis);try{g=await h(c.upload_url,{method:"PUT",headers:{"content-type":l,...p},body:i,credentials:"omit",signal:o.signal});}catch(_){throw Xe(o.signal,a.signal)?this.timeout("upload",s):new R("upload_failed",`${Dt} for PUT. Underlying error: ${_}`)}if(g.status===429)throw await Vt("upload",g);if(!g.ok){let _=await Pe(g);throw new R("upload_failed",g.status===400?"the save upload answered 400. The platform and the service holding the bytes disagree about what this upload must carry, which is not something your game can fix and not worth retrying \u2014 report it. "+_:`the save upload answered ${g.status}. `+(g.status===403?"An upload URL is short-lived, so this is most likely an expired one \u2014 start the save again rather than retrying the upload. ":"")+_)}let y=Qe(await xn(this.api,this.entity.type,this.entity.id,e,{session_id:c.session_id},{signal:o.signal}));return this.remember(e,y.etag?{kind:"etag",etag:y.etag}:void 0),y}catch(c){throw Ni(c)?new R("save_conflict",`save ${JSON.stringify(e)} was not written: the stored save changed since this game last loaded or wrote it, so another device or tab saved in between. Load it again and decide what to write from what is stored, rather than resending this write.`):(this.noteRateLimit(c),this.rethrow(c,a.signal,o.signal,"save",s))}finally{o.release();}}async get(e,n={}){let r=await this.getBytes(e,n);if(r===null)return null;try{return JSON.parse(new TextDecoder().decode(r))}catch(i){throw new R("save_malformed",`the stored save ${JSON.stringify(e)} is not JSON, so put() did not write it. Read it with getBytes() and decode it yourself. Underlying error: ${i}`)}}async getBytes(e,n={}){G(e);let r=this.budget(n.timeoutMs),i=Bt(n.signal,r),a=this.seq;try{let s;try{let p=await Fe(this.api,this.entity.type,this.entity.id,e,{signal:i.signal});if(!p.modified)return this.remember(e,{kind:"empty"},a),null;s=p.body;}catch(p){if(Ze(p))return this.remember(e,{kind:"empty"},a),null;throw p}if(typeof s.download_url!="string")throw new R("save_malformed",`the record for save ${JSON.stringify(e)} named no link to its stored bytes.`);let l=this.options.fetch??globalThis.fetch.bind(globalThis),o;try{o=await l(s.download_url,{credentials:"omit",signal:i.signal});}catch(p){throw Xe(i.signal,n.signal)?this.timeout("download",r):new R("download_failed",`${Dt} for GET. Underlying error: ${p}`)}if(o.status===429)throw await Vt("download",o);if(!o.ok){let p=await Pe(o);throw new R("download_failed",`the save download answered ${o.status}. `+(o.status===403?"A download link lasts 15 minutes, so this is most likely an expired one \u2014 call get() again for a fresh one. ":"")+p)}let c=new Uint8Array(await o.arrayBuffer());return this.remember(e,s.etag?{kind:"etag",etag:s.etag}:void 0,a),c}catch(s){throw this.slots().get(e)===void 0&&this.remember(e,{kind:"failed"}),this.noteRateLimit(s),this.rethrow(s,n.signal,i.signal,"load",r)}finally{i.release();}}async describe(e,n={}){try{let r=await Fe(this.api,this.entity.type,this.entity.id,G(e),{...n.signal===void 0?{}:{signal:n.signal},...n.ifNoneMatch===void 0?{}:{ifNoneMatch:n.ifNoneMatch}});return r.modified?Qe(r.body):null}catch(r){if(Ze(r))return null;throw r}}async list(e={}){let n=await Xn(this.api,this.entity.type,this.entity.id,{...e.limit===void 0?{}:{limit:e.limit},...e.cursor===void 0?{}:{cursor:e.cursor},...e.signal===void 0?{}:{signal:e.signal}}),r=n.next_cursor;return {saves:(n.data??[]).map(Qe),...typeof r=="string"&&r.length>0?{nextCursor:r}:{}}}async delete(e,n){try{await Rn(this.api,this.entity.type,this.entity.id,G(e),{...n===void 0?{}:{signal:n}});}catch(r){if(!Ze(r))throw r}this.remember(e,{kind:"empty"});}precondition(e,n){if(Wt(n.identity,this.identity?.()??null))throw Ht(e);if(n.waiters.some(i=>i.overwrite))return {};let r=this.slots().get(e);if(r===void 0)return {};if(r.kind==="etag")return {if_match:r.etag};if(r.kind==="empty")return {if_none_match:"*"};throw new R("load_failed",`save ${JSON.stringify(e)} was not written: the last load of this slot failed, so what this write would replace is unknown, and it could be the player's real progress. Load it again before saving, or pass overwrite: true if replacing whatever is stored is what you mean.`)}remember(e,n,r){let i=this.slots(),a=i.get(e);r!==void 0&&a!==void 0&&a.kind!=="failed"&&a.seq>r||(this.seq+=1,n===void 0?i.delete(e):i.set(e,{...n,seq:this.seq}));}slots(){let e=this.identity?.()??null;return e!==null&&e!==this.versionsOf&&(this.versionsOf!==null&&this.versions.clear(),this.versionsOf=e),this.versions}budget(e){return e??this.options.timeoutMs??Ei}timeout(e,n){return new R("save_timeout",`the save ${e} did not finish within ${n}ms`)}rethrow(e,n,r,i,a){return e instanceof R||Ut(e)?e:Xe(r,n)?this.timeout(i,a):e}};function Bi(t){try{return Be(t)}catch{return t}}function en(t,e){let n=t??{},r=typeof n.etag=="string"?n.etag:e;return {key:typeof n.key=="string"?n.key:"",value:typeof n.value=="string"?Bi(n.value):"",...r===void 0?{}:{etag:r},updatedAt:typeof n.updated_at=="number"?n.updated_at:0}}var oe=class{constructor(e,n){this.api=e;this.entity=n;}api;entity;async list(e){let r=(await Kn(this.api,this.entity.type,this.entity.id,e===void 0?{}:{signal:e}))?.settings;return Array.isArray(r)?r.map(i=>en(i)):[]}async get(e,n={}){try{let r=await kn(this.api,this.entity.type,this.entity.id,e,{...n.signal===void 0?{}:{signal:n.signal},...n.ifNoneMatch===void 0?{}:{ifNoneMatch:n.ifNoneMatch}});return r.modified?en(r.body,r.etag):null}catch(r){if(Jt(r))return null;throw r}}async put(e,n,r={}){let i=await rt(this.api,this.entity.type,this.entity.id,e,{value:we(n)},{...r.signal===void 0?{}:{signal:r.signal},...r.ifMatch===void 0?{}:{ifMatch:r.ifMatch}});return en(i)}async delete(e,n){try{await bn(this.api,this.entity.type,this.entity.id,e,n===void 0?{}:{signal:n});}catch(r){if(!Jt(r))throw r}}};function Jt(t){return t?.reason==="not_found"}function nn(t,e,n={}){let r=new ae(M,n.identity);n.onInventoryChanged&&r.onInvalidate(n.onInventoryChanged);let i=new ee(t,e,r);return {settings:new oe(t,e),inventory:i,saves:new se(t,e,n.saves??{},n.identity),currencies:new Q(i,n.resolveCurrencyId),mutations:new te(t,e,r),orders:new re(t,e),progressions:new ie(t,e,i)}}function zt(t,e,n={}){let r=new ae(M,n.identity),i=$t(t,r,n);return {scope:{...nn(t,e,n),passes:i.api},recheckPasses:i.recheck}}var F=t=>typeof t=="string"?t:"",B=t=>typeof t=="number"?t:0;function Ce(t,e){let n=e??{},r=F(n.character_id);if(r==="")throw new Error("[gem] a character response carried no character_id");return {...t(r),id:r,playerId:F(n.player_id),gameId:F(n.game_id),channel:F(n.channel)||"release",name:F(n.name),slotIndex:B(n.slot_index),isActive:n.is_active!==false,createdAt:F(n.created_at),updatedAt:F(n.updated_at)}}var le=class{constructor(e,n,r,i){this.api=e;this.saves=n;this.identity=r;this.resolveCurrencyId=i;}api;saves;identity;resolveCurrencyId;scopes=new Map;scope=e=>{let n=this.scopes.get(e);return n||(n=nn(this.api,{type:"characters",id:e},{saves:this.saves,identity:this.identity,resolveCurrencyId:this.resolveCurrencyId}),this.scopes.set(e,n)),n};async list(e){let r=(await zn(this.api,e===void 0?{}:{signal:e}))?.characters;return Array.isArray(r)?r.map(i=>Ce(this.scope,i)):[]}async get(e,n){let r=await Sn(this.api,e,n===void 0?{}:{signal:n});return Ce(this.scope,r)}async create(e){let n=await fn(this.api,{name:e.name},e.signal===void 0?{}:{signal:e.signal});return Ce(this.scope,n)}async update(e,n,r){let i=await st(this.api,e,{name:n},r===void 0?{}:{signal:r});return Ce(this.scope,i)}async delete(e,n){await dt(this.api,e,n===void 0?{}:{signal:n});}async slots(e){let r=await Bn(this.api,e===void 0?{}:{signal:e})??{};return {totalSlots:B(r?.total_slots),availableSlots:B(r?.available_slots),activeCharacterCount:B(r?.active_character_count),defaultMaxSlots:B(r?.default_max_slots),purchasedExtraSlots:B(r?.purchased_extra_slots),canPurchaseMore:r?.can_purchase_more===true}}};var Xt="[gem: use gem.text.toPlain()]",Kt=new Set,Yt;function Ui(t){try{if(Kt.has(t))return;let e=globalThis.location;if(Yt??=!!e?.port&&It(e.hostname??""),!Yt)return;Kt.add(t),console.warn(`[gem] ${t} is PlayerText, turned into a string: players see ${Xt}. Render text.toPlain(value) (text is in @indiegems/gem-web-sdk/sdk).
|
|
2
|
+
${new Error().stack}`);}catch{}}var S=class{#e;#t;constructor(e,n="player text"){this.#e=e,this.#t=n,Object.freeze(this);}toString(){return Ui(this.#t),Xt}toJSON(){return this.toString()}get[Symbol.toStringTag](){return "PlayerText"}static unwrap(e){return e.#e}};function U(t,e){return new S(t,e)}var Vi={toPlain(t){return S.unwrap(t)},compare(t,e,n){let r=t instanceof S?S.unwrap(t):t,i=e instanceof S?S.unwrap(e):e;if(typeof Intl>"u"||typeof Intl.Collator!="function")return r<i?-1:r>i?1:0;let a;try{a=new Intl.Collator(n);}catch{a=new Intl.Collator;}return a.compare(r,i)},equals(t,e){let n=t instanceof S?S.unwrap(t):t,r=e instanceof S?S.unwrap(e):e;return n.normalize("NFC")===r.normalize("NFC")}};var V=t=>typeof t=="string"?t:"";function Ge(t){let e=t??{},n=typeof e.message=="string"&&e.message.length>0?e.message:void 0,r=typeof e.resolved_at=="string"?e.resolved_at:void 0;return {id:V(e.transfer_id),status:V(e.status),sourceEntityId:V(e.source_entity_id),targetEntityId:V(e.target_entity_id),...n===void 0?{}:{message:U(n,"transfer.message")},createdAt:V(e.created_at),expiresAt:V(e.expires_at),...r===void 0?{}:{resolvedAt:r}}}function Wi(){return crypto.randomUUID()}var de=class{constructor(e,n,r){this.api=e;this.self=n;this.inventory=r;}api;self;inventory;async initiate(e){this.inventory.invalidate();let n=await Wn(this.api,{source_entity_type:this.self.type,source_entity_id:this.self.id,target_entity_type:e.to.type,target_entity_id:e.to.id,items:(e.items??[]).map(r=>({item_definition_id:r.itemDefinitionId,quantity:r.quantity})),currencies:(e.currencies??[]).map(r=>({currency_id:r.currencyId,amount:r.amount})),...e.message===void 0?{}:{message:e.message},nonce:Wi()},e.signal===void 0?{}:{signal:e.signal});return Ge(n)}async list(e={}){let r=await et(this.api,{entity_type:this.self.type,entity_id:this.self.id,...e.direction===void 0?{}:{direction:e.direction},...e.status===void 0?{}:{status:e.status},...e.cursor===void 0?{}:{cursor:e.cursor},...e.limit===void 0?{}:{limit:e.limit},...e.signal===void 0?{}:{signal:e.signal}})??{},i=typeof r.next_cursor=="string"?r.next_cursor:void 0;return {transfers:Array.isArray(r.transfers)?r.transfers.map(Ge):[],...i===void 0?{}:{nextCursor:i}}}async get(e,n){let r=await Un(this.api,e,n===void 0?{}:{signal:n});return Ge(r)}async accept(e,n){return this.resolve(()=>pn(this.api,e,n===void 0?{}:{signal:n}))}async reject(e,n){return this.resolve(()=>at(this.api,e,n===void 0?{}:{signal:n}))}async cancel(e,n){return this.resolve(()=>mn(this.api,e,n===void 0?{}:{signal:n}))}async resolve(e){return this.inventory.invalidate(),Ge(await e())}};function C(t){return typeof t=="string"&&t!==""?t:void 0}var Qt=new Set(["localhost","127.0.0.1","[::1]"]);function $(t){return Hi(t)}function Hi(t){let e=C(t);if(e===void 0)return;let n;try{n=new URL(e);}catch{return}if(!(n.username!==""||n.password!=="")&&(n.protocol==="https:"||n.protocol==="http:"&&Qt.has(n.hostname)))return e}var Ji=/^[\da-f]{8}(-[\da-f]{4}){3}-[\da-f]{12}$/i,zi=/^[a-z][a-z0-9_]{0,31}$/;function Ki(t){if(!Array.isArray(t))return;let e=[],n=new Set;for(let r of t.slice(0,8)){let i=r??{},a=C(i.family),s=C(i.avatar_3d_id),l=$(i.model_url),o=$(i.icon_url);a===void 0||!zi.test(a)||n.has(a)||s===void 0||!Ji.test(s)||l===void 0||o===void 0||(n.add(a),e.push({family:a,id:s,modelUrl:l,iconUrl:o}));}return e}function Yi(t){if(!Array.isArray(t))return [];let e=[];for(let n of t){let r=n??{},i=C(r.item_id),a=$(r.icon_url);i!==void 0&&a!==void 0&&e.push({itemId:i,iconUrl:a});}return e}function I(t){let e=t??{},n=C(e.player_id),r=C(e.display_name),i=C(e.discriminator),a=C(e.display_tag),s=C(e.avatar_icon_id),l=$(e.avatar_icon_url),o=C(e.avatar_3d_id),c=$(e.avatar_3d_model_url),p=$(e.avatar_3d_icon_url),g=Ki(e.avatars_3d);return {...n===void 0?{}:{playerId:n},...r===void 0?{}:{displayName:U(r,"displayName")},...i===void 0?{}:{discriminator:i},...a===void 0?{}:{displayTag:U(a,"displayTag")},...s===void 0?{}:{avatarIconId:s},...l===void 0?{}:{avatarIconUrl:l},...o===void 0?{}:{avatar3dId:o},...c===void 0?{}:{avatar3dModelUrl:c},...p===void 0?{}:{avatar3dIconUrl:p},...g===void 0?{}:{avatars3d:g},badges:Yi(e.badges)}}var Xi=new Set(["https://downloads.gemarcade.com","https://cdn.gemarcade.com"]);function Qi(t){if(t===void 0)return;let e=$(t);if(e===void 0)return;let n=new URL(e);return Qt.has(n.hostname)||Xi.has(n.origin)?e:void 0}var Zt=/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;var rn=class extends f{constructor(e,n={}){super(e.reason,e.status,e.detail,e.retryAfterSeconds,e.code),this.name="FriendChallengeError";for(let[r,i]of Object.entries(n))i!==void 0&&Object.assign(this,{[r]:i});}},Ie=t=>typeof t=="string"?t:void 0;function er(t){let e=t??{};return {...I(e),playerId:Ie(e.player_id)??""}}function nr(t){let e=t.has_more===true?Ie(t.next_cursor):void 0;return e===void 0?{}:{nextCursor:e}}function Zi(t){let e=t??{};return {friends:Array.isArray(e.data)?e.data.map(er):[],...nr(e)}}var tn=t=>typeof t=="number"&&Number.isFinite(t)?t:void 0;function ea(t){return typeof t!="object"||t===null||Array.isArray(t)?{}:Object.fromEntries(Object.entries(t).filter(e=>typeof e[1]=="string"||typeof e[1]=="number"&&Number.isFinite(e[1])))}function tr(t){let e=t??{},n=tn(e.opened_at),r=tn(e.answered_at);return {id:Ie(e.item_id)??"",from:er(e.sender),template:Ie(e.template)??"",params:ea(e.params),createdAt:tn(e.created_at)??0,...n===void 0?{}:{openedAt:n},...r===void 0?{}:{answeredAt:r}}}function na(t){let e=t??{};return {challenges:Array.isArray(e.data)?e.data.map(tr):[],...nr(e)}}function ta(t){let e=t;return e?.reason==="not_found"&&e.code==="inbox_item_not_found"}var ue=class{#e;#t;#a;constructor(e,n={}){this.#e=e,this.#t=n.challenge,this.#a=n.launchedChallengeId;}async list(e={}){let n=await Zn(this.#e,{...e.limit===void 0?{}:{limit:e.limit},...e.cursor===void 0?{}:{cursor:e.cursor},...e.signal===void 0?{}:{signal:e.signal}});return Zi(n)}challenge(e){return this.#t===void 0?Promise.resolve({outcome:"unavailable"}):this.#t(e)}async inbox(e={}){let n=await Qn(this.#e,{...e.limit===void 0?{}:{limit:e.limit},...e.cursor===void 0?{}:{cursor:e.cursor},...e.signal===void 0?{}:{signal:e.signal}});return na(n)}async launchedChallenge(e={}){let n=this.#a;if(n===void 0||!Zt.test(n))return null;try{return tr(await Mn(this.#e,n,{...e.signal===void 0?{}:{signal:e.signal}}))}catch(r){if(ta(r))return null;throw r}}async markAnswered(e){if(typeof e!="string"||!Zt.test(e))throw new f("invalid",400,"id must be a FriendChallenge.id, as gem.friends.launchedChallenge() or inbox() returned it",void 0,"bad_request");await nt(this.#e,e);}};var rr=100,sr=/^\d{4}-\d{2}-\d{2}(?:T\d{2}:\d{2}:\d{2}Z)?$/;function an(t){let{periodsBack:e,period:n,playerId:r}=t;if(ve(e),e!==void 0&&n!==void 0)throw new TypeError("pass periodsBack or period, not both");if(n!==void 0&&(typeof n!="string"||!sr.test(n)))throw new TypeError(`period must be a period id such as 2026-10-02 (a result's period.id), got ${String(n)}`);if(r!==void 0&&(typeof r!="string"||r===""))throw new TypeError("playerId must be a player id");return {...e===void 0?{}:{periods_back:e},...n===void 0?{}:{period:n},...r===void 0?{}:{player_id:r}}}function or(t){let e=typeof t.period_id=="string"?t.period_id:"";if(!sr.test(e))return;let n=Ve(t.period_local_date),r=L(t.period_start_at),i=L(t.period_ends_at),a=r>0&&i>0;return {id:e,...n===void 0?{}:{localDate:n},...a?{startAt:r,endsAt:i}:{},opensAt:L(t.opens_at),closesAt:L(t.closes_at),final:t.final===true}}var ce=t=>typeof t=="string"?t:"",W=t=>typeof t=="number"?t:0,pe=t=>typeof t=="string"?t:void 0,ra=t=>typeof t=="number"?t:void 0,lr={player:"players",character:"characters"};function ia(t,e){let n=t??{},r=pe(n.entity_id),i=typeof n.entity_type=="string"&&Object.hasOwn(lr,n.entity_type)?n.entity_type:void 0,a=dr(n.stats),s=n.properties!==null&&typeof n.properties=="object"?n.properties:void 0,l=e?n.is_viewer===true:void 0;return {...I(n),rank:W(n.rank),occurredAt:W(n.occurred_at),...l===void 0?{}:{isViewer:l},...r===void 0?{}:{entityId:r},...i===void 0?{}:{entityType:i},...a===void 0?{}:{stats:a},...s===void 0?{}:{properties:s}}}function ir(t,e){let n=t??{},r=pe(n.bucket_1),i=pe(n.bucket_2),a=ra(n.update_frequency_seconds),s=or(n);return {leaderboardType:ce(n.leaderboard_type),runType:ce(n.run_type),...r===void 0?{}:{bucket1:r},...i===void 0?{}:{bucket2:i},entries:Array.isArray(n.entries)?n.entries.map(l=>ia(l,e)):[],generatedAt:W(n.generated_at),...a===void 0?{}:{updateFrequencySeconds:a},...s===void 0?{}:{period:s}}}function ar(t){if(t===null||typeof t!="object"||Array.isArray(t))return;let e=t;if(!Number.isFinite(e.rank))return;let n=dr(e.stats),r=e.properties!==null&&typeof e.properties=="object"?e.properties:void 0;return {rank:e.rank,occurredAt:W(e.occurred_at),...n===void 0?{}:{stats:n},...r===void 0?{}:{properties:r}}}function dr(t){if(t===null||typeof t!="object")return;let e={};for(let[n,r]of Object.entries(t))typeof r=="number"&&(e[n]=r);return e}function aa(t,e,n){let r=t??{},i=pe(r.bucket_1),a=pe(r.bucket_2),s=or(r);return {leaderboardType:ce(r.leaderboard_type),runType:ce(r.run_type),entityType:e,entityId:n,...i===void 0?{}:{bucket1:i},...a===void 0?{}:{bucket2:a},entries:Array.isArray(r.entries)?r.entries.map(ar).filter(l=>l!==void 0):[],personalBest:ar(r.personal_best)??null,totalRuns:W(r.total_runs),totalRunsExact:r.total_runs_exact!==false,generatedAt:W(r.generated_at),...s===void 0?{}:{period:s}}}var ge=class{#e;constructor(e){this.#e=e;}async get(e,n={}){let r=an(n),i=await qn(this.#e,e,{...r,...n.bucket1===void 0?{}:{bucket_1:n.bucket1},...n.bucket2===void 0?{}:{bucket_2:n.bucket2},...n.signal===void 0?{}:{signal:n.signal}});return ir(i,false)}async friends(e,n={}){let r=an(n),i=await En(this.#e,e,{...r,...n.bucket1===void 0?{}:{bucket_1:n.bucket1},...n.bucket2===void 0?{}:{bucket_2:n.bucket2},...n.signal===void 0?{}:{signal:n.signal}});return ir(i,true)}async mine(e,n={}){return this.#t(e,"player","me",n)}async character(e,n,r={}){return this.#t(e,"character",n,r)}async#t(e,n,r,i){if(i.limit!==void 0){let{limit:o}=i;if(!Number.isInteger(o)||o<1||o>rr)throw new TypeError(`limit must be an integer between 1 and ${rr}, got ${String(o)}`)}let a=an(i),s=await On(this.#e,e,lr[n],r,{...a,...i.bucket1===void 0?{}:{bucket_1:i.bucket1},...i.bucket2===void 0?{}:{bucket_2:i.bucket2},...i.limit===void 0?{}:{limit:i.limit},...i.signal===void 0?{}:{signal:i.signal}}),l=n==="player"&&r==="me"&&ce((s??{}).entity_id)||r;return aa(s,n,l)}};var Te=t=>typeof t=="string"?t:void 0;function sa(t){let e=t??{},n=Te(e.currency_id);if(n===void 0||n==="")return;let r=typeof e.balance=="number"&&Number.isFinite(e.balance)?e.balance:0;return {slug:Te(e.slug)??"",currencyId:n,balance:r,access:e.access==="spend"?"spend":"read"}}var Ee=class{#e;constructor(e){this.#e=e;}async get(e={}){let r=(await _e(this.#e,e))?.currencies;if(!Array.isArray(r))return [];let i=[];for(let a of r){let s=sa(a);s!==void 0&&i.push(s);}return i}},sn=t=>typeof t=="number"&&Number.isFinite(t)&&t>=0?Math.floor(t):0;function oa(t){let e=t??{},n=Te(e.currency_id);if(n===void 0||n==="")return;let r=sn(e.limit),i=Math.min(sn(e.earned),r),a=Math.min(sn(e.remaining),r-i),s=e.period_days,l=typeof s=="number"&&Number.isInteger(s)&&s>=1?s:1,o=e.resets_at,c=typeof o=="number"&&Number.isFinite(o)&&o>0?Math.round(o*1e3):void 0;return {currencySlug:Te(e.currency_slug)??"",currencyId:n,limit:r,earned:i,remaining:a,period:e.period==="day"?"day":"window",periodDays:l,...c===void 0?{}:{resetsAt:c}}}var Le=class{#e;#t;#a;constructor(e,n,r){this.#e=e,this.#t=n,this.#a=r;}async get(e={}){let r=(await Fn(this.#e,e))?.currencies;if(!Array.isArray(r))return [];let i=[];for(let a of r){let s=oa(a);s!==void 0&&i.push(s);}return i}on(e,n){return e!=="changed"?(this.#a?.(`[gem] unknown earnAllowance event '${String(e)}'; the only event is 'changed'`),()=>{}):this.#t?.on(n)??(()=>{})}},me=class{currencies;earnAllowance;constructor(e,n,r){this.currencies=new Ee(e),this.earnAllowance=new Le(e,n,r);}};var on=t=>typeof t=="string"?t:"",ur=t=>typeof t=="number"?t:0;function la(t){let e=t??{};return {key:on(e.key),visibility:on(e.visibility),value:e.value,updatedAt:ur(e.updated_at)}}function da(t){let e=t??{};return {...I(e),playerId:on(e.player_id),showcase:Array.isArray(e.showcase)?e.showcase.map(la):[],generatedAt:ur(e.generated_at)}}function ua(t){return t?.reason==="not_found"}var ye=class{#e;constructor(e){this.#e=e;}async of(e,n={}){try{return da(await jn(this.#e,e,{...n.signal===void 0?{}:{signal:n.signal}}))}catch(r){if(ua(r))return null;throw r}}};var Me=t=>typeof t=="string"?t:"",ln=t=>typeof t=="number"?t:0;function cr(t){let e=t??{};return {playerId:Me(e.player_id),key:Me(e.key),value:e.value,updatedAt:ln(e.updated_at)}}function ca(t){let e=t??{};return {...I(e),playerId:Me(e.player_id),value:e.value,isViewer:e.is_viewer===true,updatedAt:ln(e.updated_at)}}function pa(t){return t?.reason==="not_found"}var fe=class{constructor(e,n){this.api=e;this.selfPlayerId=n;}api;selfPlayerId;async friends(e,n={}){let i=await Ln(this.api,G(e),{...n.signal===void 0?{}:{signal:n.signal}})??{};return {key:Me(i.key),entries:Array.isArray(i.entries)?i.entries.map(ca):[],generatedAt:ln(i.generated_at)}}async of(e,n,r={}){try{return cr(await Dn(this.api,e,G(n),{...r.signal===void 0?{}:{signal:r.signal}}))}catch(i){if(pa(i))return null;throw i}}async set(e,n,r={}){if(G(e),n===void 0)throw new TypeError(`showcase value for ${JSON.stringify(e)} is undefined, which is not JSON. Use clear() to remove one.`);try{JSON.stringify(n);}catch(a){throw new TypeError(`showcase value for ${JSON.stringify(e)} could not be serialised to JSON: ${String(a)}.`,{cause:a})}let i=await this.selfPlayerId();return cr(await it(this.api,i,e,{value:n},{...r.signal===void 0?{}:{signal:r.signal}}))}async clear(e,n={}){let r=await this.selfPlayerId();await wn(this.api,r,G(e),{...n.signal===void 0?{}:{signal:n.signal}});}};var ga="https://function.gem.invalid",pr={token:"function",expiresAt:Number.POSITIVE_INFINITY,chainEndsAt:Number.POSITIVE_INFINITY},ma="createGem() from @indiegems/gem-web-sdk/function only runs inside a serverless function; in a browser import @indiegems/gem-web-sdk/sdk",qe="gem.me is unavailable: this function was invoked by a game server, not a player",ya="gem.functions is unavailable inside a serverless function",fa="gem.gameConfig is unavailable inside a serverless function",ha="conditional requests are unavailable inside a serverless function: the platform call carries no headers, so an ifMatch or ifNoneMatch cannot travel. Drop the option, or keep the compare-and-set in the browser.";function _a(t){let e=new Set(N);return {async request(n){let r={...n},i=r.headers;if(i){for(let[a,s]of Object.entries(i))if(s!==void 0&&e.has(a.toLowerCase()))throw new v(ha)}return t.request(r)}}}function gr(t,e,n){Object.defineProperty(t,e,{get(){throw new Error(n)},enumerable:false});}function ba(t){let e=globalThis.__gemFunctionHost;if(e===void 0)throw new Error(ma);let n=e.context(),r=new Re({clock:M,request:()=>Promise.resolve(pr)});r.accept(pr);let i=_a(xt({baseUrl:ga,tokenSource:r,defaultQuery:{game_id:n.gameId,channel:n.channel}})),a=new z({transport:i,clock:M,maxRetries:0}),s={client:a,gameId:()=>n.gameId},l=n.caller.type==="player"?n.caller.playerId:null,o=l===null?null:{playerId:l,gameId:n.gameId,channel:n.channel},c=l===null?null:{type:"players",id:l},p=c===null?null:zt(s,c).scope,g=c===null||p===null?null:new de(s,c,p.inventory),h=j=>console.info(j),y=new H({client:()=>a,clock:M,gameId:()=>n.gameId,playerId:()=>l,environment:{sdk_version:cn()},log:h}),_={context:n,identity:o,awaitIdentity:()=>o===null?Promise.reject(new Error(qe)):Promise.resolve(o),awaitBridge:()=>Promise.resolve("connected"),client:a,get me(){if(p===null)throw new Error(qe);return p},characters:new le(s),get transfers(){if(g===null)throw new Error(qe);return g},analytics:y,leaderboards:new ge(s),challenges:new K(s),showcase:new fe(s,()=>l===null?Promise.reject(new Error(qe)):Promise.resolve(l)),friends:new ue(s),platform:new me(s,void 0,h),profiles:new ye(s)};return gr(_,"functions",ya),gr(_,"gameConfig",fa),_}var Ra=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]]),dn=class extends f{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:Ra.get(this.code))??super.retryable}};
|
|
3
|
+
export{H as AnalyticsApi,x as AuthError,N as CONDITIONAL_HEADERS,K as ChallengesApi,le as CharactersApi,Q as CurrenciesApi,rn as FriendChallengeError,ue as FriendsApi,f as GemApiError,z as GemClient,dn as GemFunctionError,R as GemSaveError,ee as InventoryApi,ge as LeaderboardsApi,St as MAX_PERIODS_BACK,te as MutationsApi,re as OrdersApi,me as PlatformApi,Ee as PlatformCurrenciesApi,Le as PlatformEarnAllowanceApi,S as PlayerText,ye as ProfilesApi,ie as ProgressionsApi,se as SavesApi,oe as SettingsApi,fe as ShowcaseApi,de as TransfersApi,v as TransportRefusal,U as asPlayerText,ba as createGem,I as mapIdentity,Qi as platformIconUrl,Vi as text,we as toBase64};//# sourceMappingURL=gem-web-sdk.function.js.map
|
|
4
4
|
//# sourceMappingURL=gem-web-sdk.function.js.map
|