@shaunlwm/pickle.ts 1.7.0 → 1.8.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/dist/index.d.ts +18 -0
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -226,7 +226,9 @@ declare abstract class BaseAdapter {
|
|
|
226
226
|
getIglooOpen(_igloo: number): void;
|
|
227
227
|
getIgloos(): void;
|
|
228
228
|
getPuffles(_userId: number): void;
|
|
229
|
+
adoptPuffle(_type: number, _name: string): void;
|
|
229
230
|
getIglooLikes(): void;
|
|
231
|
+
checkPuffleSprite(_puffleSprite: boolean): void;
|
|
230
232
|
joinIgloo(_igloo: number, _x?: number, _y?: number): void;
|
|
231
233
|
gameOver(_coins: number): void;
|
|
232
234
|
collectStamp(_stamp: number): void;
|
|
@@ -291,7 +293,9 @@ declare class CpjourneyAdapter extends BaseAdapter {
|
|
|
291
293
|
getIglooOpen(igloo: number): void;
|
|
292
294
|
getIgloos(): void;
|
|
293
295
|
getPuffles(userId: number): void;
|
|
296
|
+
adoptPuffle(type: number, name: string): void;
|
|
294
297
|
getIglooLikes(): void;
|
|
298
|
+
checkPuffleSprite(puffleSprite: boolean): void;
|
|
295
299
|
joinIgloo(igloo: number, x?: number, y?: number): void;
|
|
296
300
|
gameOver(coins: number): void;
|
|
297
301
|
collectStamp(stamp: number): void;
|
|
@@ -581,6 +585,10 @@ type ClientMessages = {
|
|
|
581
585
|
get_mascots: Record<string, never>;
|
|
582
586
|
get_weather: Record<string, never>;
|
|
583
587
|
join_server: Record<string, never>;
|
|
588
|
+
adopt_puffle: {
|
|
589
|
+
type: number;
|
|
590
|
+
name: string;
|
|
591
|
+
};
|
|
584
592
|
check_puffle_sprite: {
|
|
585
593
|
puffleSprite: unknown;
|
|
586
594
|
};
|
|
@@ -833,6 +841,14 @@ type ServerMessages = {
|
|
|
833
841
|
id: number;
|
|
834
842
|
transform: number;
|
|
835
843
|
};
|
|
844
|
+
adopt_puffle: {
|
|
845
|
+
puffle: unknown;
|
|
846
|
+
coins: number;
|
|
847
|
+
};
|
|
848
|
+
/** Generic server info/notification message */
|
|
849
|
+
info: {
|
|
850
|
+
message: string;
|
|
851
|
+
};
|
|
836
852
|
unknown_packet: {
|
|
837
853
|
action: string;
|
|
838
854
|
args: Record<string, unknown>;
|
|
@@ -988,7 +1004,9 @@ declare class Client extends EventEmitter {
|
|
|
988
1004
|
getIglooOpen(igloo: number): Promise<ServerMessages["get_igloo_open"]>;
|
|
989
1005
|
getIgloos(): Promise<ServerMessages["get_igloos"]>;
|
|
990
1006
|
getPuffles(userId: number): Promise<ServerMessages["get_puffles"]>;
|
|
1007
|
+
adoptPuffle(type: number, name: string): Promise<ServerMessages["adopt_puffle"]>;
|
|
991
1008
|
getIglooLikes(): Promise<ServerMessages["get_igloo_likes"]>;
|
|
1009
|
+
checkPuffleSprite(puffleSprite: boolean): void;
|
|
992
1010
|
joinIgloo(igloo: number, x?: number, y?: number): Promise<ServerMessages["join_igloo"]>;
|
|
993
1011
|
gameOver(coins: number): Promise<ServerMessages["game_over"]>;
|
|
994
1012
|
collectStamp(stamp: number): Promise<ServerMessages["stamp_earned"]>;
|
package/dist/index.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
var b=class{socket=null;normalizeUser(e){throw new Error("Not implemented: normalizeUser")}normalizePlayer(e){throw new Error("Not implemented: normalizePlayer")}extractAppearance(e){return{color:e.color??0,head:e.head??0,face:e.face??0,neck:e.neck??0,body:e.body??0,hand:e.hand??0,feet:e.feet??0,flag:e.flag??0,photo:e.photo??0}}sendMessage(e){throw new Error("Not implemented: sendMessage")}sendEmote(e){throw new Error("Not implemented: sendEmote")}sendSafe(e){throw new Error("Not implemented: sendSafe")}walk(e,r){throw new Error("Not implemented: walk")}sendFrame(e,r){throw new Error("Not implemented: sendFrame")}snowball(e,r){throw new Error("Not implemented: snowball")}joinRoom(e,r,o){throw new Error("Not implemented: joinRoom")}addItem(e){throw new Error("Not implemented: addItem")}equipColor(e){throw new Error("Not implemented: equipColor")}equipHead(e){throw new Error("Not implemented: equipHead")}equipFace(e){throw new Error("Not implemented: equipFace")}equipNeck(e){throw new Error("Not implemented: equipNeck")}equipBody(e){throw new Error("Not implemented: equipBody")}equipHand(e){throw new Error("Not implemented: equipHand")}equipFeet(e){throw new Error("Not implemented: equipFeet")}equipFlag(e){throw new Error("Not implemented: equipFlag")}equipPhoto(e){throw new Error("Not implemented: equipPhoto")}buddyRequest(e){throw new Error("Not implemented: buddyRequest")}buddyAccept(e){throw new Error("Not implemented: buddyAccept")}buddyReject(e){throw new Error("Not implemented: buddyReject")}buddyRequestSeen(e){throw new Error("Not implemented: buddyRequestSeen")}getBuddy(e,r){throw new Error("Not implemented: getBuddy")}removeBuddy(e){throw new Error("Not implemented: removeBuddy")}addIgnore(e){throw new Error("Not implemented: addIgnore")}removeIgnore(e){throw new Error("Not implemented: removeIgnore")}getPlayer(e){throw new Error("Not implemented: getPlayer")}getAllSlots(){throw new Error("Not implemented: getAllSlots")}getMascots(){throw new Error("Not implemented: getMascots")}sendPostcard(e,r){throw new Error("Not implemented: sendPostcard")}getStamps(e){throw new Error("Not implemented: getStamps")}getPostcards(){throw new Error("Not implemented: getPostcards")}getIglooOpen(e){throw new Error("Not implemented: getIglooOpen")}getIgloos(){throw new Error("Not implemented: getIgloos")}getPuffles(e){throw new Error("Not implemented: getPuffles")}getIglooLikes(){throw new Error("Not implemented: getIglooLikes")}joinIgloo(e,r,o){throw new Error("Not implemented: joinIgloo")}gameOver(e){throw new Error("Not implemented: gameOver")}collectStamp(e){throw new Error("Not implemented: collectStamp")}getNinja(){throw new Error("Not implemented: getNinja")}getMats(){throw new Error("Not implemented: getMats")}joinMatchmaking(){throw new Error("Not implemented: joinMatchmaking")}leaveMatchmaking(){throw new Error("Not implemented: leaveMatchmaking")}startGame(){throw new Error("Not implemented: startGame")}selectCard(e){throw new Error("Not implemented: selectCard")}loadAnimation(e){throw new Error("Not implemented: loadAnimation")}joinMat(e){throw new Error("Not implemented: joinMat")}};import{EventEmitter as ve}from"events";import{io as K}from"socket.io-client";import D from"socket.io-msgpack-parser";var H="wss://play.cpjourney.net",G="skip",P=class extends b{id="CPJourney";async login(e){let r=this.createSocket("/world/login/");return await new Promise((s,t)=>{let n=setTimeout(()=>{r.disconnect(),t(new Error("Login timed out"))},1e4);r.on("connect",()=>{let i=e.secret??G,a="token"in e?{username:e.username,token:e.token,secret:i}:{username:e.username,password:e.password,secret:i};r.emit("message",{action:"login",args:a})}),r.on("message",i=>{if(i.action!=="login")return;clearTimeout(n),r.disconnect();let a=i.args;if(!a.success){t(new Error("Login failed"));return}let u=Object.entries(a.populations).map(([m,l])=>({name:m,population:l}));s({servers:u,key:a.key,username:a.username,moderator:a.moderator,buddyWorlds:a.buddyWorlds??[]})}),r.on("connect_error",i=>{clearTimeout(n),r.disconnect(),t(new Error(`Login connection failed: ${i.message}`))})})}async connect(e,r,o){await this.queueForServer(e,o);let s=this.createSocket(`/world/${e.toLowerCase()}/`);return this.socket=s,await new Promise((t,n)=>{let i=!1;s.on("connect",()=>{s.emit("message",{action:"game_auth",args:{username:r.username,key:r.key,createToken:!1,joinInvis:!1,takeoverMascot:!1,token:""}})}),s.on("message",a=>{switch(a.action){case"wait_queue_update":{o?.onQueueUpdate?.(a.args);break}case"game_auth":{if(i)break;if(i=!0,!a.args.success){s.disconnect(),n(new Error("Game auth failed"));return}s.emit("message",{action:"join_server",args:{}}),t();break}}}),s.on("connect_error",a=>{s.disconnect(),n(new Error(`Game connection failed: ${a.message}`))})}),s}async queueForServer(e,r){let o=this.createSocket("/world/login/");await new Promise((s,t)=>{let n=setTimeout(()=>{o.disconnect(),t(new Error("Queue timed out"))},6e4);o.on("connect",()=>{o.emit("message",{action:"queue_server_join",args:{server:e}})}),o.on("message",i=>{switch(i.action){case"wait_queue_update":r?.onQueueUpdate?.(i.args);break;case"queue_server_join":clearTimeout(n),o.disconnect(),s();break}}),o.once("disconnect",()=>{clearTimeout(n),s()}),o.on("connect_error",i=>{clearTimeout(n),o.disconnect(),t(new Error(`Queue connection failed: ${i.message}`))})})}send(e,r){if(!this.socket)throw new Error("Not connected");this.socket.emit("message",{action:e,args:r})}disconnect(){this.socket?.disconnect(),this.socket=null}normalizeUser(e){let{id:r,username:o,displayName:s,joinTime:t,x:n,y:i,frame:a,walking:u,color:m,head:l,face:h,neck:p,body:y,hand:E,feet:v,flag:w,photo:_,...O}=e;return{...this.extractAppearance(e),id:r,username:o,displayName:s,joinTime:t,x:n??0,y:i??0,frame:a??0,walking:u,meta:O,_raw:e}}normalizePlayer(e){let r=e.user,o=this.normalizeUser(r),{user:s,coins:t,rank:n,inventory:i,furniture:a,flooring:u,buddies:m,buddyRequests:l,ignores:h,igloos:p,...y}=e;return{...o,_raw:e,coins:t??0,rank:n??0,inventory:i??[],furniture:a??[],flooring:u??[],buddies:r.buddies??[],buddyRequests:r.buddyRequests??[],ignores:r.ignores??[],igloos:p??[],meta:{...o.meta,...y}}}sendMessage(e){this.send("send_message",{message:e})}sendEmote(e){this.send("send_emote",{emote:e})}sendSafe(e){this.send("send_safe",{safe:e})}walk(e,r){this.send("send_position",{x:e,y:r})}sendFrame(e,r){this.send("send_frame",{frame:e,set:r})}snowball(e,r){this.send("snowball",{x:e,y:r})}joinRoom(e,r,o){this.send("join_room",{room:e,x:r??0,y:o??0})}addItem(e){this.send("add_item",{item:e})}equipColor(e){this.send("update_color",{item:e})}equipHead(e){this.send("update_head",{item:e})}equipFace(e){this.send("update_face",{item:e})}equipNeck(e){this.send("update_neck",{item:e})}equipBody(e){this.send("update_body",{item:e})}equipHand(e){this.send("update_hand",{item:e})}equipFeet(e){this.send("update_feet",{item:e})}equipFlag(e){this.send("update_flag",{item:e})}equipPhoto(e){this.send("update_photo",{item:e})}buddyRequest(e){this.send("buddy_request",{id:e})}buddyAccept(e){this.send("buddy_accept",{id:e})}buddyReject(e){this.send("buddy_reject",{id:e})}buddyRequestSeen(e){this.send("buddy_request_seen",{id:e})}getBuddy(e,r){this.send("get_buddy",{id:e,type:r})}removeBuddy(e){this.send("remove_buddy",{id:e})}addIgnore(e){this.send("ignore_add",{id:e})}removeIgnore(e){this.send("ignore_remove",{id:e})}getPlayer(e){this.send("get_player",{id:e})}getAllSlots(){this.send("get_all_slots",{})}getMascots(){this.send("get_mascots",{})}sendPostcard(e,r){this.send("send_postcard",{userId:e,cardId:r})}getStamps(e){this.send("get_stamps",{userId:e})}getPostcards(){this.send("get_postcards",{})}getIglooOpen(e){this.send("get_igloo_open",{igloo:e})}getIgloos(){this.send("get_igloos",{})}getPuffles(e){this.send("get_puffles",{userId:e})}getIglooLikes(){this.send("get_igloo_likes",{})}joinIgloo(e,r,o){this.send("join_igloo",{igloo:e,x:r??0,y:o??0})}gameOver(e){this.send("game_over",{coins:e})}collectStamp(e){this.send("collect_stamp",{stamp:e})}getNinja(){this.send("get_ninja",{})}getMats(){this.send("get_waddles",{})}joinMatchmaking(){this.send("join_matchmaking",{})}leaveMatchmaking(){this.send("leave_matchmaking",{})}startGame(){this.send("start_game",{})}selectCard(e){this.send("select_card",{slot:e})}loadAnimation(e){this.send("load_animation",{animation:e})}joinMat(e){this.send("join_waddle",{waddle:e})}createSocket(e){return K(H,{path:e,parser:D,transports:["polling","websocket"],reconnection:!1})}};import{io as W}from"socket.io-client";import z from"socket.io-msgpack-parser";var Q="https://api.cplegacy.com/login",J="https://api.cplegacy.com/token_login";function X(c){let e=c.on.bind(c);return c.on=((r,o)=>r==="message"?e(r,(s,t)=>{o({action:s,args:t??{}})}):e(r,o)),c}var N=class extends b{id="CPLegacy";version="";async login(e){let r="token"in e?J:Q,o="token"in e?{username:e.username,token:e.token}:{username:e.username,password:e.password,version:this.version},s=await this.postLogin(r,o);if(!s.success&&s.wantedVersion&&(this.version=s.wantedVersion,o.version=this.version,s=await this.postLogin(r,o)),!s.success)throw new Error(`Login failed: ${s.message??"unknown error"}`);return{servers:Object.entries(s.populations??{}).map(([n,i])=>({name:n,population:i})),key:s.key,username:s.username,moderator:!1,buddyWorlds:[]}}async connect(e,r,o){let s=`wss://${e.toLowerCase()}.server.cplegacy.com`,t=W(s,{path:"/socket.io/",parser:z,transports:["websocket"],reconnection:!1});return this.socket=t,await new Promise((n,i)=>{let a=setTimeout(()=>{t.disconnect(),i(new Error("Game connection timed out"))},15e3);t.on("connect",()=>{t.emit("message","game_auth",{username:r.username,key:r.key,createToken:!1,token:""})}),t.on("message",(u,m)=>{switch(u){case"wait_queue_update":{o?.onQueueUpdate?.(m);break}case"game_auth":{if(!m.success){clearTimeout(a),t.disconnect(),i(new Error("Game auth failed"));return}t.emit("message","load_player",{}),t.emit("message","join_server",{}),clearTimeout(a),n();break}}}),t.on("connect_error",u=>{clearTimeout(a),t.disconnect(),i(new Error(`Game connection failed: ${u.message}`))})}),X(t)}send(e,r){if(!this.socket)throw new Error("Not connected");this.socket.emit("message",e,r)}disconnect(){this.socket?.disconnect(),this.socket=null}normalizeUser(e){return{...this.extractAppearance(e),id:e.id,username:e.username,displayName:e.realUsername??e.username,joinTime:e.joinTime,x:e.x??0,y:e.y??0,frame:e.frame??0,walking:e.walking??void 0,meta:{internalUsername:e.username,approved:e.approved,emailVerified:e.emailVerified,safeChat:e.safeChat,tutorial:e.tutorial,loginStreak:e.loginStreak,walkingColor:e.walkingColor,stampbookColor:e.stampbookColor,stampbookClasp:e.stampbookClasp,stampbookPattern:e.stampbookPattern,ninjaPoints:e.ninjaPoints,highestNinjaRank:e.highestNinjaRank,character:e.character,transformed:e.transformed},_raw:e}}normalizePlayer(e){let r=e.user;return{...this.normalizeUser(r),_raw:e,coins:r.coins??0,rank:r.rank??0,inventory:e.inventory??[],furniture:e.furniture,buddies:[],buddyRequests:e.pending?.map(o=>o.id)??[],ignores:[],igloos:e.igloos??[]}}sendMessage(e){this.send("send_message",{message:e})}sendEmote(e){this.send("send_emote",{emote:e})}sendSafe(e){this.send("send_safe",{safe:e})}walk(e,r){this.send("send_position",{x:e,y:r})}sendFrame(e,r){this.send("send_frame",{frame:e,set:r})}snowball(e,r){this.send("snowball",{x:e,y:r})}joinRoom(e,r,o){this.send("join_room",{room:e,x:r??0,y:o??0})}addItem(e){this.send("add_item",{item:e})}equipColor(e){this.send("update_color",{item:e})}equipHead(e){this.send("update_head",{item:e})}equipFace(e){this.send("update_face",{item:e})}equipNeck(e){this.send("update_neck",{item:e})}equipBody(e){this.send("update_body",{item:e})}equipHand(e){this.send("update_hand",{item:e})}equipFeet(e){this.send("update_feet",{item:e})}equipFlag(e){this.send("update_flag",{item:e})}equipPhoto(e){this.send("update_photo",{item:e})}buddyRequest(e){this.send("buddy_request",{id:e})}buddyAccept(e){this.send("buddy_accept",{id:e})}buddyReject(e){this.send("buddy_reject",{id:e})}removeBuddy(e){this.send("remove_buddy",{id:e})}addIgnore(e){this.send("ignore_add",{id:e})}removeIgnore(e){this.send("ignore_remove",{id:e})}getPlayer(e){this.send("get_player",{id:e})}getStamps(e){this.send("get_stamps",{userId:e})}getPostcards(){this.send("get_postcards",{})}joinIgloo(e,r,o){this.send("join_igloo",{igloo:e,x:r??0,y:o??0})}gameOver(e){this.send("game_over",{coins:e})}collectStamp(e){this.send("collect_stamp",{stamp:e})}async postLogin(e,r){return(await fetch(e,{method:"POST",headers:{"Content-Type":"application/json",Accept:"application/json"},body:JSON.stringify(r)})).json()}};import{createHash as V}from"crypto";import{EventEmitter as Y}from"events";import A from"ws";var Z="wss://server.cpzero.net/login",ee="wss://server.cpzero.net/sub_zero",$="253",F="w1",f="\0",g={ID:0,USERNAME:1,COLOR:3,HEAD:4,FACE:5,NECK:6,BODY:7,HAND:8,BACK:9,BODY2:10,HAND2:11,BEAK:12,HAIR:13,FEET:14,MOUNT:15,FLAG:16,PHOTO:17,X:18,Y:19,FRAME:20,RANK:22};function re(c){return V("md5").update(c).digest("hex")}function oe(c){let e=re(c);return e.substring(16,32)+e.substring(0,16)}function d(c){let e=Number(c);return Number.isNaN(e)?0:e}function q(c){let e=c.split("|");return{id:d(e[g.ID]),username:e[g.USERNAME]??"",color:d(e[g.COLOR]),head:d(e[g.HEAD]),face:d(e[g.FACE]),neck:d(e[g.NECK]),body:d(e[g.BODY]),hand:d(e[g.HAND]),back:d(e[g.BACK]),body2:d(e[g.BODY2]),hand2:d(e[g.HAND2]),beak:d(e[g.BEAK]),hair:d(e[g.HAIR]),feet:d(e[g.FEET]),mount:d(e[g.MOUNT]),flag:d(e[g.FLAG]),photo:d(e[g.PHOTO]),x:d(e[g.X]),y:d(e[g.Y]),frame:d(e[g.FRAME]),rank:d(e[g.RANK])}}var T=class extends Y{ws;_closed=!1;_buffering=!0;_buffer=[];constructor(e){super(),this.ws=e,e.on("close",()=>{this._closed=!0,this.emit("disconnect")}),e.on("error",r=>{this.emit("connect_error",r)})}dispatchMessage(e,r){this._buffering&&this._buffer.push({action:e,args:r}),this.emit("message",{action:e,args:r})}flush(){this._buffering=!1;let e=this._buffer;this._buffer=[],setTimeout(()=>{for(let r of e)this.emit("message",r)},0)}send(e){this._closed||this.ws.send(e+f)}disconnect(){this._closed||(this._closed=!0,this.ws.close())}get connected(){return!this._closed&&this.ws.readyState===A.OPEN}};function ne(c,e){switch(c){case"lp":{let r=q(e[0]??""),o=d(e[1]),s=r.rank;return{action:"load_player",args:{user:r,coins:o,rank:s}}}case"jr":{let r=d(e[0]),o=e.slice(1).filter(Boolean).map(q);return{action:"join_room",args:{room:r,users:o}}}case"ap":return{action:"add_player",args:{user:q(e[0]??"")}};case"rp":return{action:"remove_player",args:{user:d(e[0])}};case"sp":return{action:"send_position",args:{id:d(e[0]),x:d(e[1]),y:d(e[2])}};case"sf":return{action:"send_frame",args:{id:d(e[0]),frame:d(e[1])}};case"sm":return{action:"send_message",args:{id:d(e[0]),message:e[1]??""}};case"se":return{action:"send_emote",args:{id:d(e[0]),emote:d(e[1])}};case"sa":return{action:"send_safe",args:{id:d(e[0]),safe:d(e[1])}};case"sb":return{action:"snowball",args:{id:d(e[0]),x:d(e[1]),y:d(e[2])}};case"gp":return{action:"get_player",args:{user:q(e[0]??"")}};case"upc":return{action:"update_player",args:{id:d(e[0]),item:d(e[1]),slot:"color"}};case"uph":return{action:"update_player",args:{id:d(e[0]),item:d(e[1]),slot:"head"}};case"upf":return{action:"update_player",args:{id:d(e[0]),item:d(e[1]),slot:"face"}};case"upn":return{action:"update_player",args:{id:d(e[0]),item:d(e[1]),slot:"neck"}};case"upb":return{action:"update_player",args:{id:d(e[0]),item:d(e[1]),slot:"body"}};case"upa":return{action:"update_player",args:{id:d(e[0]),item:d(e[1]),slot:"hand"}};case"upe":return{action:"update_player",args:{id:d(e[0]),item:d(e[1]),slot:"feet"}};case"upl":return{action:"update_player",args:{id:d(e[0]),item:d(e[1]),slot:"flag"}};case"upp":return{action:"update_player",args:{id:d(e[0]),item:d(e[1]),slot:"photo"}};case"upba":return{action:"update_player",args:{id:d(e[0]),item:d(e[1]),slot:"back"}};case"upm":return{action:"update_player",args:{id:d(e[0]),item:d(e[1]),slot:"mount"}};case"ai":return{action:"add_item",args:{item:d(e[0]),coins:d(e[1])}};case"jg":return{action:"join_game_room",args:{game:d(e[0])}};case"e":return{action:"error",args:{error:e[0]??"unknown"}};default:return null}}var x=class extends b{id="CPZero";sfs=null;async login(e){if("token"in e)throw new Error("CPZero does not support token login");let r=e.secret;if(!r)throw new Error("CPZero requires a pre-computed login hash in options.secret");let o=new A(Z);return await new Promise((t,n)=>{let i=setTimeout(()=>{o.close(),n(new Error("Login timed out"))},15e3),a="";o.on("open",()=>{o.send(k("verChk","0",`<ver v='${$}' />`)+f)}),o.on("message",u=>{let m=u.toString("utf-8").split(f).filter(Boolean);for(let l of m){if(l.includes('action="apiOK"')||l.includes("action='apiOK'")){o.send(k("rndK","-1","")+f);continue}let h=l.match(/<k>(.*?)<\/k>/);if(h){a=h[1];let p=se(e.username,r);o.send(p+f);continue}if(l.startsWith("%xt%l%")){let p=l.split("%").filter(Boolean),y=p[3]??"",E=p[4]??"",v=y.split("|");clearTimeout(i),o.close();let w=d(v[0]),_=v[2]??e.username;t({servers:[{name:"Sub Zero",population:0}],key:`${w}|${y}|${E}`,username:_,moderator:!1,buddyWorlds:[]});return}if(l.startsWith("%xt%e%")){clearTimeout(i),o.close();let p=l.split("%").filter(Boolean);n(new Error(`Login failed: error ${p[3]??"unknown"}`));return}}}),o.on("error",u=>{clearTimeout(i),o.close(),n(new Error(`Login WS error: ${u.message}`))}),o.on("close",()=>{clearTimeout(i)})})}async connect(e,r,o){let s=r.key.split("|"),t=s[0]??"",n=s.slice(1,-1).join("|"),i=s[s.length-1]??"",a=n.split("|")[3]??"",u=new A(ee),m=new T(u);return this.sfs=m,this.socket=m,await new Promise((l,h)=>{let p=setTimeout(()=>{u.close(),h(new Error("Game connection timed out"))},15e3);u.on("open",()=>{m.send(k("verChk","0",`<ver v='${$}' />`))}),u.on("message",y=>{let E=y.toString("utf-8").split(f).filter(Boolean);for(let v of E){if(v.includes('action="apiOK"')||v.includes("action='apiOK'")){m.send(k("rndK","-1",""));continue}let w=v.match(/<k>(.*?)<\/k>/);if(w){let _=w[1],O=`${oe(a+_)}${a}#${i}`;m.send(te(n,O));continue}if(v.startsWith("%xt%")&&(this.processXtBatch(v,m),v.includes("%xt%l%")&&m.send(`%xt%s%j#js%-1%${t}%${a}%en%`),v.includes("%xt%jr%")&&(clearTimeout(p),l())),v.includes("%xt%e%")){clearTimeout(p),u.close();let _=v.split("%").filter(Boolean);h(new Error(`Game auth failed: error ${_[3]??"unknown"}`));return}}}),u.on("error",y=>{clearTimeout(p),h(new Error(`Game WS error: ${y.message}`))})}),u.on("message",l=>{let h=l.toString("utf-8").split(f).filter(Boolean);for(let p of h)p.startsWith("%xt%")&&this.processXtBatch(p,m)}),m.flush(),m}send(e,r){if(!this.sfs)throw new Error("Not connected");let o=ie(e,r);o&&this.sfs.send(o)}disconnect(){this.sfs?.disconnect(),this.sfs=null,this.socket=null}normalizeUser(e){return{...this.extractAppearance(e),id:e.id,username:e.username,x:e.x??0,y:e.y??0,frame:e.frame??0,meta:{back:e.back,body2:e.body2,hand2:e.hand2,beak:e.beak,hair:e.hair,mount:e.mount,rank:e.rank},_raw:e}}normalizePlayer(e){let r=e.user;return{...this.normalizeUser(r),_raw:e,coins:e.coins??0,rank:r.rank??0,inventory:[],buddies:[],ignores:[]}}sendMessage(e){if(!this.sfs)throw new Error("Not connected");this.sfs.send(`%xt%s%m#sm%-1%0%${e}%`)}sendEmote(e){if(!this.sfs)throw new Error("Not connected");this.sfs.send(`%xt%s%u#se%-1%${e}%`)}sendSafe(e){if(!this.sfs)throw new Error("Not connected");this.sfs.send(`%xt%s%u#sa%-1%${e}%`)}walk(e,r){if(!this.sfs)throw new Error("Not connected");this.sfs.send(`%xt%s%u#sp%-1%${e}%${r}%`)}sendFrame(e){if(!this.sfs)throw new Error("Not connected");this.sfs.send(`%xt%s%u#sf%-1%${e}%`)}snowball(e,r){if(!this.sfs)throw new Error("Not connected");this.sfs.send(`%xt%s%u#sb%-1%${e}%${r}%`)}joinRoom(e,r,o){if(!this.sfs)throw new Error("Not connected");this.sfs.send(`%xt%s%j#jr%-1%${e}%${r??0}%${o??0}%`)}addItem(e){if(!this.sfs)throw new Error("Not connected");this.sfs.send(`%xt%s%i#ai%-1%${e}%`)}equipColor(e){if(!this.sfs)throw new Error("Not connected");this.sfs.send(`%xt%s%s#upc%-1%${e}%`)}equipHead(e){if(!this.sfs)throw new Error("Not connected");this.sfs.send(`%xt%s%s#uph%-1%${e}%`)}equipFace(e){if(!this.sfs)throw new Error("Not connected");this.sfs.send(`%xt%s%s#upf%-1%${e}%`)}equipNeck(e){if(!this.sfs)throw new Error("Not connected");this.sfs.send(`%xt%s%s#upn%-1%${e}%`)}equipBody(e){if(!this.sfs)throw new Error("Not connected");this.sfs.send(`%xt%s%s#upb%-1%${e}%`)}equipHand(e){if(!this.sfs)throw new Error("Not connected");this.sfs.send(`%xt%s%s#upa%-1%${e}%`)}equipFeet(e){if(!this.sfs)throw new Error("Not connected");this.sfs.send(`%xt%s%s#upe%-1%${e}%`)}equipFlag(e){if(!this.sfs)throw new Error("Not connected");this.sfs.send(`%xt%s%s#upl%-1%${e}%`)}equipPhoto(e){if(!this.sfs)throw new Error("Not connected");this.sfs.send(`%xt%s%s#upp%-1%${e}%`)}getPlayer(e){if(!this.sfs)throw new Error("Not connected");this.sfs.send(`%xt%s%u#gp%-1%${e}%`)}joinIgloo(e,r,o){if(!this.sfs)throw new Error("Not connected");this.sfs.send(`%xt%s%j#jp%-1%${e}%igloo%`)}processXtBatch(e,r){let o=e.split(/(?=%xt%)/).map(s=>s.trim()).filter(Boolean);for(let s of o){let t=s.split("%").filter(Boolean);if(t[0]!=="xt"||t.length<3)continue;let n=t[1],i=t.slice(3),a=ne(n,i);a&&r.dispatchMessage(a.action,a.args)}}};function k(c,e,r){return`<msg t='sys'><body action='${c}' r='${e}'>${r}</body></msg>`}function se(c,e){return k("login","0",`<login z='${F}'><nick><![CDATA[${c}]]></nick><pword><![CDATA[${e}]]></pword></login>`)}function te(c,e){return k("login","0",`<login z='${F}'><nick><![CDATA[${c}]]></nick><pword><![CDATA[${e}]]></pword></login>`)}function ie(c,e){switch(c){case"send_position":return`%xt%s%u#sp%-1%${e.x}%${e.y}%`;case"send_frame":return`%xt%s%u#sf%-1%${e.frame}%`;case"send_message":return`%xt%s%m#sm%-1%0%${e.message}%`;case"send_emote":return`%xt%s%u#se%-1%${e.emote}%`;case"send_safe":return`%xt%s%u#sa%-1%${e.safe}%`;case"snowball":return`%xt%s%u#sb%-1%${e.x}%${e.y}%`;case"join_room":return`%xt%s%j#jr%-1%${e.room}%${e.x??0}%${e.y??0}%`;case"add_item":return`%xt%s%i#ai%-1%${e.item}%`;case"get_player":return`%xt%s%u#gp%-1%${e.id}%`;default:return null}}import{createCipheriv as ae,createDecipheriv as de,randomBytes as ue}from"crypto";import{io as ce}from"socket.io-client";import j from"tweetnacl";var me="https://media8.newcp.net/assets/media/crumbs/en/crumbs.json",S=class{aesKey=null;keypair=j.box.keyPair();get publicKey(){return Buffer.from(this.keypair.publicKey).toString("base64")}get encrypted(){return this.aesKey!==null}acquireKey(e,r){let o=Buffer.from(e,"base64"),s=Buffer.from(r,"base64"),t=o.subarray(0,j.box.nonceLength),n=o.subarray(j.box.nonceLength),i=j.box.open(new Uint8Array(n),new Uint8Array(t),new Uint8Array(s),this.keypair.secretKey);return i?new TextDecoder().decode(i):null}setKey(e){this.aesKey=Buffer.from(e,"utf-8")}encrypt(e){if(!this.aesKey)throw new Error("Encryption key not set");let r=ue(16),o=ae("aes-256-cbc",this.aesKey,r),s=Buffer.concat([o.update(e,"utf-8"),o.final()]);return Buffer.concat([r,s]).toString("base64")}decrypt(e){if(!this.aesKey)throw new Error("Encryption key not set");let r=Buffer.from(e,"base64"),o=r.subarray(0,16),s=r.subarray(16),t=de("aes-256-cbc",this.aesKey,o);return Buffer.concat([t.update(s),t.final()]).toString("utf-8")}encode(e){return this.encrypted?this.encrypt(JSON.stringify(e)):JSON.stringify(e)}decode(e){return this.encrypted&&typeof e=="string"?JSON.parse(this.decrypt(e)):typeof e=="string"?JSON.parse(e):e}};function U(c,e){return new Promise((r,o)=>{let s=setTimeout(()=>{o(new Error("Handshake timed out"))},1e4);c.once("handshake",(t,n)=>{clearTimeout(s);let i=e.acquireKey(t,n);if(!i){o(new Error("Failed to decrypt handshake key"));return}let a=JSON.parse(i);if(a.time&&typeof a.time=="number"&&Math.abs(Date.now()-a.time)>3e5){o(new Error("Server time desync"));return}e.setKey(a.key),r()}),c.emit("handshake",e.publicKey)})}function le(c,e){let r=c.on.bind(c);return c.on=((o,s)=>o==="message"?r(o,t=>{try{let n=e.decode(t);s({action:n.action,args:n.args??{}})}catch{}}):r(o,s)),c}var L=class extends b{id="NewCP";encryptor=new S;worlds=null;async login(e){this.worlds||await this.loadWorlds();let r=Object.values(this.worlds??{}).find(t=>t.login);if(!r)throw new Error("Login world not found in crumbs");let o=this.createSocket(r.host,r.path);return this.encryptor=new S,await new Promise((t,n)=>{let i=setTimeout(()=>{o.disconnect(),n(new Error("Login timed out"))},15e3);o.on("connect",async()=>{try{await U(o,this.encryptor);let a="token"in e?{username:e.username,token:e.token}:{username:e.username,password:e.password},u=this.encryptor.encode({action:"login",args:a});o.emit("message",u)}catch(a){clearTimeout(i),o.disconnect(),n(a)}}),o.on("message",a=>{try{let u=this.encryptor.decode(a);if(u.action!=="login")return;clearTimeout(i),o.disconnect();let m=u.args;if(!m.success){n(new Error("Login failed"));return}let l=Object.entries(m.populations??{}).map(([h,p])=>({name:h,population:p}));t({servers:l,key:m.key,username:m.username,moderator:m.moderator??!1,buddyWorlds:m.buddyWorlds??[]})}catch(u){clearTimeout(i),o.disconnect(),n(u)}}),o.on("connect_error",a=>{clearTimeout(i),o.disconnect(),n(new Error(`Login connection failed: ${a.message}`))})})}async connect(e,r,o){this.worlds||await this.loadWorlds();let s=this.worlds?.[e];if(!s)throw new Error(`World config not found for: ${e}`);this.encryptor=new S;let t=this.createSocket(s.host,s.path);return this.socket=t,await new Promise((n,i)=>{let a=setTimeout(()=>{t.disconnect(),i(new Error("Game connection timed out"))},15e3);t.on("connect",async()=>{try{await U(t,this.encryptor);let u=this.encryptor.encode({action:"game_auth",args:{username:r.username,key:r.key,createToken:!1}});t.emit("message",u)}catch(u){clearTimeout(a),t.disconnect(),i(u)}}),t.on("message",u=>{try{let m=this.encryptor.decode(u);switch(m.action){case"wait_queue_update":{o?.onQueueUpdate?.(m.args);break}case"game_auth":{if(!m.args.success){clearTimeout(a),t.disconnect(),i(new Error("Game auth failed"));return}let h=this.encryptor.encode({action:"join_server",args:{}});t.emit("message",h),clearTimeout(a),n();break}}}catch{}}),t.on("connect_error",u=>{clearTimeout(a),t.disconnect(),i(new Error(`Game connection failed: ${u.message}`))})}),le(t,this.encryptor)}send(e,r){if(!this.socket)throw new Error("Not connected");let o=this.encryptor.encode({action:e,args:r});this.socket.emit("message",o)}disconnect(){this.socket?.disconnect(),this.socket=null}normalizeUser(e){return{...this.extractAppearance(e),id:e.id,username:e.username,displayName:e.nickname,x:e.x??0,y:e.y??0,frame:e.frame??0,meta:{nickname:e.nickname,registrationDate:e.registrationDate,customNameColor:e.customNameColor,customBubbleColor:e.customBubbleColor,customBubbleTextColor:e.customBubbleTextColor,wallHacks:e.wallHacks,moderator:e.moderator,character:e.character,approved:e.approved,walking:e.walking},_raw:e}}normalizePlayer(e){let r=e.user;return{...this.normalizeUser(r),_raw:e,coins:e.coins??0,rank:e.rank??0,inventory:e.inventory??[],buddies:e.buddies??[],ignores:e.ignores??[],furniture:e.furniture,flooring:e.floorings??[],igloos:e.igloos??[]}}sendMessage(e){this.send("send_message",{message:e})}sendEmote(e){this.send("send_emote",{emote:e})}sendSafe(e){this.send("send_safe",{safe:e})}walk(e,r){this.send("send_position",{x:e,y:r})}sendFrame(e,r){this.send("send_frame",{frame:e,set:r})}snowball(e,r){this.send("snowball",{x:e,y:r})}joinRoom(e,r,o){this.send("join_room",{room:e,x:r??0,y:o??0})}addItem(e){this.send("add_item",{item:e})}equipColor(e){this.send("update_color",{item:e})}equipHead(e){this.send("update_head",{item:e})}equipFace(e){this.send("update_face",{item:e})}equipNeck(e){this.send("update_neck",{item:e})}equipBody(e){this.send("update_body",{item:e})}equipHand(e){this.send("update_hand",{item:e})}equipFeet(e){this.send("update_feet",{item:e})}equipFlag(e){this.send("update_flag",{item:e})}equipPhoto(e){this.send("update_photo",{item:e})}buddyRequest(e){this.send("buddy_request",{id:e})}buddyAccept(e){this.send("buddy_accept",{id:e})}buddyReject(e){this.send("buddy_reject",{id:e})}removeBuddy(e){this.send("remove_buddy",{id:e})}addIgnore(e){this.send("ignore_add",{id:e})}removeIgnore(e){this.send("ignore_remove",{id:e})}getPlayer(e){this.send("get_player",{id:e})}joinIgloo(e,r,o){this.send("join_igloo",{igloo:e,x:r??0,y:o??0})}createSocket(e,r){return ce(e,{path:r,transports:["polling","websocket"],reconnection:!1})}async loadWorlds(){let e=await fetch(me);if(!e.ok)throw new Error(`Failed to fetch crumbs: ${e.status}`);let r=await e.json();this.worlds=r.worlds}};import{io as pe}from"socket.io-client";var ge="https://play.penguinorigins.online",M=class extends b{id="PenguinOrigins";async login(e){let r=this.createSocket("/world/login/");return await new Promise((s,t)=>{let n=setTimeout(()=>{r.disconnect(),t(new Error("Login timed out"))},1e4);r.on("connect",()=>{let i="token"in e?"token_login":"login",a="token"in e?{username:e.username,token:e.token}:{username:e.username,password:e.password};r.emit("message",{action:i,args:a})}),r.on("message",i=>{if(i.action!=="login")return;clearTimeout(n),r.disconnect();let a=i.args;if(!a.success){t(new Error("Login failed"));return}let u=Object.entries(a.populations).map(([m,l])=>({name:m,population:l}));s({servers:u,key:a.key,username:a.username,moderator:!1,buddyWorlds:[]})}),r.on("connect_error",i=>{clearTimeout(n),r.disconnect(),t(new Error(`Login connection failed: ${i.message}`))})})}async connect(e,r,o){let s=this.createSocket(`/world/${e.toLowerCase()}/`);return this.socket=s,await new Promise((t,n)=>{let i=!1;s.on("connect",()=>{s.emit("message",{action:"game_auth",args:{username:r.username,key:r.key,createToken:!0,token:""}})}),s.on("message",a=>{switch(a.action){case"wait_queue_update":{o?.onQueueUpdate?.(a.args);break}case"game_auth":{if(i)break;if(i=!0,!a.args.success){s.disconnect(),n(new Error("Game auth failed"));return}s.emit("message",{action:"join_server",args:{}}),t();break}}}),s.on("connect_error",a=>{s.disconnect(),n(new Error(`Game connection failed: ${a.message}`))})}),s}send(e,r){if(!this.socket)throw new Error("Not connected");this.socket.emit("message",{action:e,args:r})}disconnect(){this.socket?.disconnect(),this.socket=null}normalizeUser(e){return{...this.extractAppearance(e),id:e.id,username:e.username,displayName:e.nickname??e.username,joinTime:e.joinTime,x:e.x??0,y:e.y??0,frame:e.frame??0,meta:{toy:e.toy},_raw:e}}normalizePlayer(e){let r=e.user,o=this.normalizeUser(r);return{...o,_raw:e,coins:e.coins??0,rank:e.rank??0,inventory:e.inventory??[],furniture:e.furniture??[],flooring:e.flooring??[],buddies:e.buddies??[],buddyRequests:e.buddyRequests??[],ignores:e.ignores??[],igloos:e.igloos??[],meta:{...o.meta,postcards:e.postcards,mascots:e.mascots,pets:e.pets}}}sendMessage(e){this.send("send_message",{message:e})}sendEmote(e){this.send("send_emote",{emote:e})}sendSafe(e){this.send("send_safe",{safe:e})}walk(e,r){this.send("send_position",{x:e,y:r})}sendFrame(e,r){this.send("send_frame",{frame:e,set:r??!1})}snowball(e,r){this.send("snowball",{x:e,y:r})}joinRoom(e,r,o){this.send("join_room",{room:e,x:r??0,y:o??0})}addItem(e){this.send("add_item",{item:e})}equipColor(e){this.send("update_player",{item:e})}equipHead(e){this.send("update_player",{item:e})}equipFace(e){this.send("update_player",{item:e})}equipNeck(e){this.send("update_player",{item:e})}equipBody(e){this.send("update_player",{item:e})}equipHand(e){this.send("update_player",{item:e})}equipFeet(e){this.send("update_player",{item:e})}equipFlag(e){this.send("update_player",{item:e})}equipPhoto(e){this.send("update_player",{item:e})}buddyRequest(e){this.send("buddy_request",{id:e})}buddyAccept(e){this.send("buddy_accept",{id:e})}addIgnore(e){this.send("ignore_add",{id:e})}removeIgnore(e){this.send("ignore_remove",{id:e})}getIglooOpen(e){this.send("get_igloo_open",{igloo:e})}joinIgloo(e,r,o){this.send("join_igloo",{igloo:e,x:r??0,y:o??0})}gameOver(e){this.send("game_over",{coins:e})}createSocket(e){return pe(ge,{path:e,transports:["polling","websocket"],reconnection:!1})}};var he={CPJourney:P,CPLegacy:N,CPZero:x,NewCP:L,PenguinOrigins:M};function B(c){return new he[c]}var R=class{constructor(e,r){this.adapter=e;this.waitFor=r}adapter;waitFor;getNinja(){return this.adapter.getNinja(),this.waitFor("get_ninja")}getMats(){return this.adapter.getMats(),this.waitFor("get_waddles")}joinMat(e){this.adapter.joinMat(e)}joinMatchmaking(){return this.adapter.joinMatchmaking(),this.waitFor("join_matchmaking")}leaveMatchmaking(){this.adapter.leaveMatchmaking()}startGame(){return this.adapter.startGame(),this.waitFor("start_game")}selectCard(e){return this.adapter.selectCard(e),this.waitFor("move_my_card")}loadAnimation(e){this.adapter.loadAnimation(e)}};var be=new Set(["load_player","join_room","add_player","remove_player","send_position","send_frame","update_player","kick","close_with_error","send_message","send_emote","cpj_ping","open_sprite","close_sprite","set_weather","server_error","error","stamp_earned","game_over","join_game_room","get_ninja","get_waddles","update_waddle","join_matchmaking","tick_matchmaking","start_game","set_cards","add_enemy_cards","start_round","enable_cards","remove_card","move_my_card","card_effect","round_over","play_animation","game_won","get_player","buddy_request","buddy_accept","buddy_reject","buddy_request_seen","get_buddy","send_postcard","stamps_result","ignore_add","ignore_remove","add_item","get_postcards","get_igloo_open","get_igloos","get_igloo_likes","join_igloo","get_puffles","get_mascots","wait_queue_update","slot","snowball","send_safe","stop_walking","update_table","transform_player","queue_server_join","disconnect","unknown_packet"]);function I(c){return typeof c=="object"&&c!==null&&"action"in c&&"args"in c}var C=class extends ve{player=null;room=null;users=new Map;connected=!1;adapter;loginResult=null;log=null;_cardJitsu=null;get cardJitsu(){return this._cardJitsu||(this._cardJitsu=new R(this.adapter,this.waitFor.bind(this))),this._cardJitsu}constructor(e,r){super(),this.adapter=B(e),r?.debug&&(this.log=typeof r.debug=="function"?r.debug:console.log.bind(console))}async login(e){return this.log?.("[login] logging in as",e.username),this.loginResult=await this.adapter.login(e),this.log?.("[login] success \u2014",this.loginResult.servers.length,"servers"),this.loginResult.servers}async connect(e,r){if(!this.loginResult)throw new Error("Must call login() first");this.log?.("[connect] joining",e);let o={...r,onQueueUpdate:t=>{this.log?.("[queue]",`#${t.position}/${t.queueLength}`),this.emit("wait_queue_update",t),r?.onQueueUpdate?.(t)}},s=await this.adapter.connect(e,this.loginResult,o);s.on("message",t=>{I(t)&&this.handleMessage(t)}),s.on("disconnect",()=>{this.log?.("[disconnect] connection lost"),this.cleanup(),this.emit("disconnect")}),await new Promise((t,n)=>{let i=setTimeout(()=>{n(new Error("Waiting for load_player timed out"))},1e4),a=!1,u=!1,m=()=>{a&&u&&(clearTimeout(i),this.connected=!0,t())},l=p=>{if(I(p))switch(p.action){case"load_player":a=!0,m();break;case"join_room":u=!0,m();break;case"kick":clearTimeout(i),s.off("message",l),n(new Error(`Kicked: ${p.args.reason??"unknown"}`));break;case"close_with_error":clearTimeout(i),s.off("message",l),n(new Error(`Kicked: ${p.args.error??"unknown"}`));break;case"error":clearTimeout(i),s.off("message",l),n(new Error(`Server error: ${p.args.error??"unknown"}`));break}},h=()=>{(!a||!u)&&(clearTimeout(i),n(new Error("Disconnected before fully loaded")))};s.on("message",l),s.once("disconnect",h)})}on(e,r){return super.on(e,r)}off(e,r){return super.off(e,r)}once(e,r){return super.once(e,r)}emit(e,...r){return super.emit(e,...r)}waitFor(e,r){return new Promise((o,s)=>{let t,n=()=>{t&&clearTimeout(t),this.off(e,i),this.off("disconnect",a)},i=(u=>{n(),o(u)}),a=()=>{n(),s(new Error(`Disconnected while waiting for ${String(e)}`))};r!==void 0&&(t=setTimeout(()=>{n(),s(new Error(`Timed out waiting for ${String(e)}`))},r)),this.once(e,i),this.once("disconnect",a)})}sendMessage(e){this.adapter.sendMessage(e)}sendEmote(e){this.adapter.sendEmote(e)}sendSafe(e){this.adapter.sendSafe(e)}walk(e,r){this.adapter.walk(e,r)}sendFrame(e,r){this.adapter.sendFrame(e,r)}snowball(e,r){this.adapter.snowball(e,r)}joinRoom(e,r,o){return this.adapter.joinRoom(e,r,o),this.waitFor("join_room")}addItem(e){return this.adapter.addItem(e),this.waitFor("add_item")}equipColor(e){this.adapter.equipColor(e)}equipHead(e){this.adapter.equipHead(e)}equipFace(e){this.adapter.equipFace(e)}equipNeck(e){this.adapter.equipNeck(e)}equipBody(e){this.adapter.equipBody(e)}equipHand(e){this.adapter.equipHand(e)}equipFeet(e){this.adapter.equipFeet(e)}equipFlag(e){this.adapter.equipFlag(e)}equipPhoto(e){this.adapter.equipPhoto(e)}buddyRequest(e){this.adapter.buddyRequest(e)}buddyAccept(e){return this.adapter.buddyAccept(e),this.waitFor("buddy_accept")}buddyReject(e){return this.adapter.buddyReject(e),this.waitFor("buddy_reject")}buddyRequestSeen(e){return this.adapter.buddyRequestSeen(e),this.waitFor("buddy_request_seen")}getBuddy(e,r){return this.adapter.getBuddy(e,r),this.waitFor("get_buddy")}removeBuddy(e){this.adapter.removeBuddy(e)}addIgnore(e){return this.adapter.addIgnore(e),this.waitFor("ignore_add")}removeIgnore(e){return this.adapter.removeIgnore(e),this.waitFor("ignore_remove")}getPlayer(e){return this.adapter.getPlayer(e),this.waitFor("get_player")}getAllSlots(){return this.adapter.getAllSlots(),this.waitFor("slot")}getMascots(){return this.adapter.getMascots(),this.waitFor("get_mascots")}sendPostcard(e,r){return this.adapter.sendPostcard(e,r),this.waitFor("send_postcard")}getStamps(e){return this.adapter.getStamps(e),this.waitFor("stamps_result")}getPostcards(){return this.adapter.getPostcards(),this.waitFor("get_postcards")}getIglooOpen(e){return this.adapter.getIglooOpen(e),this.waitFor("get_igloo_open")}getIgloos(){return this.adapter.getIgloos(),this.waitFor("get_igloos")}getPuffles(e){return this.adapter.getPuffles(e),this.waitFor("get_puffles")}getIglooLikes(){return this.adapter.getIglooLikes(),this.waitFor("get_igloo_likes")}joinIgloo(e,r,o){return this.adapter.joinIgloo(e,r,o),this.waitFor("join_igloo")}gameOver(e){return this.adapter.gameOver(e),this.waitFor("game_over")}collectStamp(e){return this.adapter.collectStamp(e),this.waitFor("stamp_earned")}sleep(e){return new Promise(r=>setTimeout(r,e))}disconnect(){this.log?.("[disconnect] closing connection"),this.adapter.disconnect(),this.cleanup()}cleanup(){this.connected=!1,this.player=null,this.room=null,this.users.clear()}handleMessage(e){let{action:r,args:o}=e,s=o;switch(r){case"load_player":{let n=this.adapter.normalizePlayer(o);this.player=n,s={user:n},this.log?.("[load_player]",n.username,`id=${n.id}`,`coins=${n.coins}`,`inventory=${n.inventory.length}`);break}case"join_room":{let n=o.room,i=o.users;this.room=n,this.users.clear();let a=[];for(let u of i){let m=this.adapter.normalizeUser(u);this.users.set(m.id,m),a.push(m)}s={room:n,users:a},this.log?.("[join_room]",`room=${n}`,`users=${a.length}`);break}case"add_player":{let n=this.adapter.normalizeUser(o.user);this.users.set(n.id,n),s={user:n},this.log?.("[add_player]",n.username,`id=${n.id}`);break}case"remove_player":{let n=o.user;this.users.delete(n),this.log?.("[remove_player]",`id=${n}`);break}case"send_position":{let n=o.id,i=this.users.get(n);i&&(i.x=o.x,i.y=o.y);break}case"send_frame":{let n=o.id,i=this.users.get(n);i&&(i.frame=o.frame);break}case"join_igloo":{let n=o.igloo,i=o.users;this.room=n,this.users.clear();let a=[];for(let u of i){let m=this.adapter.normalizeUser(u);this.users.set(m.id,m),a.push(m)}s={...o,users:a},this.log?.("[join_igloo]",`igloo=${n}`,`users=${a.length}`);break}case"update_player":{let n=o.id,i=o.slot,a=o.item,u=this.users.get(n);u&&i in u&&(u[i]=a);break}case"kick":{let n=o.reason??"unknown";this.log?.("[kick]",n),this.cleanup();break}case"close_with_error":{let n=o.error??"unknown";this.log?.("[kick]",n),this.cleanup();break}default:{be.has(r)||(this.log?.("[unknown_packet]",r,JSON.stringify(o)),this.emit("unknown_packet",{action:r,args:o}));break}}let t=r==="error"?"server_error":r;this.emit(t,s)}};export{b as BaseAdapter,R as CardJitsu,C as Client};
|
|
1
|
+
var b=class{socket=null;normalizeUser(e){throw new Error("Not implemented: normalizeUser")}normalizePlayer(e){throw new Error("Not implemented: normalizePlayer")}extractAppearance(e){return{color:e.color??0,head:e.head??0,face:e.face??0,neck:e.neck??0,body:e.body??0,hand:e.hand??0,feet:e.feet??0,flag:e.flag??0,photo:e.photo??0}}sendMessage(e){throw new Error("Not implemented: sendMessage")}sendEmote(e){throw new Error("Not implemented: sendEmote")}sendSafe(e){throw new Error("Not implemented: sendSafe")}walk(e,r){throw new Error("Not implemented: walk")}sendFrame(e,r){throw new Error("Not implemented: sendFrame")}snowball(e,r){throw new Error("Not implemented: snowball")}joinRoom(e,r,o){throw new Error("Not implemented: joinRoom")}addItem(e){throw new Error("Not implemented: addItem")}equipColor(e){throw new Error("Not implemented: equipColor")}equipHead(e){throw new Error("Not implemented: equipHead")}equipFace(e){throw new Error("Not implemented: equipFace")}equipNeck(e){throw new Error("Not implemented: equipNeck")}equipBody(e){throw new Error("Not implemented: equipBody")}equipHand(e){throw new Error("Not implemented: equipHand")}equipFeet(e){throw new Error("Not implemented: equipFeet")}equipFlag(e){throw new Error("Not implemented: equipFlag")}equipPhoto(e){throw new Error("Not implemented: equipPhoto")}buddyRequest(e){throw new Error("Not implemented: buddyRequest")}buddyAccept(e){throw new Error("Not implemented: buddyAccept")}buddyReject(e){throw new Error("Not implemented: buddyReject")}buddyRequestSeen(e){throw new Error("Not implemented: buddyRequestSeen")}getBuddy(e,r){throw new Error("Not implemented: getBuddy")}removeBuddy(e){throw new Error("Not implemented: removeBuddy")}addIgnore(e){throw new Error("Not implemented: addIgnore")}removeIgnore(e){throw new Error("Not implemented: removeIgnore")}getPlayer(e){throw new Error("Not implemented: getPlayer")}getAllSlots(){throw new Error("Not implemented: getAllSlots")}getMascots(){throw new Error("Not implemented: getMascots")}sendPostcard(e,r){throw new Error("Not implemented: sendPostcard")}getStamps(e){throw new Error("Not implemented: getStamps")}getPostcards(){throw new Error("Not implemented: getPostcards")}getIglooOpen(e){throw new Error("Not implemented: getIglooOpen")}getIgloos(){throw new Error("Not implemented: getIgloos")}getPuffles(e){throw new Error("Not implemented: getPuffles")}adoptPuffle(e,r){throw new Error("Not implemented: adoptPuffle")}getIglooLikes(){throw new Error("Not implemented: getIglooLikes")}checkPuffleSprite(e){throw new Error("Not implemented: checkPuffleSprite")}joinIgloo(e,r,o){throw new Error("Not implemented: joinIgloo")}gameOver(e){throw new Error("Not implemented: gameOver")}collectStamp(e){throw new Error("Not implemented: collectStamp")}getNinja(){throw new Error("Not implemented: getNinja")}getMats(){throw new Error("Not implemented: getMats")}joinMatchmaking(){throw new Error("Not implemented: joinMatchmaking")}leaveMatchmaking(){throw new Error("Not implemented: leaveMatchmaking")}startGame(){throw new Error("Not implemented: startGame")}selectCard(e){throw new Error("Not implemented: selectCard")}loadAnimation(e){throw new Error("Not implemented: loadAnimation")}joinMat(e){throw new Error("Not implemented: joinMat")}};import{EventEmitter as ve}from"events";import{io as K}from"socket.io-client";import D from"socket.io-msgpack-parser";var H="wss://play.cpjourney.net",G="skip",P=class extends b{id="CPJourney";async login(e){let r=this.createSocket("/world/login/");return await new Promise((s,t)=>{let n=setTimeout(()=>{r.disconnect(),t(new Error("Login timed out"))},1e4);r.on("connect",()=>{let i=e.secret??G,a="token"in e?{username:e.username,token:e.token,secret:i}:{username:e.username,password:e.password,secret:i};r.emit("message",{action:"login",args:a})}),r.on("message",i=>{if(i.action!=="login")return;clearTimeout(n),r.disconnect();let a=i.args;if(!a.success){t(new Error("Login failed"));return}let u=Object.entries(a.populations).map(([m,l])=>({name:m,population:l}));s({servers:u,key:a.key,username:a.username,moderator:a.moderator,buddyWorlds:a.buddyWorlds??[]})}),r.on("connect_error",i=>{clearTimeout(n),r.disconnect(),t(new Error(`Login connection failed: ${i.message}`))})})}async connect(e,r,o){await this.queueForServer(e,o);let s=this.createSocket(`/world/${e.toLowerCase()}/`);return this.socket=s,await new Promise((t,n)=>{let i=!1;s.on("connect",()=>{s.emit("message",{action:"game_auth",args:{username:r.username,key:r.key,createToken:!1,joinInvis:!1,takeoverMascot:!1,token:""}})}),s.on("message",a=>{switch(a.action){case"wait_queue_update":{o?.onQueueUpdate?.(a.args);break}case"game_auth":{if(i)break;if(i=!0,!a.args.success){s.disconnect(),n(new Error("Game auth failed"));return}s.emit("message",{action:"join_server",args:{}}),t();break}}}),s.on("connect_error",a=>{s.disconnect(),n(new Error(`Game connection failed: ${a.message}`))})}),s}async queueForServer(e,r){let o=this.createSocket("/world/login/");await new Promise((s,t)=>{let n=setTimeout(()=>{o.disconnect(),t(new Error("Queue timed out"))},6e4);o.on("connect",()=>{o.emit("message",{action:"queue_server_join",args:{server:e}})}),o.on("message",i=>{switch(i.action){case"wait_queue_update":r?.onQueueUpdate?.(i.args);break;case"queue_server_join":clearTimeout(n),o.disconnect(),s();break}}),o.once("disconnect",()=>{clearTimeout(n),s()}),o.on("connect_error",i=>{clearTimeout(n),o.disconnect(),t(new Error(`Queue connection failed: ${i.message}`))})})}send(e,r){if(!this.socket)throw new Error("Not connected");this.socket.emit("message",{action:e,args:r})}disconnect(){this.socket?.disconnect(),this.socket=null}normalizeUser(e){let{id:r,username:o,displayName:s,joinTime:t,x:n,y:i,frame:a,walking:u,color:m,head:l,face:h,neck:p,body:f,hand:E,feet:v,flag:w,photo:_,...O}=e;return{...this.extractAppearance(e),id:r,username:o,displayName:s,joinTime:t,x:n??0,y:i??0,frame:a??0,walking:u,meta:O,_raw:e}}normalizePlayer(e){let r=e.user,o=this.normalizeUser(r),{user:s,coins:t,rank:n,inventory:i,furniture:a,flooring:u,buddies:m,buddyRequests:l,ignores:h,igloos:p,...f}=e;return{...o,_raw:e,coins:t??0,rank:n??0,inventory:i??[],furniture:a??[],flooring:u??[],buddies:r.buddies??[],buddyRequests:r.buddyRequests??[],ignores:r.ignores??[],igloos:p??[],meta:{...o.meta,...f}}}sendMessage(e){this.send("send_message",{message:e})}sendEmote(e){this.send("send_emote",{emote:e})}sendSafe(e){this.send("send_safe",{safe:e})}walk(e,r){this.send("send_position",{x:e,y:r})}sendFrame(e,r){this.send("send_frame",{frame:e,set:r})}snowball(e,r){this.send("snowball",{x:e,y:r})}joinRoom(e,r,o){this.send("join_room",{room:e,x:r??0,y:o??0})}addItem(e){this.send("add_item",{item:e})}equipColor(e){this.send("update_color",{item:e})}equipHead(e){this.send("update_head",{item:e})}equipFace(e){this.send("update_face",{item:e})}equipNeck(e){this.send("update_neck",{item:e})}equipBody(e){this.send("update_body",{item:e})}equipHand(e){this.send("update_hand",{item:e})}equipFeet(e){this.send("update_feet",{item:e})}equipFlag(e){this.send("update_flag",{item:e})}equipPhoto(e){this.send("update_photo",{item:e})}buddyRequest(e){this.send("buddy_request",{id:e})}buddyAccept(e){this.send("buddy_accept",{id:e})}buddyReject(e){this.send("buddy_reject",{id:e})}buddyRequestSeen(e){this.send("buddy_request_seen",{id:e})}getBuddy(e,r){this.send("get_buddy",{id:e,type:r})}removeBuddy(e){this.send("remove_buddy",{id:e})}addIgnore(e){this.send("ignore_add",{id:e})}removeIgnore(e){this.send("ignore_remove",{id:e})}getPlayer(e){this.send("get_player",{id:e})}getAllSlots(){this.send("get_all_slots",{})}getMascots(){this.send("get_mascots",{})}sendPostcard(e,r){this.send("send_postcard",{userId:e,cardId:r})}getStamps(e){this.send("get_stamps",{userId:e})}getPostcards(){this.send("get_postcards",{})}getIglooOpen(e){this.send("get_igloo_open",{igloo:e})}getIgloos(){this.send("get_igloos",{})}getPuffles(e){this.send("get_puffles",{userId:e})}adoptPuffle(e,r){this.send("adopt_puffle",{type:e,name:r})}getIglooLikes(){this.send("get_igloo_likes",{})}checkPuffleSprite(e){this.send("check_puffle_sprite",{puffleSprite:e})}joinIgloo(e,r,o){this.send("join_igloo",{igloo:e,x:r??0,y:o??0})}gameOver(e){this.send("game_over",{coins:e})}collectStamp(e){this.send("collect_stamp",{stamp:e})}getNinja(){this.send("get_ninja",{})}getMats(){this.send("get_waddles",{})}joinMatchmaking(){this.send("join_matchmaking",{})}leaveMatchmaking(){this.send("leave_matchmaking",{})}startGame(){this.send("start_game",{})}selectCard(e){this.send("select_card",{slot:e})}loadAnimation(e){this.send("load_animation",{animation:e})}joinMat(e){this.send("join_waddle",{waddle:e})}createSocket(e){return K(H,{path:e,parser:D,transports:["polling","websocket"],reconnection:!1})}};import{io as W}from"socket.io-client";import z from"socket.io-msgpack-parser";var Q="https://api.cplegacy.com/login",J="https://api.cplegacy.com/token_login";function X(c){let e=c.on.bind(c);return c.on=((r,o)=>r==="message"?e(r,(s,t)=>{o({action:s,args:t??{}})}):e(r,o)),c}var N=class extends b{id="CPLegacy";version="";async login(e){let r="token"in e?J:Q,o="token"in e?{username:e.username,token:e.token}:{username:e.username,password:e.password,version:this.version},s=await this.postLogin(r,o);if(!s.success&&s.wantedVersion&&(this.version=s.wantedVersion,o.version=this.version,s=await this.postLogin(r,o)),!s.success)throw new Error(`Login failed: ${s.message??"unknown error"}`);return{servers:Object.entries(s.populations??{}).map(([n,i])=>({name:n,population:i})),key:s.key,username:s.username,moderator:!1,buddyWorlds:[]}}async connect(e,r,o){let s=`wss://${e.toLowerCase()}.server.cplegacy.com`,t=W(s,{path:"/socket.io/",parser:z,transports:["websocket"],reconnection:!1});return this.socket=t,await new Promise((n,i)=>{let a=setTimeout(()=>{t.disconnect(),i(new Error("Game connection timed out"))},15e3);t.on("connect",()=>{t.emit("message","game_auth",{username:r.username,key:r.key,createToken:!1,token:""})}),t.on("message",(u,m)=>{switch(u){case"wait_queue_update":{o?.onQueueUpdate?.(m);break}case"game_auth":{if(!m.success){clearTimeout(a),t.disconnect(),i(new Error("Game auth failed"));return}t.emit("message","load_player",{}),t.emit("message","join_server",{}),clearTimeout(a),n();break}}}),t.on("connect_error",u=>{clearTimeout(a),t.disconnect(),i(new Error(`Game connection failed: ${u.message}`))})}),X(t)}send(e,r){if(!this.socket)throw new Error("Not connected");this.socket.emit("message",e,r)}disconnect(){this.socket?.disconnect(),this.socket=null}normalizeUser(e){return{...this.extractAppearance(e),id:e.id,username:e.username,displayName:e.realUsername??e.username,joinTime:e.joinTime,x:e.x??0,y:e.y??0,frame:e.frame??0,walking:e.walking??void 0,meta:{internalUsername:e.username,approved:e.approved,emailVerified:e.emailVerified,safeChat:e.safeChat,tutorial:e.tutorial,loginStreak:e.loginStreak,walkingColor:e.walkingColor,stampbookColor:e.stampbookColor,stampbookClasp:e.stampbookClasp,stampbookPattern:e.stampbookPattern,ninjaPoints:e.ninjaPoints,highestNinjaRank:e.highestNinjaRank,character:e.character,transformed:e.transformed},_raw:e}}normalizePlayer(e){let r=e.user;return{...this.normalizeUser(r),_raw:e,coins:r.coins??0,rank:r.rank??0,inventory:e.inventory??[],furniture:e.furniture,buddies:[],buddyRequests:e.pending?.map(o=>o.id)??[],ignores:[],igloos:e.igloos??[]}}sendMessage(e){this.send("send_message",{message:e})}sendEmote(e){this.send("send_emote",{emote:e})}sendSafe(e){this.send("send_safe",{safe:e})}walk(e,r){this.send("send_position",{x:e,y:r})}sendFrame(e,r){this.send("send_frame",{frame:e,set:r})}snowball(e,r){this.send("snowball",{x:e,y:r})}joinRoom(e,r,o){this.send("join_room",{room:e,x:r??0,y:o??0})}addItem(e){this.send("add_item",{item:e})}equipColor(e){this.send("update_color",{item:e})}equipHead(e){this.send("update_head",{item:e})}equipFace(e){this.send("update_face",{item:e})}equipNeck(e){this.send("update_neck",{item:e})}equipBody(e){this.send("update_body",{item:e})}equipHand(e){this.send("update_hand",{item:e})}equipFeet(e){this.send("update_feet",{item:e})}equipFlag(e){this.send("update_flag",{item:e})}equipPhoto(e){this.send("update_photo",{item:e})}buddyRequest(e){this.send("buddy_request",{id:e})}buddyAccept(e){this.send("buddy_accept",{id:e})}buddyReject(e){this.send("buddy_reject",{id:e})}removeBuddy(e){this.send("remove_buddy",{id:e})}addIgnore(e){this.send("ignore_add",{id:e})}removeIgnore(e){this.send("ignore_remove",{id:e})}getPlayer(e){this.send("get_player",{id:e})}getStamps(e){this.send("get_stamps",{userId:e})}getPostcards(){this.send("get_postcards",{})}joinIgloo(e,r,o){this.send("join_igloo",{igloo:e,x:r??0,y:o??0})}gameOver(e){this.send("game_over",{coins:e})}collectStamp(e){this.send("collect_stamp",{stamp:e})}async postLogin(e,r){return(await fetch(e,{method:"POST",headers:{"Content-Type":"application/json",Accept:"application/json"},body:JSON.stringify(r)})).json()}};import{createHash as V}from"crypto";import{EventEmitter as Y}from"events";import A from"ws";var Z="wss://server.cpzero.net/login",ee="wss://server.cpzero.net/sub_zero",F="253",$="w1",y="\0",g={ID:0,USERNAME:1,COLOR:3,HEAD:4,FACE:5,NECK:6,BODY:7,HAND:8,BACK:9,BODY2:10,HAND2:11,BEAK:12,HAIR:13,FEET:14,MOUNT:15,FLAG:16,PHOTO:17,X:18,Y:19,FRAME:20,RANK:22};function re(c){return V("md5").update(c).digest("hex")}function oe(c){let e=re(c);return e.substring(16,32)+e.substring(0,16)}function d(c){let e=Number(c);return Number.isNaN(e)?0:e}function q(c){let e=c.split("|");return{id:d(e[g.ID]),username:e[g.USERNAME]??"",color:d(e[g.COLOR]),head:d(e[g.HEAD]),face:d(e[g.FACE]),neck:d(e[g.NECK]),body:d(e[g.BODY]),hand:d(e[g.HAND]),back:d(e[g.BACK]),body2:d(e[g.BODY2]),hand2:d(e[g.HAND2]),beak:d(e[g.BEAK]),hair:d(e[g.HAIR]),feet:d(e[g.FEET]),mount:d(e[g.MOUNT]),flag:d(e[g.FLAG]),photo:d(e[g.PHOTO]),x:d(e[g.X]),y:d(e[g.Y]),frame:d(e[g.FRAME]),rank:d(e[g.RANK])}}var T=class extends Y{ws;_closed=!1;_buffering=!0;_buffer=[];constructor(e){super(),this.ws=e,e.on("close",()=>{this._closed=!0,this.emit("disconnect")}),e.on("error",r=>{this.emit("connect_error",r)})}dispatchMessage(e,r){this._buffering&&this._buffer.push({action:e,args:r}),this.emit("message",{action:e,args:r})}flush(){this._buffering=!1;let e=this._buffer;this._buffer=[],setTimeout(()=>{for(let r of e)this.emit("message",r)},0)}send(e){this._closed||this.ws.send(e+y)}disconnect(){this._closed||(this._closed=!0,this.ws.close())}get connected(){return!this._closed&&this.ws.readyState===A.OPEN}};function ne(c,e){switch(c){case"lp":{let r=q(e[0]??""),o=d(e[1]),s=r.rank;return{action:"load_player",args:{user:r,coins:o,rank:s}}}case"jr":{let r=d(e[0]),o=e.slice(1).filter(Boolean).map(q);return{action:"join_room",args:{room:r,users:o}}}case"ap":return{action:"add_player",args:{user:q(e[0]??"")}};case"rp":return{action:"remove_player",args:{user:d(e[0])}};case"sp":return{action:"send_position",args:{id:d(e[0]),x:d(e[1]),y:d(e[2])}};case"sf":return{action:"send_frame",args:{id:d(e[0]),frame:d(e[1])}};case"sm":return{action:"send_message",args:{id:d(e[0]),message:e[1]??""}};case"se":return{action:"send_emote",args:{id:d(e[0]),emote:d(e[1])}};case"sa":return{action:"send_safe",args:{id:d(e[0]),safe:d(e[1])}};case"sb":return{action:"snowball",args:{id:d(e[0]),x:d(e[1]),y:d(e[2])}};case"gp":return{action:"get_player",args:{user:q(e[0]??"")}};case"upc":return{action:"update_player",args:{id:d(e[0]),item:d(e[1]),slot:"color"}};case"uph":return{action:"update_player",args:{id:d(e[0]),item:d(e[1]),slot:"head"}};case"upf":return{action:"update_player",args:{id:d(e[0]),item:d(e[1]),slot:"face"}};case"upn":return{action:"update_player",args:{id:d(e[0]),item:d(e[1]),slot:"neck"}};case"upb":return{action:"update_player",args:{id:d(e[0]),item:d(e[1]),slot:"body"}};case"upa":return{action:"update_player",args:{id:d(e[0]),item:d(e[1]),slot:"hand"}};case"upe":return{action:"update_player",args:{id:d(e[0]),item:d(e[1]),slot:"feet"}};case"upl":return{action:"update_player",args:{id:d(e[0]),item:d(e[1]),slot:"flag"}};case"upp":return{action:"update_player",args:{id:d(e[0]),item:d(e[1]),slot:"photo"}};case"upba":return{action:"update_player",args:{id:d(e[0]),item:d(e[1]),slot:"back"}};case"upm":return{action:"update_player",args:{id:d(e[0]),item:d(e[1]),slot:"mount"}};case"ai":return{action:"add_item",args:{item:d(e[0]),coins:d(e[1])}};case"jg":return{action:"join_game_room",args:{game:d(e[0])}};case"e":return{action:"error",args:{error:e[0]??"unknown"}};default:return null}}var x=class extends b{id="CPZero";sfs=null;async login(e){if("token"in e)throw new Error("CPZero does not support token login");let r=e.secret;if(!r)throw new Error("CPZero requires a pre-computed login hash in options.secret");let o=new A(Z);return await new Promise((t,n)=>{let i=setTimeout(()=>{o.close(),n(new Error("Login timed out"))},15e3),a="";o.on("open",()=>{o.send(k("verChk","0",`<ver v='${F}' />`)+y)}),o.on("message",u=>{let m=u.toString("utf-8").split(y).filter(Boolean);for(let l of m){if(l.includes('action="apiOK"')||l.includes("action='apiOK'")){o.send(k("rndK","-1","")+y);continue}let h=l.match(/<k>(.*?)<\/k>/);if(h){a=h[1];let p=se(e.username,r);o.send(p+y);continue}if(l.startsWith("%xt%l%")){let p=l.split("%").filter(Boolean),f=p[3]??"",E=p[4]??"",v=f.split("|");clearTimeout(i),o.close();let w=d(v[0]),_=v[2]??e.username;t({servers:[{name:"Sub Zero",population:0}],key:`${w}|${f}|${E}`,username:_,moderator:!1,buddyWorlds:[]});return}if(l.startsWith("%xt%e%")){clearTimeout(i),o.close();let p=l.split("%").filter(Boolean);n(new Error(`Login failed: error ${p[3]??"unknown"}`));return}}}),o.on("error",u=>{clearTimeout(i),o.close(),n(new Error(`Login WS error: ${u.message}`))}),o.on("close",()=>{clearTimeout(i)})})}async connect(e,r,o){let s=r.key.split("|"),t=s[0]??"",n=s.slice(1,-1).join("|"),i=s[s.length-1]??"",a=n.split("|")[3]??"",u=new A(ee),m=new T(u);return this.sfs=m,this.socket=m,await new Promise((l,h)=>{let p=setTimeout(()=>{u.close(),h(new Error("Game connection timed out"))},15e3);u.on("open",()=>{m.send(k("verChk","0",`<ver v='${F}' />`))}),u.on("message",f=>{let E=f.toString("utf-8").split(y).filter(Boolean);for(let v of E){if(v.includes('action="apiOK"')||v.includes("action='apiOK'")){m.send(k("rndK","-1",""));continue}let w=v.match(/<k>(.*?)<\/k>/);if(w){let _=w[1],O=`${oe(a+_)}${a}#${i}`;m.send(te(n,O));continue}if(v.startsWith("%xt%")&&(this.processXtBatch(v,m),v.includes("%xt%l%")&&m.send(`%xt%s%j#js%-1%${t}%${a}%en%`),v.includes("%xt%jr%")&&(clearTimeout(p),l())),v.includes("%xt%e%")){clearTimeout(p),u.close();let _=v.split("%").filter(Boolean);h(new Error(`Game auth failed: error ${_[3]??"unknown"}`));return}}}),u.on("error",f=>{clearTimeout(p),h(new Error(`Game WS error: ${f.message}`))})}),u.on("message",l=>{let h=l.toString("utf-8").split(y).filter(Boolean);for(let p of h)p.startsWith("%xt%")&&this.processXtBatch(p,m)}),m.flush(),m}send(e,r){if(!this.sfs)throw new Error("Not connected");let o=ie(e,r);o&&this.sfs.send(o)}disconnect(){this.sfs?.disconnect(),this.sfs=null,this.socket=null}normalizeUser(e){return{...this.extractAppearance(e),id:e.id,username:e.username,x:e.x??0,y:e.y??0,frame:e.frame??0,meta:{back:e.back,body2:e.body2,hand2:e.hand2,beak:e.beak,hair:e.hair,mount:e.mount,rank:e.rank},_raw:e}}normalizePlayer(e){let r=e.user;return{...this.normalizeUser(r),_raw:e,coins:e.coins??0,rank:r.rank??0,inventory:[],buddies:[],ignores:[]}}sendMessage(e){if(!this.sfs)throw new Error("Not connected");this.sfs.send(`%xt%s%m#sm%-1%0%${e}%`)}sendEmote(e){if(!this.sfs)throw new Error("Not connected");this.sfs.send(`%xt%s%u#se%-1%${e}%`)}sendSafe(e){if(!this.sfs)throw new Error("Not connected");this.sfs.send(`%xt%s%u#sa%-1%${e}%`)}walk(e,r){if(!this.sfs)throw new Error("Not connected");this.sfs.send(`%xt%s%u#sp%-1%${e}%${r}%`)}sendFrame(e){if(!this.sfs)throw new Error("Not connected");this.sfs.send(`%xt%s%u#sf%-1%${e}%`)}snowball(e,r){if(!this.sfs)throw new Error("Not connected");this.sfs.send(`%xt%s%u#sb%-1%${e}%${r}%`)}joinRoom(e,r,o){if(!this.sfs)throw new Error("Not connected");this.sfs.send(`%xt%s%j#jr%-1%${e}%${r??0}%${o??0}%`)}addItem(e){if(!this.sfs)throw new Error("Not connected");this.sfs.send(`%xt%s%i#ai%-1%${e}%`)}equipColor(e){if(!this.sfs)throw new Error("Not connected");this.sfs.send(`%xt%s%s#upc%-1%${e}%`)}equipHead(e){if(!this.sfs)throw new Error("Not connected");this.sfs.send(`%xt%s%s#uph%-1%${e}%`)}equipFace(e){if(!this.sfs)throw new Error("Not connected");this.sfs.send(`%xt%s%s#upf%-1%${e}%`)}equipNeck(e){if(!this.sfs)throw new Error("Not connected");this.sfs.send(`%xt%s%s#upn%-1%${e}%`)}equipBody(e){if(!this.sfs)throw new Error("Not connected");this.sfs.send(`%xt%s%s#upb%-1%${e}%`)}equipHand(e){if(!this.sfs)throw new Error("Not connected");this.sfs.send(`%xt%s%s#upa%-1%${e}%`)}equipFeet(e){if(!this.sfs)throw new Error("Not connected");this.sfs.send(`%xt%s%s#upe%-1%${e}%`)}equipFlag(e){if(!this.sfs)throw new Error("Not connected");this.sfs.send(`%xt%s%s#upl%-1%${e}%`)}equipPhoto(e){if(!this.sfs)throw new Error("Not connected");this.sfs.send(`%xt%s%s#upp%-1%${e}%`)}getPlayer(e){if(!this.sfs)throw new Error("Not connected");this.sfs.send(`%xt%s%u#gp%-1%${e}%`)}joinIgloo(e,r,o){if(!this.sfs)throw new Error("Not connected");this.sfs.send(`%xt%s%j#jp%-1%${e}%igloo%`)}processXtBatch(e,r){let o=e.split(/(?=%xt%)/).map(s=>s.trim()).filter(Boolean);for(let s of o){let t=s.split("%").filter(Boolean);if(t[0]!=="xt"||t.length<3)continue;let n=t[1],i=t.slice(3),a=ne(n,i);a&&r.dispatchMessage(a.action,a.args)}}};function k(c,e,r){return`<msg t='sys'><body action='${c}' r='${e}'>${r}</body></msg>`}function se(c,e){return k("login","0",`<login z='${$}'><nick><![CDATA[${c}]]></nick><pword><![CDATA[${e}]]></pword></login>`)}function te(c,e){return k("login","0",`<login z='${$}'><nick><![CDATA[${c}]]></nick><pword><![CDATA[${e}]]></pword></login>`)}function ie(c,e){switch(c){case"send_position":return`%xt%s%u#sp%-1%${e.x}%${e.y}%`;case"send_frame":return`%xt%s%u#sf%-1%${e.frame}%`;case"send_message":return`%xt%s%m#sm%-1%0%${e.message}%`;case"send_emote":return`%xt%s%u#se%-1%${e.emote}%`;case"send_safe":return`%xt%s%u#sa%-1%${e.safe}%`;case"snowball":return`%xt%s%u#sb%-1%${e.x}%${e.y}%`;case"join_room":return`%xt%s%j#jr%-1%${e.room}%${e.x??0}%${e.y??0}%`;case"add_item":return`%xt%s%i#ai%-1%${e.item}%`;case"get_player":return`%xt%s%u#gp%-1%${e.id}%`;default:return null}}import{createCipheriv as ae,createDecipheriv as de,randomBytes as ue}from"crypto";import{io as ce}from"socket.io-client";import j from"tweetnacl";var me="https://media8.newcp.net/assets/media/crumbs/en/crumbs.json",S=class{aesKey=null;keypair=j.box.keyPair();get publicKey(){return Buffer.from(this.keypair.publicKey).toString("base64")}get encrypted(){return this.aesKey!==null}acquireKey(e,r){let o=Buffer.from(e,"base64"),s=Buffer.from(r,"base64"),t=o.subarray(0,j.box.nonceLength),n=o.subarray(j.box.nonceLength),i=j.box.open(new Uint8Array(n),new Uint8Array(t),new Uint8Array(s),this.keypair.secretKey);return i?new TextDecoder().decode(i):null}setKey(e){this.aesKey=Buffer.from(e,"utf-8")}encrypt(e){if(!this.aesKey)throw new Error("Encryption key not set");let r=ue(16),o=ae("aes-256-cbc",this.aesKey,r),s=Buffer.concat([o.update(e,"utf-8"),o.final()]);return Buffer.concat([r,s]).toString("base64")}decrypt(e){if(!this.aesKey)throw new Error("Encryption key not set");let r=Buffer.from(e,"base64"),o=r.subarray(0,16),s=r.subarray(16),t=de("aes-256-cbc",this.aesKey,o);return Buffer.concat([t.update(s),t.final()]).toString("utf-8")}encode(e){return this.encrypted?this.encrypt(JSON.stringify(e)):JSON.stringify(e)}decode(e){return this.encrypted&&typeof e=="string"?JSON.parse(this.decrypt(e)):typeof e=="string"?JSON.parse(e):e}};function U(c,e){return new Promise((r,o)=>{let s=setTimeout(()=>{o(new Error("Handshake timed out"))},1e4);c.once("handshake",(t,n)=>{clearTimeout(s);let i=e.acquireKey(t,n);if(!i){o(new Error("Failed to decrypt handshake key"));return}let a=JSON.parse(i);if(a.time&&typeof a.time=="number"&&Math.abs(Date.now()-a.time)>3e5){o(new Error("Server time desync"));return}e.setKey(a.key),r()}),c.emit("handshake",e.publicKey)})}function le(c,e){let r=c.on.bind(c);return c.on=((o,s)=>o==="message"?r(o,t=>{try{let n=e.decode(t);s({action:n.action,args:n.args??{}})}catch{}}):r(o,s)),c}var M=class extends b{id="NewCP";encryptor=new S;worlds=null;async login(e){this.worlds||await this.loadWorlds();let r=Object.values(this.worlds??{}).find(t=>t.login);if(!r)throw new Error("Login world not found in crumbs");let o=this.createSocket(r.host,r.path);return this.encryptor=new S,await new Promise((t,n)=>{let i=setTimeout(()=>{o.disconnect(),n(new Error("Login timed out"))},15e3);o.on("connect",async()=>{try{await U(o,this.encryptor);let a="token"in e?{username:e.username,token:e.token}:{username:e.username,password:e.password},u=this.encryptor.encode({action:"login",args:a});o.emit("message",u)}catch(a){clearTimeout(i),o.disconnect(),n(a)}}),o.on("message",a=>{try{let u=this.encryptor.decode(a);if(u.action!=="login")return;clearTimeout(i),o.disconnect();let m=u.args;if(!m.success){n(new Error("Login failed"));return}let l=Object.entries(m.populations??{}).map(([h,p])=>({name:h,population:p}));t({servers:l,key:m.key,username:m.username,moderator:m.moderator??!1,buddyWorlds:m.buddyWorlds??[]})}catch(u){clearTimeout(i),o.disconnect(),n(u)}}),o.on("connect_error",a=>{clearTimeout(i),o.disconnect(),n(new Error(`Login connection failed: ${a.message}`))})})}async connect(e,r,o){this.worlds||await this.loadWorlds();let s=this.worlds?.[e];if(!s)throw new Error(`World config not found for: ${e}`);this.encryptor=new S;let t=this.createSocket(s.host,s.path);return this.socket=t,await new Promise((n,i)=>{let a=setTimeout(()=>{t.disconnect(),i(new Error("Game connection timed out"))},15e3);t.on("connect",async()=>{try{await U(t,this.encryptor);let u=this.encryptor.encode({action:"game_auth",args:{username:r.username,key:r.key,createToken:!1}});t.emit("message",u)}catch(u){clearTimeout(a),t.disconnect(),i(u)}}),t.on("message",u=>{try{let m=this.encryptor.decode(u);switch(m.action){case"wait_queue_update":{o?.onQueueUpdate?.(m.args);break}case"game_auth":{if(!m.args.success){clearTimeout(a),t.disconnect(),i(new Error("Game auth failed"));return}let h=this.encryptor.encode({action:"join_server",args:{}});t.emit("message",h),clearTimeout(a),n();break}}}catch{}}),t.on("connect_error",u=>{clearTimeout(a),t.disconnect(),i(new Error(`Game connection failed: ${u.message}`))})}),le(t,this.encryptor)}send(e,r){if(!this.socket)throw new Error("Not connected");let o=this.encryptor.encode({action:e,args:r});this.socket.emit("message",o)}disconnect(){this.socket?.disconnect(),this.socket=null}normalizeUser(e){return{...this.extractAppearance(e),id:e.id,username:e.username,displayName:e.nickname,x:e.x??0,y:e.y??0,frame:e.frame??0,meta:{nickname:e.nickname,registrationDate:e.registrationDate,customNameColor:e.customNameColor,customBubbleColor:e.customBubbleColor,customBubbleTextColor:e.customBubbleTextColor,wallHacks:e.wallHacks,moderator:e.moderator,character:e.character,approved:e.approved,walking:e.walking},_raw:e}}normalizePlayer(e){let r=e.user;return{...this.normalizeUser(r),_raw:e,coins:e.coins??0,rank:e.rank??0,inventory:e.inventory??[],buddies:e.buddies??[],ignores:e.ignores??[],furniture:e.furniture,flooring:e.floorings??[],igloos:e.igloos??[]}}sendMessage(e){this.send("send_message",{message:e})}sendEmote(e){this.send("send_emote",{emote:e})}sendSafe(e){this.send("send_safe",{safe:e})}walk(e,r){this.send("send_position",{x:e,y:r})}sendFrame(e,r){this.send("send_frame",{frame:e,set:r})}snowball(e,r){this.send("snowball",{x:e,y:r})}joinRoom(e,r,o){this.send("join_room",{room:e,x:r??0,y:o??0})}addItem(e){this.send("add_item",{item:e})}equipColor(e){this.send("update_color",{item:e})}equipHead(e){this.send("update_head",{item:e})}equipFace(e){this.send("update_face",{item:e})}equipNeck(e){this.send("update_neck",{item:e})}equipBody(e){this.send("update_body",{item:e})}equipHand(e){this.send("update_hand",{item:e})}equipFeet(e){this.send("update_feet",{item:e})}equipFlag(e){this.send("update_flag",{item:e})}equipPhoto(e){this.send("update_photo",{item:e})}buddyRequest(e){this.send("buddy_request",{id:e})}buddyAccept(e){this.send("buddy_accept",{id:e})}buddyReject(e){this.send("buddy_reject",{id:e})}removeBuddy(e){this.send("remove_buddy",{id:e})}addIgnore(e){this.send("ignore_add",{id:e})}removeIgnore(e){this.send("ignore_remove",{id:e})}getPlayer(e){this.send("get_player",{id:e})}joinIgloo(e,r,o){this.send("join_igloo",{igloo:e,x:r??0,y:o??0})}createSocket(e,r){return ce(e,{path:r,transports:["polling","websocket"],reconnection:!1})}async loadWorlds(){let e=await fetch(me);if(!e.ok)throw new Error(`Failed to fetch crumbs: ${e.status}`);let r=await e.json();this.worlds=r.worlds}};import{io as pe}from"socket.io-client";var ge="https://play.penguinorigins.online",L=class extends b{id="PenguinOrigins";async login(e){let r=this.createSocket("/world/login/");return await new Promise((s,t)=>{let n=setTimeout(()=>{r.disconnect(),t(new Error("Login timed out"))},1e4);r.on("connect",()=>{let i="token"in e?"token_login":"login",a="token"in e?{username:e.username,token:e.token}:{username:e.username,password:e.password};r.emit("message",{action:i,args:a})}),r.on("message",i=>{if(i.action!=="login")return;clearTimeout(n),r.disconnect();let a=i.args;if(!a.success){t(new Error("Login failed"));return}let u=Object.entries(a.populations).map(([m,l])=>({name:m,population:l}));s({servers:u,key:a.key,username:a.username,moderator:!1,buddyWorlds:[]})}),r.on("connect_error",i=>{clearTimeout(n),r.disconnect(),t(new Error(`Login connection failed: ${i.message}`))})})}async connect(e,r,o){let s=this.createSocket(`/world/${e.toLowerCase()}/`);return this.socket=s,await new Promise((t,n)=>{let i=!1;s.on("connect",()=>{s.emit("message",{action:"game_auth",args:{username:r.username,key:r.key,createToken:!0,token:""}})}),s.on("message",a=>{switch(a.action){case"wait_queue_update":{o?.onQueueUpdate?.(a.args);break}case"game_auth":{if(i)break;if(i=!0,!a.args.success){s.disconnect(),n(new Error("Game auth failed"));return}s.emit("message",{action:"join_server",args:{}}),t();break}}}),s.on("connect_error",a=>{s.disconnect(),n(new Error(`Game connection failed: ${a.message}`))})}),s}send(e,r){if(!this.socket)throw new Error("Not connected");this.socket.emit("message",{action:e,args:r})}disconnect(){this.socket?.disconnect(),this.socket=null}normalizeUser(e){return{...this.extractAppearance(e),id:e.id,username:e.username,displayName:e.nickname??e.username,joinTime:e.joinTime,x:e.x??0,y:e.y??0,frame:e.frame??0,meta:{toy:e.toy},_raw:e}}normalizePlayer(e){let r=e.user,o=this.normalizeUser(r);return{...o,_raw:e,coins:e.coins??0,rank:e.rank??0,inventory:e.inventory??[],furniture:e.furniture??[],flooring:e.flooring??[],buddies:e.buddies??[],buddyRequests:e.buddyRequests??[],ignores:e.ignores??[],igloos:e.igloos??[],meta:{...o.meta,postcards:e.postcards,mascots:e.mascots,pets:e.pets}}}sendMessage(e){this.send("send_message",{message:e})}sendEmote(e){this.send("send_emote",{emote:e})}sendSafe(e){this.send("send_safe",{safe:e})}walk(e,r){this.send("send_position",{x:e,y:r})}sendFrame(e,r){this.send("send_frame",{frame:e,set:r??!1})}snowball(e,r){this.send("snowball",{x:e,y:r})}joinRoom(e,r,o){this.send("join_room",{room:e,x:r??0,y:o??0})}addItem(e){this.send("add_item",{item:e})}equipColor(e){this.send("update_player",{item:e})}equipHead(e){this.send("update_player",{item:e})}equipFace(e){this.send("update_player",{item:e})}equipNeck(e){this.send("update_player",{item:e})}equipBody(e){this.send("update_player",{item:e})}equipHand(e){this.send("update_player",{item:e})}equipFeet(e){this.send("update_player",{item:e})}equipFlag(e){this.send("update_player",{item:e})}equipPhoto(e){this.send("update_player",{item:e})}buddyRequest(e){this.send("buddy_request",{id:e})}buddyAccept(e){this.send("buddy_accept",{id:e})}addIgnore(e){this.send("ignore_add",{id:e})}removeIgnore(e){this.send("ignore_remove",{id:e})}getIglooOpen(e){this.send("get_igloo_open",{igloo:e})}joinIgloo(e,r,o){this.send("join_igloo",{igloo:e,x:r??0,y:o??0})}gameOver(e){this.send("game_over",{coins:e})}createSocket(e){return pe(ge,{path:e,transports:["polling","websocket"],reconnection:!1})}};var he={CPJourney:P,CPLegacy:N,CPZero:x,NewCP:M,PenguinOrigins:L};function B(c){return new he[c]}var R=class{constructor(e,r){this.adapter=e;this.waitFor=r}adapter;waitFor;getNinja(){return this.adapter.getNinja(),this.waitFor("get_ninja")}getMats(){return this.adapter.getMats(),this.waitFor("get_waddles")}joinMat(e){this.adapter.joinMat(e)}joinMatchmaking(){return this.adapter.joinMatchmaking(),this.waitFor("join_matchmaking")}leaveMatchmaking(){this.adapter.leaveMatchmaking()}startGame(){return this.adapter.startGame(),this.waitFor("start_game")}selectCard(e){return this.adapter.selectCard(e),this.waitFor("move_my_card")}loadAnimation(e){this.adapter.loadAnimation(e)}};var be=new Set(["load_player","join_room","add_player","remove_player","send_position","send_frame","update_player","kick","close_with_error","send_message","send_emote","cpj_ping","open_sprite","close_sprite","set_weather","server_error","error","stamp_earned","game_over","join_game_room","get_ninja","get_waddles","update_waddle","join_matchmaking","tick_matchmaking","start_game","set_cards","add_enemy_cards","start_round","enable_cards","remove_card","move_my_card","card_effect","round_over","play_animation","game_won","get_player","buddy_request","buddy_accept","buddy_reject","buddy_request_seen","get_buddy","send_postcard","stamps_result","ignore_add","ignore_remove","add_item","get_postcards","get_igloo_open","get_igloos","get_igloo_likes","join_igloo","get_puffles","get_mascots","wait_queue_update","slot","snowball","send_safe","stop_walking","update_table","transform_player","adopt_puffle","info","queue_server_join","disconnect","unknown_packet"]);function I(c){return typeof c=="object"&&c!==null&&"action"in c&&"args"in c}var C=class extends ve{player=null;room=null;users=new Map;connected=!1;adapter;loginResult=null;log=null;_cardJitsu=null;get cardJitsu(){return this._cardJitsu||(this._cardJitsu=new R(this.adapter,this.waitFor.bind(this))),this._cardJitsu}constructor(e,r){super(),this.adapter=B(e),r?.debug&&(this.log=typeof r.debug=="function"?r.debug:console.log.bind(console))}async login(e){return this.log?.("[login] logging in as",e.username),this.loginResult=await this.adapter.login(e),this.log?.("[login] success \u2014",this.loginResult.servers.length,"servers"),this.loginResult.servers}async connect(e,r){if(!this.loginResult)throw new Error("Must call login() first");this.log?.("[connect] joining",e);let o={...r,onQueueUpdate:t=>{this.log?.("[queue]",`#${t.position}/${t.queueLength}`),this.emit("wait_queue_update",t),r?.onQueueUpdate?.(t)}},s=await this.adapter.connect(e,this.loginResult,o);s.on("message",t=>{I(t)&&this.handleMessage(t)}),s.on("disconnect",()=>{this.log?.("[disconnect] connection lost"),this.cleanup(),this.emit("disconnect")}),await new Promise((t,n)=>{let i=setTimeout(()=>{n(new Error("Waiting for load_player timed out"))},1e4),a=!1,u=!1,m=()=>{a&&u&&(clearTimeout(i),this.connected=!0,t())},l=p=>{if(I(p))switch(p.action){case"load_player":a=!0,m();break;case"join_room":u=!0,m();break;case"kick":clearTimeout(i),s.off("message",l),n(new Error(`Kicked: ${p.args.reason??"unknown"}`));break;case"close_with_error":clearTimeout(i),s.off("message",l),n(new Error(`Kicked: ${p.args.error??"unknown"}`));break;case"error":clearTimeout(i),s.off("message",l),n(new Error(`Server error: ${p.args.error??"unknown"}`));break}},h=()=>{(!a||!u)&&(clearTimeout(i),n(new Error("Disconnected before fully loaded")))};s.on("message",l),s.once("disconnect",h)})}on(e,r){return super.on(e,r)}off(e,r){return super.off(e,r)}once(e,r){return super.once(e,r)}emit(e,...r){return super.emit(e,...r)}waitFor(e,r){return new Promise((o,s)=>{let t,n=()=>{t&&clearTimeout(t),this.off(e,i),this.off("disconnect",a)},i=(u=>{n(),o(u)}),a=()=>{n(),s(new Error(`Disconnected while waiting for ${String(e)}`))};r!==void 0&&(t=setTimeout(()=>{n(),s(new Error(`Timed out waiting for ${String(e)}`))},r)),this.once(e,i),this.once("disconnect",a)})}sendMessage(e){this.adapter.sendMessage(e)}sendEmote(e){this.adapter.sendEmote(e)}sendSafe(e){this.adapter.sendSafe(e)}walk(e,r){this.adapter.walk(e,r)}sendFrame(e,r){this.adapter.sendFrame(e,r)}snowball(e,r){this.adapter.snowball(e,r)}joinRoom(e,r,o){return this.adapter.joinRoom(e,r,o),this.waitFor("join_room")}addItem(e){return this.adapter.addItem(e),this.waitFor("add_item")}equipColor(e){this.adapter.equipColor(e)}equipHead(e){this.adapter.equipHead(e)}equipFace(e){this.adapter.equipFace(e)}equipNeck(e){this.adapter.equipNeck(e)}equipBody(e){this.adapter.equipBody(e)}equipHand(e){this.adapter.equipHand(e)}equipFeet(e){this.adapter.equipFeet(e)}equipFlag(e){this.adapter.equipFlag(e)}equipPhoto(e){this.adapter.equipPhoto(e)}buddyRequest(e){this.adapter.buddyRequest(e)}buddyAccept(e){return this.adapter.buddyAccept(e),this.waitFor("buddy_accept")}buddyReject(e){return this.adapter.buddyReject(e),this.waitFor("buddy_reject")}buddyRequestSeen(e){return this.adapter.buddyRequestSeen(e),this.waitFor("buddy_request_seen")}getBuddy(e,r){return this.adapter.getBuddy(e,r),this.waitFor("get_buddy")}removeBuddy(e){this.adapter.removeBuddy(e)}addIgnore(e){return this.adapter.addIgnore(e),this.waitFor("ignore_add")}removeIgnore(e){return this.adapter.removeIgnore(e),this.waitFor("ignore_remove")}getPlayer(e){return this.adapter.getPlayer(e),this.waitFor("get_player")}getAllSlots(){return this.adapter.getAllSlots(),this.waitFor("slot")}getMascots(){return this.adapter.getMascots(),this.waitFor("get_mascots")}sendPostcard(e,r){return this.adapter.sendPostcard(e,r),this.waitFor("send_postcard")}getStamps(e){return this.adapter.getStamps(e),this.waitFor("stamps_result")}getPostcards(){return this.adapter.getPostcards(),this.waitFor("get_postcards")}getIglooOpen(e){return this.adapter.getIglooOpen(e),this.waitFor("get_igloo_open")}getIgloos(){return this.adapter.getIgloos(),this.waitFor("get_igloos")}getPuffles(e){return this.adapter.getPuffles(e),this.waitFor("get_puffles")}adoptPuffle(e,r){return this.adapter.adoptPuffle(e,r),this.waitFor("adopt_puffle")}getIglooLikes(){return this.adapter.getIglooLikes(),this.waitFor("get_igloo_likes")}checkPuffleSprite(e){this.adapter.checkPuffleSprite(e)}joinIgloo(e,r,o){return this.adapter.joinIgloo(e,r,o),this.waitFor("join_igloo")}gameOver(e){return this.adapter.gameOver(e),this.waitFor("game_over")}collectStamp(e){return this.adapter.collectStamp(e),this.waitFor("stamp_earned")}sleep(e){return new Promise(r=>setTimeout(r,e))}disconnect(){this.log?.("[disconnect] closing connection"),this.adapter.disconnect(),this.cleanup()}cleanup(){this.connected=!1,this.player=null,this.room=null,this.users.clear()}handleMessage(e){let{action:r,args:o}=e,s=o;switch(r){case"load_player":{let n=this.adapter.normalizePlayer(o);this.player=n,s={user:n},this.log?.("[load_player]",n.username,`id=${n.id}`,`coins=${n.coins}`,`inventory=${n.inventory.length}`);break}case"join_room":{let n=o.room,i=o.users;this.room=n,this.users.clear();let a=[];for(let u of i){let m=this.adapter.normalizeUser(u);this.users.set(m.id,m),a.push(m)}s={room:n,users:a},this.log?.("[join_room]",`room=${n}`,`users=${a.length}`);break}case"add_player":{let n=this.adapter.normalizeUser(o.user);this.users.set(n.id,n),s={user:n},this.log?.("[add_player]",n.username,`id=${n.id}`);break}case"remove_player":{let n=o.user;this.users.delete(n),this.log?.("[remove_player]",`id=${n}`);break}case"send_position":{let n=o.id,i=this.users.get(n);i&&(i.x=o.x,i.y=o.y);break}case"send_frame":{let n=o.id,i=this.users.get(n);i&&(i.frame=o.frame);break}case"join_igloo":{let n=o.igloo,i=o.users;this.room=n,this.users.clear();let a=[];for(let u of i){let m=this.adapter.normalizeUser(u);this.users.set(m.id,m),a.push(m)}s={...o,users:a},this.log?.("[join_igloo]",`igloo=${n}`,`users=${a.length}`);break}case"update_player":{let n=o.id,i=o.slot,a=o.item,u=this.users.get(n);u&&i in u&&(u[i]=a);break}case"kick":{let n=o.reason??"unknown";this.log?.("[kick]",n),this.cleanup();break}case"close_with_error":{let n=o.error??"unknown";this.log?.("[kick]",n),this.cleanup();break}default:{be.has(r)||(this.log?.("[unknown_packet]",r,JSON.stringify(o)),this.emit("unknown_packet",{action:r,args:o}));break}}let t=r==="error"?"server_error":r;this.emit(t,s)}};export{b as BaseAdapter,R as CardJitsu,C as Client};
|
|
2
2
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/adapters/base-adapter.ts","../src/client.ts","../src/adapters/cpjourney-adapter.ts","../src/adapters/cplegacy-adapter.ts","../src/adapters/cpzero-adapter.ts","../src/adapters/newcp-adapter.ts","../src/adapters/penguinorigins-adapter.ts","../src/adapters/index.ts","../src/games/card-jitsu.ts"],"sourcesContent":["import type { Socket } from \"socket.io-client\";\nimport type {\n LoginOptions,\n LoginResult,\n QueueUpdate,\n TokenLoginOptions,\n} from \"../types/adapter-types.js\";\nimport type {\n PlayerAppearance,\n PlayerData,\n RoomUser,\n} from \"../types/player-types.js\";\n\nexport type ConnectOptions = {\n onQueueUpdate?: (update: QueueUpdate) => void;\n};\n\nexport abstract class BaseAdapter {\n abstract readonly id: string;\n protected socket: Socket | null = null;\n\n abstract login(\n options: LoginOptions | TokenLoginOptions,\n ): Promise<LoginResult>;\n abstract connect(\n serverName: string,\n loginResult: LoginResult,\n options?: ConnectOptions,\n ): Promise<Socket>;\n abstract disconnect(): void;\n abstract send(action: string, args: Record<string, unknown>): void;\n\n normalizeUser(_raw: Record<string, unknown>): RoomUser {\n throw new Error(\"Not implemented: normalizeUser\");\n }\n\n normalizePlayer(_raw: Record<string, unknown>): PlayerData {\n throw new Error(\"Not implemented: normalizePlayer\");\n }\n\n protected extractAppearance(raw: Record<string, unknown>): PlayerAppearance {\n return {\n color: (raw.color as number) ?? 0,\n head: (raw.head as number) ?? 0,\n face: (raw.face as number) ?? 0,\n neck: (raw.neck as number) ?? 0,\n body: (raw.body as number) ?? 0,\n hand: (raw.hand as number) ?? 0,\n feet: (raw.feet as number) ?? 0,\n flag: (raw.flag as number) ?? 0,\n photo: (raw.photo as number) ?? 0,\n };\n }\n\n sendMessage(_message: string): void {\n throw new Error(\"Not implemented: sendMessage\");\n }\n\n sendEmote(_emote: number): void {\n throw new Error(\"Not implemented: sendEmote\");\n }\n\n sendSafe(_safe: number): void {\n throw new Error(\"Not implemented: sendSafe\");\n }\n\n walk(_x: number, _y: number): void {\n throw new Error(\"Not implemented: walk\");\n }\n\n sendFrame(_frame: number, _set?: boolean): void {\n throw new Error(\"Not implemented: sendFrame\");\n }\n\n snowball(_x: number, _y: number): void {\n throw new Error(\"Not implemented: snowball\");\n }\n\n joinRoom(_room: number, _x?: number, _y?: number): void {\n throw new Error(\"Not implemented: joinRoom\");\n }\n\n addItem(_item: number): void {\n throw new Error(\"Not implemented: addItem\");\n }\n\n equipColor(_item: number): void {\n throw new Error(\"Not implemented: equipColor\");\n }\n\n equipHead(_item: number): void {\n throw new Error(\"Not implemented: equipHead\");\n }\n\n equipFace(_item: number): void {\n throw new Error(\"Not implemented: equipFace\");\n }\n\n equipNeck(_item: number): void {\n throw new Error(\"Not implemented: equipNeck\");\n }\n\n equipBody(_item: number): void {\n throw new Error(\"Not implemented: equipBody\");\n }\n\n equipHand(_item: number): void {\n throw new Error(\"Not implemented: equipHand\");\n }\n\n equipFeet(_item: number): void {\n throw new Error(\"Not implemented: equipFeet\");\n }\n\n equipFlag(_item: number): void {\n throw new Error(\"Not implemented: equipFlag\");\n }\n\n equipPhoto(_item: number): void {\n throw new Error(\"Not implemented: equipPhoto\");\n }\n\n buddyRequest(_id: number): void {\n throw new Error(\"Not implemented: buddyRequest\");\n }\n\n buddyAccept(_id: number): void {\n throw new Error(\"Not implemented: buddyAccept\");\n }\n\n buddyReject(_id: number): void {\n throw new Error(\"Not implemented: buddyReject\");\n }\n\n buddyRequestSeen(_id: number): void {\n throw new Error(\"Not implemented: buddyRequestSeen\");\n }\n\n getBuddy(_id: number, _type: \"buddies\" | \"buddyRequests\"): void {\n throw new Error(\"Not implemented: getBuddy\");\n }\n\n removeBuddy(_id: number): void {\n throw new Error(\"Not implemented: removeBuddy\");\n }\n\n addIgnore(_id: number): void {\n throw new Error(\"Not implemented: addIgnore\");\n }\n\n removeIgnore(_id: number): void {\n throw new Error(\"Not implemented: removeIgnore\");\n }\n\n getPlayer(_id: number): void {\n throw new Error(\"Not implemented: getPlayer\");\n }\n\n getAllSlots(): void {\n throw new Error(\"Not implemented: getAllSlots\");\n }\n\n getMascots(): void {\n throw new Error(\"Not implemented: getMascots\");\n }\n\n sendPostcard(_userId: number, _cardId: string): void {\n throw new Error(\"Not implemented: sendPostcard\");\n }\n\n getStamps(_userId: number): void {\n throw new Error(\"Not implemented: getStamps\");\n }\n\n getPostcards(): void {\n throw new Error(\"Not implemented: getPostcards\");\n }\n\n getIglooOpen(_igloo: number): void {\n throw new Error(\"Not implemented: getIglooOpen\");\n }\n\n getIgloos(): void {\n throw new Error(\"Not implemented: getIgloos\");\n }\n\n getPuffles(_userId: number): void {\n throw new Error(\"Not implemented: getPuffles\");\n }\n\n getIglooLikes(): void {\n throw new Error(\"Not implemented: getIglooLikes\");\n }\n\n joinIgloo(_igloo: number, _x?: number, _y?: number): void {\n throw new Error(\"Not implemented: joinIgloo\");\n }\n\n gameOver(_coins: number): void {\n throw new Error(\"Not implemented: gameOver\");\n }\n\n collectStamp(_stamp: number): void {\n throw new Error(\"Not implemented: collectStamp\");\n }\n\n /** Fetch ninja rank, progress, and card deck. Listen for `get_ninja` event. */\n getNinja(): void {\n throw new Error(\"Not implemented: getNinja\");\n }\n\n /** Fetch state of all Dojo mats. Listen for `get_waddles` event. */\n getMats(): void {\n throw new Error(\"Not implemented: getMats\");\n }\n\n /** Join Sensei matchmaking queue. Listen for `tick_matchmaking` events. */\n joinMatchmaking(): void {\n throw new Error(\"Not implemented: joinMatchmaking\");\n }\n\n /** Leave Sensei matchmaking queue. */\n leaveMatchmaking(): void {\n throw new Error(\"Not implemented: leaveMatchmaking\");\n }\n\n /** Start a Card-Jitsu match after entering a game room. Listen for `start_game` event. */\n startGame(): void {\n throw new Error(\"Not implemented: startGame\");\n }\n\n /** Play a card from your hand by slot index. Listen for `move_my_card` event. */\n selectCard(_slot: number): void {\n throw new Error(\"Not implemented: selectCard\");\n }\n\n /** Preload a power card animation asset. */\n loadAnimation(_animation: string): void {\n throw new Error(\"Not implemented: loadAnimation\");\n }\n\n /** Sit on a Dojo mat to wait for an opponent. Listen for `update_waddle` events. */\n joinMat(_waddle: number): void {\n throw new Error(\"Not implemented: joinMat\");\n }\n}\n","import { EventEmitter } from \"node:events\";\nimport type { BaseAdapter, ConnectOptions } from \"./adapters/base-adapter.js\";\nimport { type AdapterName, createAdapter } from \"./adapters/index.js\";\nimport { CardJitsu } from \"./games/card-jitsu.js\";\nimport type {\n LoginOptions,\n LoginResult,\n QueueUpdate,\n ServerInfo,\n TokenLoginOptions,\n} from \"./types/adapter-types.js\";\nimport type { ServerMessages } from \"./types/message-types.js\";\nimport type { PlayerData, RoomUser } from \"./types/player-types.js\";\n\n/** Actions with explicit switch-case handling or typed in ServerMessages — not truly unknown. */\nconst KNOWN_ACTIONS = new Set<string>([\n\t// Handled in switch\n\t\"load_player\", \"join_room\", \"add_player\", \"remove_player\",\n\t\"send_position\", \"send_frame\", \"update_player\", \"kick\", \"close_with_error\",\n\t// Typed passthrough (emitted as-is, no state updates needed)\n\t\"send_message\", \"send_emote\", \"cpj_ping\", \"open_sprite\", \"close_sprite\",\n\t\"set_weather\", \"server_error\", \"error\", \"stamp_earned\", \"game_over\",\n\t\"join_game_room\", \"get_ninja\", \"get_waddles\", \"update_waddle\",\n\t\"join_matchmaking\", \"tick_matchmaking\", \"start_game\", \"set_cards\",\n\t\"add_enemy_cards\", \"start_round\", \"enable_cards\", \"remove_card\",\n\t\"move_my_card\", \"card_effect\", \"round_over\", \"play_animation\", \"game_won\",\n\t\"get_player\", \"buddy_request\", \"buddy_accept\", \"buddy_reject\",\n\t\"buddy_request_seen\", \"get_buddy\", \"send_postcard\", \"stamps_result\",\n\t\"ignore_add\", \"ignore_remove\", \"add_item\", \"get_postcards\",\n\t\"get_igloo_open\", \"get_igloos\", \"get_igloo_likes\", \"join_igloo\", \"get_puffles\",\n\t\"get_mascots\", \"wait_queue_update\", \"slot\",\n\t\"snowball\", \"send_safe\", \"stop_walking\", \"update_table\", \"transform_player\",\n\t\"queue_server_join\",\n\t\"disconnect\", \"unknown_packet\",\n]);\n\ntype ServerMessageHandler<K extends keyof ServerMessages> = (\n args: ServerMessages[K],\n) => void;\n\nexport type LogFn = (message: string, ...args: unknown[]) => void;\n\nexport type ClientOptions = {\n debug?: boolean | LogFn;\n};\n\ntype MessagePayload = {\n action: string;\n args: Record<string, unknown>;\n};\n\nfunction isMessagePayload(msg: unknown): msg is MessagePayload {\n return (\n typeof msg === \"object\" && msg !== null && \"action\" in msg && \"args\" in msg\n );\n}\n\nexport class Client extends EventEmitter {\n player: PlayerData | null = null;\n room: number | null = null;\n users: Map<number, RoomUser> = new Map();\n connected = false;\n\n private adapter: BaseAdapter;\n private loginResult: LoginResult | null = null;\n private log: LogFn | null = null;\n private _cardJitsu: CardJitsu | null = null;\n\n get cardJitsu(): CardJitsu {\n if (!this._cardJitsu)\n this._cardJitsu = new CardJitsu(this.adapter, this.waitFor.bind(this));\n return this._cardJitsu;\n }\n\n constructor(server: AdapterName, options?: ClientOptions) {\n super();\n this.adapter = createAdapter(server);\n\n if (options?.debug) {\n this.log =\n typeof options.debug === \"function\"\n ? options.debug\n : console.log.bind(console);\n }\n }\n\n async login(\n options: LoginOptions | TokenLoginOptions,\n ): Promise<ServerInfo[]> {\n this.log?.(\"[login] logging in as\", options.username);\n this.loginResult = await this.adapter.login(options);\n this.log?.(\"[login] success —\", this.loginResult.servers.length, \"servers\");\n return this.loginResult.servers;\n }\n\n async connect(serverName: string, options?: ConnectOptions): Promise<void> {\n if (!this.loginResult) throw new Error(\"Must call login() first\");\n\n this.log?.(\"[connect] joining\", serverName);\n\n const connectOptions: ConnectOptions = {\n ...options,\n onQueueUpdate: (update: QueueUpdate) => {\n this.log?.(\"[queue]\", `#${update.position}/${update.queueLength}`);\n this.emit(\"wait_queue_update\", update);\n options?.onQueueUpdate?.(update);\n },\n };\n\n const socket = await this.adapter.connect(\n serverName,\n this.loginResult,\n connectOptions,\n );\n\n socket.on(\"message\", (msg: unknown) => {\n if (!isMessagePayload(msg)) return;\n this.handleMessage(msg);\n });\n\n socket.on(\"disconnect\", () => {\n this.log?.(\"[disconnect] connection lost\");\n this.cleanup();\n this.emit(\"disconnect\");\n });\n\n await new Promise<void>((resolve, reject) => {\n const timeout = setTimeout(() => {\n reject(new Error(\"Waiting for load_player timed out\"));\n }, 10_000);\n\n let playerLoaded = false;\n let roomJoined = false;\n\n const checkReady = (): void => {\n if (playerLoaded && roomJoined) {\n clearTimeout(timeout);\n this.connected = true;\n resolve();\n }\n };\n\n const onMessage = (msg: unknown): void => {\n if (!isMessagePayload(msg)) return;\n switch (msg.action) {\n case \"load_player\":\n playerLoaded = true;\n checkReady();\n break;\n case \"join_room\":\n roomJoined = true;\n checkReady();\n break;\n case \"kick\":\n clearTimeout(timeout);\n socket.off(\"message\", onMessage);\n reject(\n new Error(\n `Kicked: ${(msg.args as { reason?: string }).reason ?? \"unknown\"}`,\n ),\n );\n break;\n case \"close_with_error\":\n clearTimeout(timeout);\n socket.off(\"message\", onMessage);\n reject(\n new Error(\n `Kicked: ${(msg.args as { error?: string }).error ?? \"unknown\"}`,\n ),\n );\n break;\n case \"error\":\n clearTimeout(timeout);\n socket.off(\"message\", onMessage);\n reject(\n new Error(\n `Server error: ${(msg.args as { error?: string | number }).error ?? \"unknown\"}`,\n ),\n );\n break;\n }\n };\n\n const onDisconnect = (): void => {\n if (!playerLoaded || !roomJoined) {\n clearTimeout(timeout);\n reject(new Error(\"Disconnected before fully loaded\"));\n }\n };\n\n socket.on(\"message\", onMessage);\n socket.once(\"disconnect\", onDisconnect);\n });\n }\n\n on<K extends keyof ServerMessages>(\n event: K,\n listener: ServerMessageHandler<K>,\n ): this;\n on(event: string, listener: (...args: unknown[]) => void): this;\n on(event: string, listener: (...args: unknown[]) => void): this {\n return super.on(event, listener);\n }\n\n off<K extends keyof ServerMessages>(\n event: K,\n listener: ServerMessageHandler<K>,\n ): this;\n off(event: string, listener: (...args: unknown[]) => void): this;\n off(event: string, listener: (...args: unknown[]) => void): this {\n return super.off(event, listener);\n }\n\n once<K extends keyof ServerMessages>(\n event: K,\n listener: ServerMessageHandler<K>,\n ): this;\n once(event: string, listener: (...args: unknown[]) => void): this;\n once(event: string, listener: (...args: unknown[]) => void): this {\n return super.once(event, listener);\n }\n\n emit<K extends keyof ServerMessages>(\n event: K,\n args: ServerMessages[K],\n ): boolean;\n emit(event: string, ...args: unknown[]): boolean;\n emit(event: string, ...args: unknown[]): boolean {\n return super.emit(event, ...args);\n }\n\n /** Wait for a server event. Resolves with the event payload. Optional timeout in ms. Rejects on disconnect. */\n waitFor<K extends keyof ServerMessages>(\n event: K,\n timeout?: number,\n ): Promise<ServerMessages[K]> {\n return new Promise<ServerMessages[K]>((resolve, reject) => {\n let timer: ReturnType<typeof setTimeout> | undefined;\n\n const cleanup = (): void => {\n if (timer) clearTimeout(timer);\n this.off(event, handler as unknown as (...args: unknown[]) => void);\n this.off(\"disconnect\", onDisconnect);\n };\n\n const handler = ((args: ServerMessages[K]) => {\n cleanup();\n resolve(args);\n }) as ServerMessageHandler<K>;\n\n const onDisconnect = (): void => {\n cleanup();\n reject(new Error(`Disconnected while waiting for ${String(event)}`));\n };\n\n if (timeout !== undefined) {\n timer = setTimeout(() => {\n cleanup();\n reject(new Error(`Timed out waiting for ${String(event)}`));\n }, timeout);\n }\n\n this.once(event, handler);\n this.once(\"disconnect\", onDisconnect);\n });\n }\n\n sendMessage(message: string): void {\n this.adapter.sendMessage(message);\n }\n sendEmote(emote: number): void {\n this.adapter.sendEmote(emote);\n }\n sendSafe(safe: number): void {\n this.adapter.sendSafe(safe);\n }\n walk(x: number, y: number): void {\n this.adapter.walk(x, y);\n }\n sendFrame(frame: number, set?: boolean): void {\n this.adapter.sendFrame(frame, set);\n }\n snowball(x: number, y: number): void {\n this.adapter.snowball(x, y);\n }\n joinRoom(\n room: number,\n x?: number,\n y?: number,\n ): Promise<ServerMessages[\"join_room\"]> {\n this.adapter.joinRoom(room, x, y);\n return this.waitFor(\"join_room\");\n }\n addItem(item: number): Promise<ServerMessages[\"add_item\"]> {\n this.adapter.addItem(item);\n return this.waitFor(\"add_item\");\n }\n equipColor(item: number): void {\n this.adapter.equipColor(item);\n }\n equipHead(item: number): void {\n this.adapter.equipHead(item);\n }\n equipFace(item: number): void {\n this.adapter.equipFace(item);\n }\n equipNeck(item: number): void {\n this.adapter.equipNeck(item);\n }\n equipBody(item: number): void {\n this.adapter.equipBody(item);\n }\n equipHand(item: number): void {\n this.adapter.equipHand(item);\n }\n equipFeet(item: number): void {\n this.adapter.equipFeet(item);\n }\n equipFlag(item: number): void {\n this.adapter.equipFlag(item);\n }\n equipPhoto(item: number): void {\n this.adapter.equipPhoto(item);\n }\n buddyRequest(id: number): void {\n this.adapter.buddyRequest(id);\n }\n buddyAccept(id: number): Promise<ServerMessages[\"buddy_accept\"]> {\n this.adapter.buddyAccept(id);\n return this.waitFor(\"buddy_accept\");\n }\n buddyReject(id: number): Promise<ServerMessages[\"buddy_reject\"]> {\n this.adapter.buddyReject(id);\n return this.waitFor(\"buddy_reject\");\n }\n buddyRequestSeen(id: number): Promise<ServerMessages[\"buddy_request_seen\"]> {\n this.adapter.buddyRequestSeen(id);\n return this.waitFor(\"buddy_request_seen\");\n }\n getBuddy(\n id: number,\n type: \"buddies\" | \"buddyRequests\",\n ): Promise<ServerMessages[\"get_buddy\"]> {\n this.adapter.getBuddy(id, type);\n return this.waitFor(\"get_buddy\");\n }\n removeBuddy(id: number): void {\n this.adapter.removeBuddy(id);\n }\n addIgnore(id: number): Promise<ServerMessages[\"ignore_add\"]> {\n this.adapter.addIgnore(id);\n return this.waitFor(\"ignore_add\");\n }\n removeIgnore(id: number): Promise<ServerMessages[\"ignore_remove\"]> {\n this.adapter.removeIgnore(id);\n return this.waitFor(\"ignore_remove\");\n }\n getPlayer(id: number): Promise<ServerMessages[\"get_player\"]> {\n this.adapter.getPlayer(id);\n return this.waitFor(\"get_player\");\n }\n getAllSlots(): Promise<ServerMessages[\"slot\"]> {\n this.adapter.getAllSlots();\n return this.waitFor(\"slot\");\n }\n getMascots(): Promise<ServerMessages[\"get_mascots\"]> {\n this.adapter.getMascots();\n return this.waitFor(\"get_mascots\");\n }\n sendPostcard(\n userId: number,\n cardId: string,\n ): Promise<ServerMessages[\"send_postcard\"]> {\n this.adapter.sendPostcard(userId, cardId);\n return this.waitFor(\"send_postcard\");\n }\n getStamps(userId: number): Promise<ServerMessages[\"stamps_result\"]> {\n this.adapter.getStamps(userId);\n return this.waitFor(\"stamps_result\");\n }\n getPostcards(): Promise<ServerMessages[\"get_postcards\"]> {\n this.adapter.getPostcards();\n return this.waitFor(\"get_postcards\");\n }\n getIglooOpen(igloo: number): Promise<ServerMessages[\"get_igloo_open\"]> {\n this.adapter.getIglooOpen(igloo);\n return this.waitFor(\"get_igloo_open\");\n }\n getIgloos(): Promise<ServerMessages[\"get_igloos\"]> {\n this.adapter.getIgloos();\n return this.waitFor(\"get_igloos\");\n }\n getPuffles(userId: number): Promise<ServerMessages[\"get_puffles\"]> {\n this.adapter.getPuffles(userId);\n return this.waitFor(\"get_puffles\");\n }\n getIglooLikes(): Promise<ServerMessages[\"get_igloo_likes\"]> {\n this.adapter.getIglooLikes();\n return this.waitFor(\"get_igloo_likes\");\n }\n joinIgloo(\n igloo: number,\n x?: number,\n y?: number,\n ): Promise<ServerMessages[\"join_igloo\"]> {\n this.adapter.joinIgloo(igloo, x, y);\n return this.waitFor(\"join_igloo\");\n }\n gameOver(coins: number): Promise<ServerMessages[\"game_over\"]> {\n this.adapter.gameOver(coins);\n return this.waitFor(\"game_over\");\n }\n collectStamp(stamp: number): Promise<ServerMessages[\"stamp_earned\"]> {\n this.adapter.collectStamp(stamp);\n return this.waitFor(\"stamp_earned\");\n }\n\n sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n }\n\n disconnect(): void {\n this.log?.(\"[disconnect] closing connection\");\n this.adapter.disconnect();\n this.cleanup();\n }\n\n private cleanup(): void {\n this.connected = false;\n this.player = null;\n this.room = null;\n this.users.clear();\n }\n\n private handleMessage(msg: MessagePayload): void {\n const { action, args } = msg;\n let emitArgs: unknown = args;\n\n switch (action) {\n case \"load_player\": {\n const player = this.adapter.normalizePlayer(args);\n this.player = player;\n emitArgs = { user: player };\n this.log?.(\n \"[load_player]\",\n player.username,\n `id=${player.id}`,\n `coins=${player.coins}`,\n `inventory=${player.inventory.length}`,\n );\n break;\n }\n case \"join_room\": {\n const room = args.room as number;\n const rawUsers = args.users as Record<string, unknown>[];\n this.room = room;\n this.users.clear();\n const users: RoomUser[] = [];\n for (const rawUser of rawUsers) {\n const user = this.adapter.normalizeUser(rawUser);\n this.users.set(user.id, user);\n users.push(user);\n }\n emitArgs = { room, users };\n this.log?.(\"[join_room]\", `room=${room}`, `users=${users.length}`);\n break;\n }\n case \"add_player\": {\n const user = this.adapter.normalizeUser(\n args.user as Record<string, unknown>,\n );\n this.users.set(user.id, user);\n emitArgs = { user };\n this.log?.(\"[add_player]\", user.username, `id=${user.id}`);\n break;\n }\n case \"remove_player\": {\n const id = args.user as number;\n this.users.delete(id);\n this.log?.(\"[remove_player]\", `id=${id}`);\n break;\n }\n case \"send_position\": {\n const id = args.id as number;\n const user = this.users.get(id);\n if (user) {\n user.x = args.x as number;\n user.y = args.y as number;\n }\n break;\n }\n case \"send_frame\": {\n const id = args.id as number;\n const user = this.users.get(id);\n if (user) {\n user.frame = args.frame as number;\n }\n break;\n }\n case \"join_igloo\": {\n const igloo = args.igloo as number;\n const rawUsers = args.users as Record<string, unknown>[];\n this.room = igloo;\n this.users.clear();\n const iglooUsers: RoomUser[] = [];\n for (const rawUser of rawUsers) {\n const user = this.adapter.normalizeUser(rawUser);\n this.users.set(user.id, user);\n iglooUsers.push(user);\n }\n emitArgs = { ...args, users: iglooUsers };\n this.log?.(\"[join_igloo]\", `igloo=${igloo}`, `users=${iglooUsers.length}`);\n break;\n }\n case \"update_player\": {\n const id = args.id as number;\n const slot = args.slot as string;\n const item = args.item as number;\n const user = this.users.get(id);\n if (user && slot in user) {\n (user as Record<string, unknown>)[slot] = item;\n }\n break;\n }\n case \"kick\": {\n const reason = (args as { reason?: string }).reason ?? \"unknown\";\n this.log?.(\"[kick]\", reason);\n this.cleanup();\n break;\n }\n case \"close_with_error\": {\n const error = (args as { error?: string }).error ?? \"unknown\";\n this.log?.(\"[kick]\", error);\n this.cleanup();\n break;\n }\n default: {\n if (!KNOWN_ACTIONS.has(action)) {\n this.log?.(`[unknown_packet]`, action, JSON.stringify(args));\n this.emit(\"unknown_packet\", { action, args });\n }\n break;\n }\n }\n\n const eventName = action === \"error\" ? \"server_error\" : action;\n this.emit(eventName, emitArgs);\n }\n}\n","import { io, type Socket } from \"socket.io-client\";\nimport msgpackParser from \"socket.io-msgpack-parser\";\nimport type {\n LoginOptions,\n LoginResult,\n QueueUpdate,\n ServerInfo,\n TokenLoginOptions,\n} from \"../types/adapter-types.js\";\nimport type { Buddy, PlayerData, RoomUser } from \"../types/player-types.js\";\nimport { BaseAdapter, type ConnectOptions } from \"./base-adapter.js\";\n\nconst BASE_URL = \"wss://play.cpjourney.net\";\nconst DEFAULT_SECRET = \"skip\";\n\ntype LoginResponse = {\n success: boolean;\n username: string;\n key: string;\n populations: Record<string, number>;\n moderator: boolean;\n buddyWorlds: string[];\n};\n\ntype GameAuthResponse = {\n success: boolean;\n token?: string;\n};\n\ntype ServerMessage = {\n action: string;\n args: Record<string, unknown>;\n};\n\nexport class CpjourneyAdapter extends BaseAdapter {\n readonly id = \"CPJourney\";\n\n async login(options: LoginOptions | TokenLoginOptions): Promise<LoginResult> {\n const loginSocket = this.createSocket(\"/world/login/\");\n\n const result = await new Promise<LoginResult>((resolve, reject) => {\n const timeout = setTimeout(() => {\n loginSocket.disconnect();\n reject(new Error(\"Login timed out\"));\n }, 10_000);\n\n loginSocket.on(\"connect\", () => {\n const secret = options.secret ?? DEFAULT_SECRET;\n const args =\n \"token\" in options\n ? { username: options.username, token: options.token, secret }\n : {\n username: options.username,\n password: options.password,\n secret,\n };\n\n loginSocket.emit(\"message\", { action: \"login\", args });\n });\n\n loginSocket.on(\"message\", (msg: ServerMessage) => {\n if (msg.action !== \"login\") return;\n\n clearTimeout(timeout);\n loginSocket.disconnect();\n\n const response = msg.args as LoginResponse;\n\n if (!response.success) {\n reject(new Error(\"Login failed\"));\n return;\n }\n\n const servers: ServerInfo[] = Object.entries(response.populations).map(\n ([name, population]) => ({ name, population }),\n );\n\n resolve({\n servers,\n key: response.key,\n username: response.username,\n moderator: response.moderator,\n buddyWorlds: response.buddyWorlds ?? [],\n });\n });\n\n loginSocket.on(\"connect_error\", (err: Error) => {\n clearTimeout(timeout);\n loginSocket.disconnect();\n reject(new Error(`Login connection failed: ${err.message}`));\n });\n });\n\n return result;\n }\n\n async connect(\n serverName: string,\n loginResult: LoginResult,\n options?: ConnectOptions,\n ): Promise<Socket> {\n // Queue step on a fresh login socket (matches browser flow).\n // The original login socket is dead — server disconnects after login response.\n await this.queueForServer(serverName, options);\n\n // Connect game socket — still needs game_auth in Node.js\n // (browser uses cookies from HTTP polling, not available cross-Manager)\n const gameSocket = this.createSocket(`/world/${serverName.toLowerCase()}/`);\n this.socket = gameSocket;\n\n await new Promise<void>((resolve, reject) => {\n let authSent = false;\n\n gameSocket.on(\"connect\", () => {\n gameSocket.emit(\"message\", {\n action: \"game_auth\",\n args: {\n username: loginResult.username,\n key: loginResult.key,\n createToken: false,\n joinInvis: false,\n takeoverMascot: false,\n token: \"\",\n },\n });\n });\n\n gameSocket.on(\"message\", (msg: ServerMessage) => {\n switch (msg.action) {\n case \"wait_queue_update\": {\n options?.onQueueUpdate?.(msg.args as QueueUpdate);\n break;\n }\n case \"game_auth\": {\n if (authSent) break;\n authSent = true;\n\n const response = msg.args as GameAuthResponse;\n if (!response.success) {\n gameSocket.disconnect();\n reject(new Error(\"Game auth failed\"));\n return;\n }\n\n gameSocket.emit(\"message\", {\n action: \"join_server\",\n args: {},\n });\n resolve();\n break;\n }\n }\n });\n\n gameSocket.on(\"connect_error\", (err: Error) => {\n gameSocket.disconnect();\n reject(new Error(`Game connection failed: ${err.message}`));\n });\n });\n\n return gameSocket;\n }\n\n private async queueForServer(\n serverName: string,\n options?: ConnectOptions,\n ): Promise<void> {\n const queueSocket = this.createSocket(\"/world/login/\");\n\n await new Promise<void>((resolve, reject) => {\n const timeout = setTimeout(() => {\n queueSocket.disconnect();\n reject(new Error(\"Queue timed out\"));\n }, 60_000);\n\n queueSocket.on(\"connect\", () => {\n queueSocket.emit(\"message\", {\n action: \"queue_server_join\",\n args: { server: serverName },\n });\n });\n\n queueSocket.on(\"message\", (msg: ServerMessage) => {\n switch (msg.action) {\n case \"wait_queue_update\":\n options?.onQueueUpdate?.(msg.args as QueueUpdate);\n break;\n case \"queue_server_join\":\n clearTimeout(timeout);\n queueSocket.disconnect();\n resolve();\n break;\n }\n });\n\n queueSocket.once(\"disconnect\", () => {\n clearTimeout(timeout);\n resolve();\n });\n\n queueSocket.on(\"connect_error\", (err: Error) => {\n clearTimeout(timeout);\n queueSocket.disconnect();\n reject(new Error(`Queue connection failed: ${err.message}`));\n });\n });\n }\n\n send(action: string, args: Record<string, unknown>): void {\n if (!this.socket) throw new Error(\"Not connected\");\n this.socket.emit(\"message\", { action, args });\n }\n\n disconnect(): void {\n this.socket?.disconnect();\n this.socket = null;\n }\n\n override normalizeUser(raw: Record<string, unknown>): RoomUser {\n const { id, username, displayName, joinTime, x, y, frame, walking,\n color, head, face, neck, body, hand, feet, flag, photo,\n ...rest } = raw;\n return {\n ...this.extractAppearance(raw),\n id: id as number,\n username: username as string,\n displayName: displayName as string | undefined,\n joinTime: joinTime as string | undefined,\n x: (x as number) ?? 0,\n y: (y as number) ?? 0,\n frame: (frame as number) ?? 0,\n walking: walking as number | undefined,\n meta: rest,\n _raw: raw,\n };\n }\n\n override normalizePlayer(raw: Record<string, unknown>): PlayerData {\n const user = raw.user as Record<string, unknown>;\n const normalized = this.normalizeUser(user);\n const { user: _user, coins, rank, inventory, furniture, flooring,\n buddies, buddyRequests, ignores, igloos, ...rest } = raw;\n return {\n ...normalized,\n _raw: raw,\n coins: (coins as number) ?? 0,\n rank: (rank as number) ?? 0,\n inventory: (inventory as number[]) ?? [],\n furniture: (furniture as unknown[]) ?? [],\n flooring: (flooring as unknown[]) ?? [],\n buddies: (user.buddies as Buddy[]) ?? [],\n buddyRequests: (user.buddyRequests as number[]) ?? [],\n ignores: (user.ignores as number[]) ?? [],\n igloos: (igloos as unknown[]) ?? [],\n meta: { ...normalized.meta, ...rest },\n };\n }\n\n override sendMessage(message: string): void {\n this.send(\"send_message\", { message });\n }\n\n override sendEmote(emote: number): void {\n this.send(\"send_emote\", { emote });\n }\n\n override sendSafe(safe: number): void {\n this.send(\"send_safe\", { safe });\n }\n\n override walk(x: number, y: number): void {\n this.send(\"send_position\", { x, y });\n }\n\n override sendFrame(frame: number, set?: boolean): void {\n this.send(\"send_frame\", { frame, set });\n }\n\n override snowball(x: number, y: number): void {\n this.send(\"snowball\", { x, y });\n }\n\n override joinRoom(room: number, x?: number, y?: number): void {\n this.send(\"join_room\", { room, x: x ?? 0, y: y ?? 0 });\n }\n\n override addItem(item: number): void {\n this.send(\"add_item\", { item });\n }\n\n override equipColor(item: number): void {\n this.send(\"update_color\", { item });\n }\n\n override equipHead(item: number): void {\n this.send(\"update_head\", { item });\n }\n\n override equipFace(item: number): void {\n this.send(\"update_face\", { item });\n }\n\n override equipNeck(item: number): void {\n this.send(\"update_neck\", { item });\n }\n\n override equipBody(item: number): void {\n this.send(\"update_body\", { item });\n }\n\n override equipHand(item: number): void {\n this.send(\"update_hand\", { item });\n }\n\n override equipFeet(item: number): void {\n this.send(\"update_feet\", { item });\n }\n\n override equipFlag(item: number): void {\n this.send(\"update_flag\", { item });\n }\n\n override equipPhoto(item: number): void {\n this.send(\"update_photo\", { item });\n }\n\n override buddyRequest(id: number): void {\n this.send(\"buddy_request\", { id });\n }\n\n override buddyAccept(id: number): void {\n this.send(\"buddy_accept\", { id });\n }\n\n override buddyReject(id: number): void {\n this.send(\"buddy_reject\", { id });\n }\n\n override buddyRequestSeen(id: number): void {\n this.send(\"buddy_request_seen\", { id });\n }\n\n override getBuddy(id: number, type: \"buddies\" | \"buddyRequests\"): void {\n this.send(\"get_buddy\", { id, type });\n }\n\n override removeBuddy(id: number): void {\n this.send(\"remove_buddy\", { id });\n }\n\n override addIgnore(id: number): void {\n this.send(\"ignore_add\", { id });\n }\n\n override removeIgnore(id: number): void {\n this.send(\"ignore_remove\", { id });\n }\n\n override getPlayer(id: number): void {\n this.send(\"get_player\", { id });\n }\n\n override getAllSlots(): void {\n this.send(\"get_all_slots\", {});\n }\n\n override getMascots(): void {\n this.send(\"get_mascots\", {});\n }\n\n override sendPostcard(userId: number, cardId: string): void {\n this.send(\"send_postcard\", { userId, cardId });\n }\n\n override getStamps(userId: number): void {\n this.send(\"get_stamps\", { userId });\n }\n\n override getPostcards(): void {\n this.send(\"get_postcards\", {});\n }\n\n override getIglooOpen(igloo: number): void {\n this.send(\"get_igloo_open\", { igloo });\n }\n\n override getIgloos(): void {\n this.send(\"get_igloos\", {});\n }\n\n override getPuffles(userId: number): void {\n this.send(\"get_puffles\", { userId });\n }\n\n override getIglooLikes(): void {\n this.send(\"get_igloo_likes\", {});\n }\n\n override joinIgloo(igloo: number, x?: number, y?: number): void {\n this.send(\"join_igloo\", { igloo, x: x ?? 0, y: y ?? 0 });\n }\n\n override gameOver(coins: number): void {\n this.send(\"game_over\", { coins });\n }\n\n override collectStamp(stamp: number): void {\n this.send(\"collect_stamp\", { stamp });\n }\n\n override getNinja(): void {\n this.send(\"get_ninja\", {});\n }\n\n override getMats(): void {\n this.send(\"get_waddles\", {});\n }\n\n override joinMatchmaking(): void {\n this.send(\"join_matchmaking\", {});\n }\n\n override leaveMatchmaking(): void {\n this.send(\"leave_matchmaking\", {});\n }\n\n override startGame(): void {\n this.send(\"start_game\", {});\n }\n\n override selectCard(slot: number): void {\n this.send(\"select_card\", { slot });\n }\n\n override loadAnimation(animation: string): void {\n this.send(\"load_animation\", { animation });\n }\n\n override joinMat(waddle: number): void {\n this.send(\"join_waddle\", { waddle });\n }\n\n private createSocket(path: string): Socket {\n return io(BASE_URL, {\n path,\n parser: msgpackParser,\n transports: [\"polling\", \"websocket\"],\n reconnection: false,\n });\n }\n}\n","import { io, type Socket } from \"socket.io-client\";\nimport msgpackParser from \"socket.io-msgpack-parser\";\nimport type {\n LoginOptions,\n LoginResult,\n QueueUpdate,\n ServerInfo,\n TokenLoginOptions,\n} from \"../types/adapter-types.js\";\nimport type { Buddy, PlayerData, RoomUser } from \"../types/player-types.js\";\nimport { BaseAdapter, type ConnectOptions } from \"./base-adapter.js\";\n\nconst LOGIN_URL = \"https://api.cplegacy.com/login\";\nconst TOKEN_LOGIN_URL = \"https://api.cplegacy.com/token_login\";\n\ntype LoginResponse = {\n success: boolean;\n username: string;\n key: string;\n populations: Record<string, number>;\n requires2FA: boolean;\n message?: string;\n wantedVersion?: string;\n};\n\ntype GameAuthResponse = {\n success: boolean;\n};\n\n/**\n * Wraps a CPLegacy socket to normalize its positional message format\n * `(\"message\", action, args)` into the `{ action, args }` envelope\n * that the Client class expects.\n */\nfunction wrapSocket(raw: Socket): Socket {\n const original = raw.on.bind(raw);\n\n raw.on = ((event: string, listener: (...args: unknown[]) => void) => {\n if (event === \"message\") {\n return original(event, (action: unknown, args: unknown) => {\n listener({ action, args: args ?? {} });\n });\n }\n return original(event, listener);\n }) as typeof raw.on;\n\n return raw;\n}\n\nexport class CplegacyAdapter extends BaseAdapter {\n readonly id = \"CPLegacy\";\n private version = \"\";\n\n async login(options: LoginOptions | TokenLoginOptions): Promise<LoginResult> {\n const url = \"token\" in options ? TOKEN_LOGIN_URL : LOGIN_URL;\n const body: Record<string, unknown> =\n \"token\" in options\n ? { username: options.username, token: options.token }\n : {\n username: options.username,\n password: options.password,\n version: this.version,\n };\n\n let data = await this.postLogin(url, body);\n\n // Version negotiation: server returns wantedVersion when ours is stale/empty\n if (!data.success && data.wantedVersion) {\n this.version = data.wantedVersion;\n body.version = this.version;\n data = await this.postLogin(url, body);\n }\n\n if (!data.success) {\n throw new Error(`Login failed: ${data.message ?? \"unknown error\"}`);\n }\n\n const servers: ServerInfo[] = Object.entries(data.populations ?? {}).map(\n ([name, population]) => ({ name, population }),\n );\n\n return {\n servers,\n key: data.key,\n username: data.username,\n moderator: false,\n buddyWorlds: [],\n };\n }\n\n async connect(\n serverName: string,\n loginResult: LoginResult,\n options?: ConnectOptions,\n ): Promise<Socket> {\n const wsUrl = `wss://${serverName.toLowerCase()}.server.cplegacy.com`;\n const rawSocket = io(wsUrl, {\n path: \"/socket.io/\",\n parser: msgpackParser,\n transports: [\"websocket\"],\n reconnection: false,\n });\n this.socket = rawSocket;\n\n await new Promise<void>((resolve, reject) => {\n const timeout = setTimeout(() => {\n rawSocket.disconnect();\n reject(new Error(\"Game connection timed out\"));\n }, 15_000);\n\n rawSocket.on(\"connect\", () => {\n rawSocket.emit(\"message\", \"game_auth\", {\n username: loginResult.username,\n key: loginResult.key,\n createToken: false,\n token: \"\",\n });\n });\n\n rawSocket.on(\n \"message\",\n (action: string, args: Record<string, unknown>) => {\n switch (action) {\n case \"wait_queue_update\": {\n options?.onQueueUpdate?.(args as unknown as QueueUpdate);\n break;\n }\n case \"game_auth\": {\n const response = args as unknown as GameAuthResponse;\n if (!response.success) {\n clearTimeout(timeout);\n rawSocket.disconnect();\n reject(new Error(\"Game auth failed\"));\n return;\n }\n\n // CPLegacy requires explicitly requesting load_player before join_server\n rawSocket.emit(\"message\", \"load_player\", {});\n rawSocket.emit(\"message\", \"join_server\", {});\n clearTimeout(timeout);\n resolve();\n break;\n }\n }\n },\n );\n\n rawSocket.on(\"connect_error\", (err: Error) => {\n clearTimeout(timeout);\n rawSocket.disconnect();\n reject(new Error(`Game connection failed: ${err.message}`));\n });\n });\n\n // Return wrapped socket so Client receives normalized { action, args } messages\n return wrapSocket(rawSocket);\n }\n\n send(action: string, args: Record<string, unknown>): void {\n if (!this.socket) throw new Error(\"Not connected\");\n this.socket.emit(\"message\", action, args);\n }\n\n disconnect(): void {\n this.socket?.disconnect();\n this.socket = null;\n }\n\n override normalizeUser(raw: Record<string, unknown>): RoomUser {\n return {\n ...this.extractAppearance(raw),\n id: raw.id as number,\n username: raw.username as string,\n displayName: (raw.realUsername as string) ?? (raw.username as string),\n joinTime: raw.joinTime as string | undefined,\n x: (raw.x as number) ?? 0,\n y: (raw.y as number) ?? 0,\n frame: (raw.frame as number) ?? 0,\n walking: (raw.walking as number) ?? undefined,\n meta: {\n internalUsername: raw.username as string,\n approved: raw.approved,\n emailVerified: raw.emailVerified,\n safeChat: raw.safeChat,\n tutorial: raw.tutorial,\n loginStreak: raw.loginStreak,\n walkingColor: raw.walkingColor,\n stampbookColor: raw.stampbookColor,\n stampbookClasp: raw.stampbookClasp,\n stampbookPattern: raw.stampbookPattern,\n ninjaPoints: raw.ninjaPoints,\n highestNinjaRank: raw.highestNinjaRank,\n character: raw.character,\n transformed: raw.transformed,\n },\n _raw: raw,\n };\n }\n\n override normalizePlayer(raw: Record<string, unknown>): PlayerData {\n const user = raw.user as Record<string, unknown>;\n return {\n ...this.normalizeUser(user),\n _raw: raw,\n coins: (user.coins as number) ?? 0,\n rank: (user.rank as number) ?? 0,\n inventory: (raw.inventory as number[]) ?? [],\n furniture: raw.furniture as Record<string, unknown> | undefined,\n buddies: [],\n buddyRequests:\n (raw.pending as Buddy[] | undefined)?.map((b) => b.id) ?? [],\n ignores: [],\n igloos: (raw.igloos as unknown[]) ?? [],\n };\n }\n\n override sendMessage(message: string): void {\n this.send(\"send_message\", { message });\n }\n\n override sendEmote(emote: number): void {\n this.send(\"send_emote\", { emote });\n }\n\n override sendSafe(safe: number): void {\n this.send(\"send_safe\", { safe });\n }\n\n override walk(x: number, y: number): void {\n this.send(\"send_position\", { x, y });\n }\n\n override sendFrame(frame: number, set?: boolean): void {\n this.send(\"send_frame\", { frame, set });\n }\n\n override snowball(x: number, y: number): void {\n this.send(\"snowball\", { x, y });\n }\n\n override joinRoom(room: number, x?: number, y?: number): void {\n this.send(\"join_room\", { room, x: x ?? 0, y: y ?? 0 });\n }\n\n override addItem(item: number): void {\n this.send(\"add_item\", { item });\n }\n\n override equipColor(item: number): void {\n this.send(\"update_color\", { item });\n }\n\n override equipHead(item: number): void {\n this.send(\"update_head\", { item });\n }\n\n override equipFace(item: number): void {\n this.send(\"update_face\", { item });\n }\n\n override equipNeck(item: number): void {\n this.send(\"update_neck\", { item });\n }\n\n override equipBody(item: number): void {\n this.send(\"update_body\", { item });\n }\n\n override equipHand(item: number): void {\n this.send(\"update_hand\", { item });\n }\n\n override equipFeet(item: number): void {\n this.send(\"update_feet\", { item });\n }\n\n override equipFlag(item: number): void {\n this.send(\"update_flag\", { item });\n }\n\n override equipPhoto(item: number): void {\n this.send(\"update_photo\", { item });\n }\n\n override buddyRequest(id: number): void {\n this.send(\"buddy_request\", { id });\n }\n\n override buddyAccept(id: number): void {\n this.send(\"buddy_accept\", { id });\n }\n\n override buddyReject(id: number): void {\n this.send(\"buddy_reject\", { id });\n }\n\n override removeBuddy(id: number): void {\n this.send(\"remove_buddy\", { id });\n }\n\n override addIgnore(id: number): void {\n this.send(\"ignore_add\", { id });\n }\n\n override removeIgnore(id: number): void {\n this.send(\"ignore_remove\", { id });\n }\n\n override getPlayer(id: number): void {\n this.send(\"get_player\", { id });\n }\n\n override getStamps(userId: number): void {\n this.send(\"get_stamps\", { userId });\n }\n\n override getPostcards(): void {\n this.send(\"get_postcards\", {});\n }\n\n override joinIgloo(igloo: number, x?: number, y?: number): void {\n this.send(\"join_igloo\", { igloo, x: x ?? 0, y: y ?? 0 });\n }\n\n override gameOver(coins: number): void {\n this.send(\"game_over\", { coins });\n }\n\n override collectStamp(stamp: number): void {\n this.send(\"collect_stamp\", { stamp });\n }\n\n private async postLogin(\n url: string,\n body: Record<string, unknown>,\n ): Promise<LoginResponse> {\n const resp = await fetch(url, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n Accept: \"application/json\",\n },\n body: JSON.stringify(body),\n });\n\n return resp.json() as Promise<LoginResponse>;\n }\n}\n","import { createHash } from \"node:crypto\";\nimport { EventEmitter } from \"node:events\";\nimport WebSocket from \"ws\";\nimport type {\n LoginOptions,\n LoginResult,\n TokenLoginOptions,\n} from \"../types/adapter-types.js\";\nimport type { PlayerData, RoomUser } from \"../types/player-types.js\";\nimport { BaseAdapter, type ConnectOptions } from \"./base-adapter.js\";\n\nconst LOGIN_WS_URL = \"wss://server.cpzero.net/login\";\nconst GAME_WS_URL = \"wss://server.cpzero.net/sub_zero\";\nconst API_VERSION = \"253\";\nconst LOGIN_ZONE = \"w1\";\nconst NUL = \"\\0\";\n\n/**\n * CPZero user string field indices.\n * Extended Houdini format with 15 clothing slots (indices 3–17).\n */\nconst U = {\n ID: 0,\n USERNAME: 1,\n // 2 = agent/approval\n COLOR: 3,\n HEAD: 4,\n FACE: 5,\n NECK: 6,\n BODY: 7,\n HAND: 8,\n BACK: 9,\n BODY2: 10,\n HAND2: 11,\n BEAK: 12,\n HAIR: 13,\n FEET: 14,\n MOUNT: 15,\n FLAG: 16,\n PHOTO: 17,\n X: 18,\n Y: 19,\n FRAME: 20,\n // 21 = member\n RANK: 22,\n} as const;\n\nfunction md5(input: string): string {\n return createHash(\"md5\").update(input).digest(\"hex\");\n}\n\n/** MD5 then swap the two 16-char halves — classic Houdini password hash. */\nfunction swapMD5(input: string): string {\n const hash = md5(input);\n return hash.substring(16, 32) + hash.substring(0, 16);\n}\n\nfunction int(v: string | undefined): number {\n const n = Number(v);\n return Number.isNaN(n) ? 0 : n;\n}\n\n/**\n * Parse a pipe-delimited user string into a keyed object.\n * Example: `32924|kingofxiaomi|1|15|674|0|0|...|x|y|frame|...`\n */\nfunction parseUserString(str: string): Record<string, unknown> {\n const f = str.split(\"|\");\n return {\n id: int(f[U.ID]),\n username: f[U.USERNAME] ?? \"\",\n color: int(f[U.COLOR]),\n head: int(f[U.HEAD]),\n face: int(f[U.FACE]),\n neck: int(f[U.NECK]),\n body: int(f[U.BODY]),\n hand: int(f[U.HAND]),\n back: int(f[U.BACK]),\n body2: int(f[U.BODY2]),\n hand2: int(f[U.HAND2]),\n beak: int(f[U.BEAK]),\n hair: int(f[U.HAIR]),\n feet: int(f[U.FEET]),\n mount: int(f[U.MOUNT]),\n flag: int(f[U.FLAG]),\n photo: int(f[U.PHOTO]),\n x: int(f[U.X]),\n y: int(f[U.Y]),\n frame: int(f[U.FRAME]),\n rank: int(f[U.RANK]),\n };\n}\n\n/**\n * Minimal Socket-like wrapper around a raw WebSocket.\n * Emits `\"message\"` with `{ action, args }` payloads so the Client class\n * can consume CPZero messages identically to Socket.IO adapters.\n */\nclass SmartFoxSocket extends EventEmitter {\n private ws: WebSocket;\n private _closed = false;\n private _buffering = true;\n private _buffer: { action: string; args: Record<string, unknown> }[] = [];\n\n constructor(ws: WebSocket) {\n super();\n this.ws = ws;\n\n ws.on(\"close\", () => {\n this._closed = true;\n this.emit(\"disconnect\");\n });\n\n ws.on(\"error\", (err) => {\n this.emit(\"connect_error\", err);\n });\n }\n\n /** Emit a `\"message\"` event with the standard `{ action, args }` shape. */\n dispatchMessage(action: string, args: Record<string, unknown>): void {\n if (this._buffering) {\n this._buffer.push({ action, args });\n }\n this.emit(\"message\", { action, args });\n }\n\n /**\n * Stop buffering and replay all buffered messages on the next microtask.\n * This gives the Client time to attach its `socket.on(\"message\", ...)` listener\n * after `connect()` resolves.\n */\n flush(): void {\n this._buffering = false;\n const buffered = this._buffer;\n this._buffer = [];\n setTimeout(() => {\n for (const msg of buffered) {\n this.emit(\"message\", msg);\n }\n }, 0);\n }\n\n send(data: string): void {\n if (!this._closed) this.ws.send(data + NUL);\n }\n\n disconnect(): void {\n if (!this._closed) {\n this._closed = true;\n this.ws.close();\n }\n }\n\n get connected(): boolean {\n return !this._closed && this.ws.readyState === WebSocket.OPEN;\n }\n}\n\n/**\n * Map `%xt%` command names to the normalized action + args shape\n * that the Client class expects.\n */\nfunction translateXt(\n cmd: string,\n parts: string[],\n): { action: string; args: Record<string, unknown> } | null {\n switch (cmd) {\n case \"lp\": {\n // load_player: parts[0] = user string, parts[1..] = extra fields\n const user = parseUserString(parts[0] ?? \"\");\n const coins = int(parts[1]);\n const rank = user.rank as number;\n return {\n action: \"load_player\",\n args: { user, coins, rank },\n };\n }\n\n case \"jr\": {\n // join_room: parts[0] = roomId, parts[1..] = user strings\n const room = int(parts[0]);\n const users = parts.slice(1).filter(Boolean).map(parseUserString);\n return { action: \"join_room\", args: { room, users } };\n }\n\n case \"ap\": {\n // add_player: single user string\n const user = parseUserString(parts[0] ?? \"\");\n return { action: \"add_player\", args: { user } };\n }\n\n case \"rp\": {\n // remove_player: user id\n return { action: \"remove_player\", args: { user: int(parts[0]) } };\n }\n\n case \"sp\": {\n // send_position: userId, x, y\n return {\n action: \"send_position\",\n args: { id: int(parts[0]), x: int(parts[1]), y: int(parts[2]) },\n };\n }\n\n case \"sf\": {\n // send_frame: userId, frame\n return {\n action: \"send_frame\",\n args: { id: int(parts[0]), frame: int(parts[1]) },\n };\n }\n\n case \"sm\": {\n // send_message: userId, message\n return {\n action: \"send_message\",\n args: { id: int(parts[0]), message: parts[1] ?? \"\" },\n };\n }\n\n case \"se\": {\n // send_emote: userId, emote\n return {\n action: \"send_emote\",\n args: { id: int(parts[0]), emote: int(parts[1]) },\n };\n }\n\n case \"sa\": {\n // send_action (safe chat): userId, action\n return {\n action: \"send_safe\",\n args: { id: int(parts[0]), safe: int(parts[1]) },\n };\n }\n\n case \"sb\": {\n // snowball: userId, x, y\n return {\n action: \"snowball\",\n args: { id: int(parts[0]), x: int(parts[1]), y: int(parts[2]) },\n };\n }\n\n case \"gp\": {\n // get_player response: user string\n const user = parseUserString(parts[0] ?? \"\");\n return { action: \"get_player\", args: { user } };\n }\n\n // Equip updates: userId, itemId\n case \"upc\":\n return {\n action: \"update_player\",\n args: { id: int(parts[0]), item: int(parts[1]), slot: \"color\" },\n };\n case \"uph\":\n return {\n action: \"update_player\",\n args: { id: int(parts[0]), item: int(parts[1]), slot: \"head\" },\n };\n case \"upf\":\n return {\n action: \"update_player\",\n args: { id: int(parts[0]), item: int(parts[1]), slot: \"face\" },\n };\n case \"upn\":\n return {\n action: \"update_player\",\n args: { id: int(parts[0]), item: int(parts[1]), slot: \"neck\" },\n };\n case \"upb\":\n return {\n action: \"update_player\",\n args: { id: int(parts[0]), item: int(parts[1]), slot: \"body\" },\n };\n case \"upa\":\n return {\n action: \"update_player\",\n args: { id: int(parts[0]), item: int(parts[1]), slot: \"hand\" },\n };\n case \"upe\":\n return {\n action: \"update_player\",\n args: { id: int(parts[0]), item: int(parts[1]), slot: \"feet\" },\n };\n case \"upl\":\n return {\n action: \"update_player\",\n args: { id: int(parts[0]), item: int(parts[1]), slot: \"flag\" },\n };\n case \"upp\":\n return {\n action: \"update_player\",\n args: { id: int(parts[0]), item: int(parts[1]), slot: \"photo\" },\n };\n case \"upba\":\n return {\n action: \"update_player\",\n args: { id: int(parts[0]), item: int(parts[1]), slot: \"back\" },\n };\n case \"upm\":\n return {\n action: \"update_player\",\n args: { id: int(parts[0]), item: int(parts[1]), slot: \"mount\" },\n };\n\n case \"ai\": {\n // add_item response: itemId, coins remaining\n return {\n action: \"add_item\",\n args: { item: int(parts[0]), coins: int(parts[1]) },\n };\n }\n\n case \"jg\": {\n // join_game_room\n return { action: \"join_game_room\", args: { game: int(parts[0]) } };\n }\n\n case \"e\": {\n // error\n return { action: \"error\", args: { error: parts[0] ?? \"unknown\" } };\n }\n\n default:\n return null;\n }\n}\n\nexport class CpzeroAdapter extends BaseAdapter {\n readonly id = \"CPZero\";\n private sfs: SmartFoxSocket | null = null;\n\n async login(options: LoginOptions | TokenLoginOptions): Promise<LoginResult> {\n if (\"token\" in options) {\n throw new Error(\"CPZero does not support token login\");\n }\n\n const loginHash = options.secret;\n if (!loginHash) {\n throw new Error(\n \"CPZero requires a pre-computed login hash in options.secret\",\n );\n }\n\n const ws = new WebSocket(LOGIN_WS_URL);\n const result = await new Promise<LoginResult>((resolve, reject) => {\n const timeout = setTimeout(() => {\n ws.close();\n reject(new Error(\"Login timed out\"));\n }, 15_000);\n\n let _rndK = \"\";\n\n ws.on(\"open\", () => {\n ws.send(xmlMsg(\"verChk\", \"0\", `<ver v='${API_VERSION}' />`) + NUL);\n });\n\n ws.on(\"message\", (raw: Buffer) => {\n const messages = raw.toString(\"utf-8\").split(NUL).filter(Boolean);\n for (const msg of messages) {\n if (\n msg.includes('action=\"apiOK\"') ||\n msg.includes(\"action='apiOK'\")\n ) {\n ws.send(xmlMsg(\"rndK\", \"-1\", \"\") + NUL);\n continue;\n }\n\n const kMatch = msg.match(/<k>(.*?)<\\/k>/);\n if (kMatch) {\n _rndK = kMatch[1];\n const loginXml = xmlLogin(options.username, loginHash);\n ws.send(loginXml + NUL);\n continue;\n }\n\n if (msg.startsWith(\"%xt%l%\")) {\n const xtParts = msg.split(\"%\").filter(Boolean);\n // xt, l, -1, nickString, confirmationKey, ...\n const nickString = xtParts[3] ?? \"\";\n const confirmationKey = xtParts[4] ?? \"\";\n const nickFields = nickString.split(\"|\");\n\n clearTimeout(timeout);\n ws.close();\n\n const userId = int(nickFields[0]);\n const username = nickFields[2] ?? options.username;\n resolve({\n servers: [{ name: \"Sub Zero\", population: 0 }],\n key: `${userId}|${nickString}|${confirmationKey}`,\n username,\n moderator: false,\n buddyWorlds: [],\n });\n return;\n }\n\n if (msg.startsWith(\"%xt%e%\")) {\n clearTimeout(timeout);\n ws.close();\n const errParts = msg.split(\"%\").filter(Boolean);\n reject(\n new Error(`Login failed: error ${errParts[3] ?? \"unknown\"}`),\n );\n return;\n }\n }\n });\n\n ws.on(\"error\", (err) => {\n clearTimeout(timeout);\n ws.close();\n reject(new Error(`Login WS error: ${(err as Error).message}`));\n });\n\n ws.on(\"close\", () => {\n clearTimeout(timeout);\n });\n });\n\n return result;\n }\n\n async connect(\n _serverName: string,\n loginResult: LoginResult,\n _options?: ConnectOptions,\n ): Promise<import(\"socket.io-client\").Socket> {\n // loginResult.key = \"userId|nickString|confirmationKey\"\n const keyParts = loginResult.key.split(\"|\");\n const userId = keyParts[0] ?? \"\";\n const nickString = keyParts.slice(1, -1).join(\"|\");\n const confirmationKey = keyParts[keyParts.length - 1] ?? \"\";\n const loginKey = nickString.split(\"|\")[3] ?? \"\";\n\n const ws = new WebSocket(GAME_WS_URL);\n const sfs = new SmartFoxSocket(ws);\n this.sfs = sfs;\n // Store as unknown since SmartFoxSocket is not a Socket.IO Socket\n this.socket = sfs as unknown as import(\"socket.io-client\").Socket;\n\n await new Promise<void>((resolve, reject) => {\n const timeout = setTimeout(() => {\n ws.close();\n reject(new Error(\"Game connection timed out\"));\n }, 15_000);\n\n ws.on(\"open\", () => {\n sfs.send(xmlMsg(\"verChk\", \"0\", `<ver v='${API_VERSION}' />`));\n });\n\n ws.on(\"message\", (raw: Buffer) => {\n const messages = raw.toString(\"utf-8\").split(NUL).filter(Boolean);\n for (const msg of messages) {\n // XML phase\n if (\n msg.includes('action=\"apiOK\"') ||\n msg.includes(\"action='apiOK'\")\n ) {\n sfs.send(xmlMsg(\"rndK\", \"-1\", \"\"));\n continue;\n }\n\n const kMatch = msg.match(/<k>(.*?)<\\/k>/);\n if (kMatch) {\n const rndK = kMatch[1];\n const gamePword = `${swapMD5(loginKey + rndK)}${loginKey}#${confirmationKey}`;\n sfs.send(xmlGameLogin(nickString, gamePword));\n continue;\n }\n\n // xt phase — may contain multiple messages concatenated\n if (msg.startsWith(\"%xt%\")) {\n this.processXtBatch(msg, sfs);\n\n // Detect login success and send join_server\n if (msg.includes(\"%xt%l%\")) {\n sfs.send(`%xt%s%j#js%-1%${userId}%${loginKey}%en%`);\n }\n\n // Resolve once we get load_player + join_room\n if (msg.includes(\"%xt%jr%\")) {\n clearTimeout(timeout);\n resolve();\n }\n }\n\n if (msg.includes(\"%xt%e%\")) {\n clearTimeout(timeout);\n ws.close();\n const errParts = msg.split(\"%\").filter(Boolean);\n reject(\n new Error(`Game auth failed: error ${errParts[3] ?? \"unknown\"}`),\n );\n return;\n }\n }\n });\n\n ws.on(\"error\", (err) => {\n clearTimeout(timeout);\n reject(new Error(`Game WS error: ${(err as Error).message}`));\n });\n });\n\n // Wire up ongoing message handling\n ws.on(\"message\", (raw: Buffer) => {\n const messages = raw.toString(\"utf-8\").split(NUL).filter(Boolean);\n for (const msg of messages) {\n if (msg.startsWith(\"%xt%\")) {\n this.processXtBatch(msg, sfs);\n }\n }\n });\n\n // Replay buffered load_player/join_room messages after the Client attaches its listener\n sfs.flush();\n\n // Cast to Socket — Client only uses .on(\"message\") / .on(\"disconnect\") / .off()\n return sfs as unknown as import(\"socket.io-client\").Socket;\n }\n\n send(action: string, args: Record<string, unknown>): void {\n if (!this.sfs) throw new Error(\"Not connected\");\n const xt = actionToXt(action, args);\n if (xt) this.sfs.send(xt);\n }\n\n disconnect(): void {\n this.sfs?.disconnect();\n this.sfs = null;\n this.socket = null;\n }\n\n override normalizeUser(raw: Record<string, unknown>): RoomUser {\n return {\n ...this.extractAppearance(raw),\n id: raw.id as number,\n username: raw.username as string,\n x: (raw.x as number) ?? 0,\n y: (raw.y as number) ?? 0,\n frame: (raw.frame as number) ?? 0,\n meta: {\n back: raw.back,\n body2: raw.body2,\n hand2: raw.hand2,\n beak: raw.beak,\n hair: raw.hair,\n mount: raw.mount,\n rank: raw.rank,\n },\n _raw: raw,\n };\n }\n\n override normalizePlayer(raw: Record<string, unknown>): PlayerData {\n const user = raw.user as Record<string, unknown>;\n return {\n ...this.normalizeUser(user),\n _raw: raw,\n coins: (raw.coins as number) ?? 0,\n rank: (user.rank as number) ?? 0,\n inventory: [],\n buddies: [],\n ignores: [],\n };\n }\n\n override sendMessage(message: string): void {\n if (!this.sfs) throw new Error(\"Not connected\");\n const userId = 0; // Server ignores the sent userId for own messages\n this.sfs.send(`%xt%s%m#sm%-1%${userId}%${message}%`);\n }\n\n override sendEmote(emote: number): void {\n if (!this.sfs) throw new Error(\"Not connected\");\n this.sfs.send(`%xt%s%u#se%-1%${emote}%`);\n }\n\n override sendSafe(safe: number): void {\n if (!this.sfs) throw new Error(\"Not connected\");\n this.sfs.send(`%xt%s%u#sa%-1%${safe}%`);\n }\n\n override walk(x: number, y: number): void {\n if (!this.sfs) throw new Error(\"Not connected\");\n this.sfs.send(`%xt%s%u#sp%-1%${x}%${y}%`);\n }\n\n override sendFrame(frame: number): void {\n if (!this.sfs) throw new Error(\"Not connected\");\n this.sfs.send(`%xt%s%u#sf%-1%${frame}%`);\n }\n\n override snowball(x: number, y: number): void {\n if (!this.sfs) throw new Error(\"Not connected\");\n this.sfs.send(`%xt%s%u#sb%-1%${x}%${y}%`);\n }\n\n override joinRoom(room: number, x?: number, y?: number): void {\n if (!this.sfs) throw new Error(\"Not connected\");\n this.sfs.send(`%xt%s%j#jr%-1%${room}%${x ?? 0}%${y ?? 0}%`);\n }\n\n override addItem(item: number): void {\n if (!this.sfs) throw new Error(\"Not connected\");\n this.sfs.send(`%xt%s%i#ai%-1%${item}%`);\n }\n\n override equipColor(item: number): void {\n if (!this.sfs) throw new Error(\"Not connected\");\n this.sfs.send(`%xt%s%s#upc%-1%${item}%`);\n }\n\n override equipHead(item: number): void {\n if (!this.sfs) throw new Error(\"Not connected\");\n this.sfs.send(`%xt%s%s#uph%-1%${item}%`);\n }\n\n override equipFace(item: number): void {\n if (!this.sfs) throw new Error(\"Not connected\");\n this.sfs.send(`%xt%s%s#upf%-1%${item}%`);\n }\n\n override equipNeck(item: number): void {\n if (!this.sfs) throw new Error(\"Not connected\");\n this.sfs.send(`%xt%s%s#upn%-1%${item}%`);\n }\n\n override equipBody(item: number): void {\n if (!this.sfs) throw new Error(\"Not connected\");\n this.sfs.send(`%xt%s%s#upb%-1%${item}%`);\n }\n\n override equipHand(item: number): void {\n if (!this.sfs) throw new Error(\"Not connected\");\n this.sfs.send(`%xt%s%s#upa%-1%${item}%`);\n }\n\n override equipFeet(item: number): void {\n if (!this.sfs) throw new Error(\"Not connected\");\n this.sfs.send(`%xt%s%s#upe%-1%${item}%`);\n }\n\n override equipFlag(item: number): void {\n if (!this.sfs) throw new Error(\"Not connected\");\n this.sfs.send(`%xt%s%s#upl%-1%${item}%`);\n }\n\n override equipPhoto(item: number): void {\n if (!this.sfs) throw new Error(\"Not connected\");\n this.sfs.send(`%xt%s%s#upp%-1%${item}%`);\n }\n\n override getPlayer(id: number): void {\n if (!this.sfs) throw new Error(\"Not connected\");\n this.sfs.send(`%xt%s%u#gp%-1%${id}%`);\n }\n\n override joinIgloo(igloo: number, _x?: number, _y?: number): void {\n if (!this.sfs) throw new Error(\"Not connected\");\n this.sfs.send(`%xt%s%j#jp%-1%${igloo}%igloo%`);\n }\n\n /**\n * Process a batch of `%xt%` messages that may be concatenated in a single\n * WebSocket frame (separated by \\0 already split, but multiple %xt% in one string).\n */\n private processXtBatch(raw: string, sfs: SmartFoxSocket): void {\n // Split concatenated xt messages: \" %xt%cmd1%...% %xt%cmd2%...%\"\n const xtMessages = raw\n .split(/(?=%xt%)/)\n .map((s) => s.trim())\n .filter(Boolean);\n\n for (const xt of xtMessages) {\n const parts = xt.split(\"%\").filter(Boolean);\n // parts: [\"xt\", cmd, roomId, ...args]\n if (parts[0] !== \"xt\" || parts.length < 3) continue;\n\n const cmd = parts[1];\n const xtArgs = parts.slice(3); // skip \"xt\", cmd, roomId\n\n const translated = translateXt(cmd, xtArgs);\n if (translated) {\n sfs.dispatchMessage(translated.action, translated.args);\n }\n }\n }\n}\n\n// ── XML helpers ──\n\nfunction xmlMsg(action: string, r: string, body: string): string {\n return `<msg t='sys'><body action='${action}' r='${r}'>${body}</body></msg>`;\n}\n\nfunction xmlLogin(username: string, pword: string): string {\n return xmlMsg(\n \"login\",\n \"0\",\n `<login z='${LOGIN_ZONE}'><nick><![CDATA[${username}]]></nick><pword><![CDATA[${pword}]]></pword></login>`,\n );\n}\n\nfunction xmlGameLogin(nick: string, pword: string): string {\n return xmlMsg(\n \"login\",\n \"0\",\n `<login z='${LOGIN_ZONE}'><nick><![CDATA[${nick}]]></nick><pword><![CDATA[${pword}]]></pword></login>`,\n );\n}\n\n/**\n * Convert a normalized Client action to the raw `%xt%` send format.\n * Only used when called via the generic `send()` method.\n */\nfunction actionToXt(\n action: string,\n args: Record<string, unknown>,\n): string | null {\n switch (action) {\n case \"send_position\":\n return `%xt%s%u#sp%-1%${args.x}%${args.y}%`;\n case \"send_frame\":\n return `%xt%s%u#sf%-1%${args.frame}%`;\n case \"send_message\":\n return `%xt%s%m#sm%-1%0%${args.message}%`;\n case \"send_emote\":\n return `%xt%s%u#se%-1%${args.emote}%`;\n case \"send_safe\":\n return `%xt%s%u#sa%-1%${args.safe}%`;\n case \"snowball\":\n return `%xt%s%u#sb%-1%${args.x}%${args.y}%`;\n case \"join_room\":\n return `%xt%s%j#jr%-1%${args.room}%${args.x ?? 0}%${args.y ?? 0}%`;\n case \"add_item\":\n return `%xt%s%i#ai%-1%${args.item}%`;\n case \"get_player\":\n return `%xt%s%u#gp%-1%${args.id}%`;\n default:\n return null;\n }\n}\n","import { createCipheriv, createDecipheriv, randomBytes } from \"node:crypto\";\nimport { io, type Socket } from \"socket.io-client\";\nimport nacl from \"tweetnacl\";\nimport type {\n LoginOptions,\n LoginResult,\n QueueUpdate,\n ServerInfo,\n TokenLoginOptions,\n} from \"../types/adapter-types.js\";\nimport type { Buddy, PlayerData, RoomUser } from \"../types/player-types.js\";\nimport { BaseAdapter, type ConnectOptions } from \"./base-adapter.js\";\n\nconst CRUMBS_URL =\n \"https://media8.newcp.net/assets/media/crumbs/en/crumbs.json\";\n\ntype WorldConfig = {\n id?: number;\n host: string;\n path: string;\n login?: boolean;\n};\n\ntype CrumbsWorlds = Record<string, WorldConfig>;\n\ntype LoginResponse = {\n success: boolean;\n username: string;\n key: string;\n populations: Record<string, number>;\n moderator: boolean;\n buddyWorlds: string[];\n};\n\ntype GameAuthResponse = {\n success: boolean;\n token?: string;\n};\n\nclass Encryptor {\n private aesKey: Buffer | null = null;\n private keypair = nacl.box.keyPair();\n\n get publicKey(): string {\n return Buffer.from(this.keypair.publicKey).toString(\"base64\");\n }\n\n get encrypted(): boolean {\n return this.aesKey !== null;\n }\n\n acquireKey(encryptedB64: string, serverPubKeyB64: string): string | null {\n const data = Buffer.from(encryptedB64, \"base64\");\n const serverPubKey = Buffer.from(serverPubKeyB64, \"base64\");\n const nonce = data.subarray(0, nacl.box.nonceLength);\n const ciphertext = data.subarray(nacl.box.nonceLength);\n const plaintext = nacl.box.open(\n new Uint8Array(ciphertext),\n new Uint8Array(nonce),\n new Uint8Array(serverPubKey),\n this.keypair.secretKey,\n );\n return plaintext ? new TextDecoder().decode(plaintext) : null;\n }\n\n setKey(keyString: string): void {\n this.aesKey = Buffer.from(keyString, \"utf-8\");\n }\n\n encrypt(plaintext: string): string {\n if (!this.aesKey) throw new Error(\"Encryption key not set\");\n const iv = randomBytes(16);\n const cipher = createCipheriv(\"aes-256-cbc\", this.aesKey, iv);\n const encrypted = Buffer.concat([\n cipher.update(plaintext, \"utf-8\"),\n cipher.final(),\n ]);\n const result = Buffer.concat([iv, encrypted]);\n return result.toString(\"base64\");\n }\n\n decrypt(data: string): string {\n if (!this.aesKey) throw new Error(\"Encryption key not set\");\n const buf = Buffer.from(data, \"base64\");\n const iv = buf.subarray(0, 16);\n const ciphertext = buf.subarray(16);\n const decipher = createDecipheriv(\"aes-256-cbc\", this.aesKey, iv);\n return Buffer.concat([\n decipher.update(ciphertext),\n decipher.final(),\n ]).toString(\"utf-8\");\n }\n\n encode(data: Record<string, unknown>): string {\n return this.encrypted\n ? this.encrypt(JSON.stringify(data))\n : JSON.stringify(data);\n }\n\n decode(data: unknown): Record<string, unknown> {\n if (this.encrypted && typeof data === \"string\") {\n return JSON.parse(this.decrypt(data)) as Record<string, unknown>;\n }\n return typeof data === \"string\"\n ? (JSON.parse(data) as Record<string, unknown>)\n : (data as Record<string, unknown>);\n }\n}\n\nfunction performHandshake(socket: Socket, encryptor: Encryptor): Promise<void> {\n return new Promise((resolve, reject) => {\n const timeout = setTimeout(() => {\n reject(new Error(\"Handshake timed out\"));\n }, 10_000);\n\n socket.once(\n \"handshake\",\n (encryptedKey: string, serverPubKeyB64: string) => {\n clearTimeout(timeout);\n const raw = encryptor.acquireKey(encryptedKey, serverPubKeyB64);\n if (!raw) {\n reject(new Error(\"Failed to decrypt handshake key\"));\n return;\n }\n\n const parsed = JSON.parse(raw) as { key: string; time?: number };\n if (\n parsed.time &&\n typeof parsed.time === \"number\" &&\n Math.abs(Date.now() - parsed.time) > 300_000\n ) {\n reject(new Error(\"Server time desync\"));\n return;\n }\n\n encryptor.setKey(parsed.key);\n resolve();\n },\n );\n\n socket.emit(\"handshake\", encryptor.publicKey);\n });\n}\n\n/**\n * Wraps a NewCP socket to decrypt incoming messages into the\n * `{ action, args }` envelope that the Client class expects.\n */\nfunction wrapSocket(raw: Socket, encryptor: Encryptor): Socket {\n const original = raw.on.bind(raw);\n\n raw.on = ((event: string, listener: (...args: unknown[]) => void) => {\n if (event === \"message\") {\n return original(event, (msg: unknown) => {\n try {\n const decoded = encryptor.decode(msg);\n listener({ action: decoded.action, args: decoded.args ?? {} });\n } catch {\n // Skip malformed messages\n }\n });\n }\n return original(event, listener);\n }) as typeof raw.on;\n\n return raw;\n}\n\nexport class NewcpAdapter extends BaseAdapter {\n readonly id = \"NewCP\";\n private encryptor = new Encryptor();\n private worlds: CrumbsWorlds | null = null;\n\n async login(options: LoginOptions | TokenLoginOptions): Promise<LoginResult> {\n if (!this.worlds) {\n await this.loadWorlds();\n }\n\n const loginWorld = Object.values(this.worlds ?? {}).find((w) => w.login);\n if (!loginWorld) throw new Error(\"Login world not found in crumbs\");\n\n const loginSocket = this.createSocket(loginWorld.host, loginWorld.path);\n this.encryptor = new Encryptor();\n\n const result = await new Promise<LoginResult>((resolve, reject) => {\n const timeout = setTimeout(() => {\n loginSocket.disconnect();\n reject(new Error(\"Login timed out\"));\n }, 15_000);\n\n loginSocket.on(\"connect\", async () => {\n try {\n await performHandshake(loginSocket, this.encryptor);\n\n const args =\n \"token\" in options\n ? { username: options.username, token: options.token }\n : { username: options.username, password: options.password };\n\n const encrypted = this.encryptor.encode({ action: \"login\", args });\n loginSocket.emit(\"message\", encrypted);\n } catch (err) {\n clearTimeout(timeout);\n loginSocket.disconnect();\n reject(err);\n }\n });\n\n loginSocket.on(\"message\", (msg: unknown) => {\n try {\n const decoded = this.encryptor.decode(msg);\n if (decoded.action !== \"login\") return;\n\n clearTimeout(timeout);\n loginSocket.disconnect();\n\n const response = decoded.args as unknown as LoginResponse;\n\n if (!response.success) {\n reject(new Error(\"Login failed\"));\n return;\n }\n\n const servers: ServerInfo[] = Object.entries(\n response.populations ?? {},\n ).map(([name, population]) => ({ name, population }));\n\n resolve({\n servers,\n key: response.key,\n username: response.username,\n moderator: response.moderator ?? false,\n buddyWorlds: response.buddyWorlds ?? [],\n });\n } catch (err) {\n clearTimeout(timeout);\n loginSocket.disconnect();\n reject(err);\n }\n });\n\n loginSocket.on(\"connect_error\", (err: Error) => {\n clearTimeout(timeout);\n loginSocket.disconnect();\n reject(new Error(`Login connection failed: ${err.message}`));\n });\n });\n\n return result;\n }\n\n async connect(\n serverName: string,\n loginResult: LoginResult,\n options?: ConnectOptions,\n ): Promise<Socket> {\n if (!this.worlds) {\n await this.loadWorlds();\n }\n\n const worldConfig = this.worlds?.[serverName];\n if (!worldConfig)\n throw new Error(`World config not found for: ${serverName}`);\n\n this.encryptor = new Encryptor();\n const gameSocket = this.createSocket(worldConfig.host, worldConfig.path);\n this.socket = gameSocket;\n\n await new Promise<void>((resolve, reject) => {\n const timeout = setTimeout(() => {\n gameSocket.disconnect();\n reject(new Error(\"Game connection timed out\"));\n }, 15_000);\n\n gameSocket.on(\"connect\", async () => {\n try {\n await performHandshake(gameSocket, this.encryptor);\n\n const encrypted = this.encryptor.encode({\n action: \"game_auth\",\n args: {\n username: loginResult.username,\n key: loginResult.key,\n createToken: false,\n },\n });\n gameSocket.emit(\"message\", encrypted);\n } catch (err) {\n clearTimeout(timeout);\n gameSocket.disconnect();\n reject(err);\n }\n });\n\n gameSocket.on(\"message\", (msg: unknown) => {\n try {\n const decoded = this.encryptor.decode(msg);\n\n switch (decoded.action) {\n case \"wait_queue_update\": {\n options?.onQueueUpdate?.(decoded.args as unknown as QueueUpdate);\n break;\n }\n case \"game_auth\": {\n const response = decoded.args as unknown as GameAuthResponse;\n if (!response.success) {\n clearTimeout(timeout);\n gameSocket.disconnect();\n reject(new Error(\"Game auth failed\"));\n return;\n }\n\n const joinEncrypted = this.encryptor.encode({\n action: \"join_server\",\n args: {},\n });\n gameSocket.emit(\"message\", joinEncrypted);\n clearTimeout(timeout);\n resolve();\n break;\n }\n }\n } catch {\n // Ignore decode errors during auth phase\n }\n });\n\n gameSocket.on(\"connect_error\", (err: Error) => {\n clearTimeout(timeout);\n gameSocket.disconnect();\n reject(new Error(`Game connection failed: ${err.message}`));\n });\n });\n\n return wrapSocket(gameSocket, this.encryptor);\n }\n\n send(action: string, args: Record<string, unknown>): void {\n if (!this.socket) throw new Error(\"Not connected\");\n const encrypted = this.encryptor.encode({ action, args });\n this.socket.emit(\"message\", encrypted);\n }\n\n disconnect(): void {\n this.socket?.disconnect();\n this.socket = null;\n }\n\n override normalizeUser(raw: Record<string, unknown>): RoomUser {\n return {\n ...this.extractAppearance(raw),\n id: raw.id as number,\n username: raw.username as string,\n displayName: raw.nickname as string | undefined,\n x: (raw.x as number) ?? 0,\n y: (raw.y as number) ?? 0,\n frame: (raw.frame as number) ?? 0,\n meta: {\n nickname: raw.nickname,\n registrationDate: raw.registrationDate,\n customNameColor: raw.customNameColor,\n customBubbleColor: raw.customBubbleColor,\n customBubbleTextColor: raw.customBubbleTextColor,\n wallHacks: raw.wallHacks,\n moderator: raw.moderator,\n character: raw.character,\n approved: raw.approved,\n walking: raw.walking,\n },\n _raw: raw,\n };\n }\n\n override normalizePlayer(raw: Record<string, unknown>): PlayerData {\n const user = raw.user as Record<string, unknown>;\n return {\n ...this.normalizeUser(user),\n _raw: raw,\n coins: (raw.coins as number) ?? 0,\n rank: (raw.rank as number) ?? 0,\n inventory: (raw.inventory as number[]) ?? [],\n buddies: (raw.buddies as Buddy[]) ?? [],\n ignores: (raw.ignores as number[]) ?? [],\n furniture: raw.furniture as Record<string, unknown> | undefined,\n flooring: (raw.floorings as unknown[]) ?? [],\n igloos: (raw.igloos as unknown[]) ?? [],\n };\n }\n\n override sendMessage(message: string): void {\n this.send(\"send_message\", { message });\n }\n\n override sendEmote(emote: number): void {\n this.send(\"send_emote\", { emote });\n }\n\n override sendSafe(safe: number): void {\n this.send(\"send_safe\", { safe });\n }\n\n override walk(x: number, y: number): void {\n this.send(\"send_position\", { x, y });\n }\n\n override sendFrame(frame: number, set?: boolean): void {\n this.send(\"send_frame\", { frame, set });\n }\n\n override snowball(x: number, y: number): void {\n this.send(\"snowball\", { x, y });\n }\n\n override joinRoom(room: number, x?: number, y?: number): void {\n this.send(\"join_room\", { room, x: x ?? 0, y: y ?? 0 });\n }\n\n override addItem(item: number): void {\n this.send(\"add_item\", { item });\n }\n\n override equipColor(item: number): void {\n this.send(\"update_color\", { item });\n }\n\n override equipHead(item: number): void {\n this.send(\"update_head\", { item });\n }\n\n override equipFace(item: number): void {\n this.send(\"update_face\", { item });\n }\n\n override equipNeck(item: number): void {\n this.send(\"update_neck\", { item });\n }\n\n override equipBody(item: number): void {\n this.send(\"update_body\", { item });\n }\n\n override equipHand(item: number): void {\n this.send(\"update_hand\", { item });\n }\n\n override equipFeet(item: number): void {\n this.send(\"update_feet\", { item });\n }\n\n override equipFlag(item: number): void {\n this.send(\"update_flag\", { item });\n }\n\n override equipPhoto(item: number): void {\n this.send(\"update_photo\", { item });\n }\n\n override buddyRequest(id: number): void {\n this.send(\"buddy_request\", { id });\n }\n\n override buddyAccept(id: number): void {\n this.send(\"buddy_accept\", { id });\n }\n\n override buddyReject(id: number): void {\n this.send(\"buddy_reject\", { id });\n }\n\n override removeBuddy(id: number): void {\n this.send(\"remove_buddy\", { id });\n }\n\n override addIgnore(id: number): void {\n this.send(\"ignore_add\", { id });\n }\n\n override removeIgnore(id: number): void {\n this.send(\"ignore_remove\", { id });\n }\n\n override getPlayer(id: number): void {\n this.send(\"get_player\", { id });\n }\n\n override joinIgloo(igloo: number, x?: number, y?: number): void {\n this.send(\"join_igloo\", { igloo, x: x ?? 0, y: y ?? 0 });\n }\n\n private createSocket(host: string, path: string): Socket {\n return io(host, {\n path,\n transports: [\"polling\", \"websocket\"],\n reconnection: false,\n });\n }\n\n private async loadWorlds(): Promise<void> {\n const resp = await fetch(CRUMBS_URL);\n if (!resp.ok) throw new Error(`Failed to fetch crumbs: ${resp.status}`);\n const crumbs = (await resp.json()) as { worlds: CrumbsWorlds };\n this.worlds = crumbs.worlds;\n }\n}\n","import { io, type Socket } from \"socket.io-client\";\nimport type {\n LoginOptions,\n LoginResult,\n QueueUpdate,\n TokenLoginOptions,\n} from \"../types/adapter-types.js\";\nimport type { PlayerData, RoomUser } from \"../types/player-types.js\";\nimport { BaseAdapter, type ConnectOptions } from \"./base-adapter.js\";\n\nconst BASE_URL = \"https://play.penguinorigins.online\";\n\ntype LoginResponse = {\n success: boolean;\n username: string;\n key: string;\n populations: Record<string, number>;\n};\n\ntype GameAuthResponse = {\n success: boolean;\n token?: string;\n};\n\ntype ServerMessage = {\n action: string;\n args: Record<string, unknown>;\n};\n\nexport class PenguinoriginsAdapter extends BaseAdapter {\n readonly id = \"PenguinOrigins\";\n\n async login(options: LoginOptions | TokenLoginOptions): Promise<LoginResult> {\n const loginSocket = this.createSocket(\"/world/login/\");\n\n const result = await new Promise<LoginResult>((resolve, reject) => {\n const timeout = setTimeout(() => {\n loginSocket.disconnect();\n reject(new Error(\"Login timed out\"));\n }, 10_000);\n\n loginSocket.on(\"connect\", () => {\n const action = \"token\" in options ? \"token_login\" : \"login\";\n const args =\n \"token\" in options\n ? { username: options.username, token: options.token }\n : { username: options.username, password: options.password };\n\n loginSocket.emit(\"message\", { action, args });\n });\n\n loginSocket.on(\"message\", (msg: ServerMessage) => {\n if (msg.action !== \"login\") return;\n\n clearTimeout(timeout);\n loginSocket.disconnect();\n\n const response = msg.args as LoginResponse;\n\n if (!response.success) {\n reject(new Error(\"Login failed\"));\n return;\n }\n\n const servers = Object.entries(response.populations).map(\n ([name, population]) => ({ name, population }),\n );\n\n resolve({\n servers,\n key: response.key,\n username: response.username,\n moderator: false,\n buddyWorlds: [],\n });\n });\n\n loginSocket.on(\"connect_error\", (err: Error) => {\n clearTimeout(timeout);\n loginSocket.disconnect();\n reject(new Error(`Login connection failed: ${err.message}`));\n });\n });\n\n return result;\n }\n\n async connect(\n serverName: string,\n loginResult: LoginResult,\n options?: ConnectOptions,\n ): Promise<Socket> {\n const gameSocket = this.createSocket(`/world/${serverName.toLowerCase()}/`);\n this.socket = gameSocket;\n\n await new Promise<void>((resolve, reject) => {\n let authSent = false;\n\n gameSocket.on(\"connect\", () => {\n gameSocket.emit(\"message\", {\n action: \"game_auth\",\n args: {\n username: loginResult.username,\n key: loginResult.key,\n createToken: true,\n token: \"\",\n },\n });\n });\n\n gameSocket.on(\"message\", (msg: ServerMessage) => {\n switch (msg.action) {\n case \"wait_queue_update\": {\n options?.onQueueUpdate?.(msg.args as QueueUpdate);\n break;\n }\n case \"game_auth\": {\n if (authSent) break;\n authSent = true;\n\n const response = msg.args as GameAuthResponse;\n if (!response.success) {\n gameSocket.disconnect();\n reject(new Error(\"Game auth failed\"));\n return;\n }\n\n gameSocket.emit(\"message\", {\n action: \"join_server\",\n args: {},\n });\n resolve();\n break;\n }\n }\n });\n\n gameSocket.on(\"connect_error\", (err: Error) => {\n gameSocket.disconnect();\n reject(new Error(`Game connection failed: ${err.message}`));\n });\n });\n\n return gameSocket;\n }\n\n send(action: string, args: Record<string, unknown>): void {\n if (!this.socket) throw new Error(\"Not connected\");\n this.socket.emit(\"message\", { action, args });\n }\n\n disconnect(): void {\n this.socket?.disconnect();\n this.socket = null;\n }\n\n override normalizeUser(raw: Record<string, unknown>): RoomUser {\n return {\n ...this.extractAppearance(raw),\n id: raw.id as number,\n username: raw.username as string,\n displayName: (raw.nickname as string) ?? (raw.username as string),\n joinTime: raw.joinTime as string | undefined,\n x: (raw.x as number) ?? 0,\n y: (raw.y as number) ?? 0,\n frame: (raw.frame as number) ?? 0,\n meta: {\n toy: raw.toy,\n },\n _raw: raw,\n };\n }\n\n override normalizePlayer(raw: Record<string, unknown>): PlayerData {\n const user = raw.user as Record<string, unknown>;\n const normalized = this.normalizeUser(user);\n return {\n ...normalized,\n _raw: raw,\n coins: (raw.coins as number) ?? 0,\n rank: (raw.rank as number) ?? 0,\n inventory: (raw.inventory as number[]) ?? [],\n furniture: (raw.furniture as unknown[]) ?? [],\n flooring: (raw.flooring as unknown[]) ?? [],\n buddies: (raw.buddies as PlayerData[\"buddies\"]) ?? [],\n buddyRequests: (raw.buddyRequests as number[]) ?? [],\n ignores: (raw.ignores as number[]) ?? [],\n igloos: (raw.igloos as unknown[]) ?? [],\n meta: {\n ...normalized.meta,\n postcards: raw.postcards,\n mascots: raw.mascots,\n pets: raw.pets,\n },\n };\n }\n\n override sendMessage(message: string): void {\n this.send(\"send_message\", { message });\n }\n\n override sendEmote(emote: number): void {\n this.send(\"send_emote\", { emote });\n }\n\n override sendSafe(safe: number): void {\n this.send(\"send_safe\", { safe });\n }\n\n override walk(x: number, y: number): void {\n this.send(\"send_position\", { x, y });\n }\n\n override sendFrame(frame: number, set?: boolean): void {\n this.send(\"send_frame\", { frame, set: set ?? false });\n }\n\n override snowball(x: number, y: number): void {\n this.send(\"snowball\", { x, y });\n }\n\n override joinRoom(room: number, x?: number, y?: number): void {\n this.send(\"join_room\", { room, x: x ?? 0, y: y ?? 0 });\n }\n\n override addItem(item: number): void {\n this.send(\"add_item\", { item });\n }\n\n override equipColor(item: number): void {\n this.send(\"update_player\", { item });\n }\n\n override equipHead(item: number): void {\n this.send(\"update_player\", { item });\n }\n\n override equipFace(item: number): void {\n this.send(\"update_player\", { item });\n }\n\n override equipNeck(item: number): void {\n this.send(\"update_player\", { item });\n }\n\n override equipBody(item: number): void {\n this.send(\"update_player\", { item });\n }\n\n override equipHand(item: number): void {\n this.send(\"update_player\", { item });\n }\n\n override equipFeet(item: number): void {\n this.send(\"update_player\", { item });\n }\n\n override equipFlag(item: number): void {\n this.send(\"update_player\", { item });\n }\n\n override equipPhoto(item: number): void {\n this.send(\"update_player\", { item });\n }\n\n override buddyRequest(id: number): void {\n this.send(\"buddy_request\", { id });\n }\n\n override buddyAccept(id: number): void {\n this.send(\"buddy_accept\", { id });\n }\n\n override addIgnore(id: number): void {\n this.send(\"ignore_add\", { id });\n }\n\n override removeIgnore(id: number): void {\n this.send(\"ignore_remove\", { id });\n }\n\n override getIglooOpen(igloo: number): void {\n this.send(\"get_igloo_open\", { igloo });\n }\n\n override joinIgloo(igloo: number, x?: number, y?: number): void {\n this.send(\"join_igloo\", { igloo, x: x ?? 0, y: y ?? 0 });\n }\n\n override gameOver(coins: number): void {\n this.send(\"game_over\", { coins });\n }\n\n private createSocket(path: string): Socket {\n return io(BASE_URL, {\n path,\n transports: [\"polling\", \"websocket\"],\n reconnection: false,\n });\n }\n}\n","import type { BaseAdapter } from \"./base-adapter.js\";\nimport { CpjourneyAdapter } from \"./cpjourney-adapter.js\";\nimport { CplegacyAdapter } from \"./cplegacy-adapter.js\";\nimport { CpzeroAdapter } from \"./cpzero-adapter.js\";\nimport { NewcpAdapter } from \"./newcp-adapter.js\";\nimport { PenguinoriginsAdapter } from \"./penguinorigins-adapter.js\";\n\nconst ADAPTERS = {\n CPJourney: CpjourneyAdapter,\n CPLegacy: CplegacyAdapter,\n CPZero: CpzeroAdapter,\n NewCP: NewcpAdapter,\n PenguinOrigins: PenguinoriginsAdapter,\n} as const;\n\nexport type AdapterName = keyof typeof ADAPTERS;\n\nexport function createAdapter(name: AdapterName): BaseAdapter {\n return new ADAPTERS[name]();\n}\n","import type { BaseAdapter } from \"../adapters/base-adapter.js\";\nimport type { ServerMessages } from \"../types/message-types.js\";\n\ntype WaitForFn = <K extends keyof ServerMessages>(\n event: K,\n timeout?: number,\n) => Promise<ServerMessages[K]>;\n\nexport class CardJitsu {\n constructor(\n private adapter: BaseAdapter,\n private waitFor: WaitForFn,\n ) {}\n\n /** Fetch ninja rank, progress, and card deck. Resolves with ninja data. */\n getNinja(): Promise<ServerMessages[\"get_ninja\"]> {\n this.adapter.getNinja();\n return this.waitFor(\"get_ninja\");\n }\n\n /** Fetch state of all Dojo mats. Resolves with mat state. */\n getMats(): Promise<ServerMessages[\"get_waddles\"]> {\n this.adapter.getMats();\n return this.waitFor(\"get_waddles\");\n }\n\n /** Sit on a Dojo mat to wait for an opponent. Listen for `update_waddle` events. */\n joinMat(waddle: number): void {\n this.adapter.joinMat(waddle);\n }\n\n /** Join Sensei matchmaking queue. Resolves when server acknowledges. */\n joinMatchmaking(): Promise<ServerMessages[\"join_matchmaking\"]> {\n this.adapter.joinMatchmaking();\n return this.waitFor(\"join_matchmaking\");\n }\n\n /** Leave Sensei matchmaking queue. */\n leaveMatchmaking(): void {\n this.adapter.leaveMatchmaking();\n }\n\n /** Start a Card-Jitsu match after entering a game room. Resolves with player info. */\n startGame(): Promise<ServerMessages[\"start_game\"]> {\n this.adapter.startGame();\n return this.waitFor(\"start_game\");\n }\n\n /** Play a card from your hand by slot index. Resolves when server acknowledges. */\n selectCard(slot: number): Promise<ServerMessages[\"move_my_card\"]> {\n this.adapter.selectCard(slot);\n return this.waitFor(\"move_my_card\");\n }\n\n /** Preload a power card animation asset. */\n loadAnimation(animation: string): void {\n this.adapter.loadAnimation(animation);\n }\n}\n"],"mappings":"AAiBO,IAAeA,EAAf,KAA2B,CAEtB,OAAwB,KAalC,cAAcC,EAAyC,CACrD,MAAM,IAAI,MAAM,gCAAgC,CAClD,CAEA,gBAAgBA,EAA2C,CACzD,MAAM,IAAI,MAAM,kCAAkC,CACpD,CAEU,kBAAkBC,EAAgD,CAC1E,MAAO,CACL,MAAQA,EAAI,OAAoB,EAChC,KAAOA,EAAI,MAAmB,EAC9B,KAAOA,EAAI,MAAmB,EAC9B,KAAOA,EAAI,MAAmB,EAC9B,KAAOA,EAAI,MAAmB,EAC9B,KAAOA,EAAI,MAAmB,EAC9B,KAAOA,EAAI,MAAmB,EAC9B,KAAOA,EAAI,MAAmB,EAC9B,MAAQA,EAAI,OAAoB,CAClC,CACF,CAEA,YAAYC,EAAwB,CAClC,MAAM,IAAI,MAAM,8BAA8B,CAChD,CAEA,UAAUC,EAAsB,CAC9B,MAAM,IAAI,MAAM,4BAA4B,CAC9C,CAEA,SAASC,EAAqB,CAC5B,MAAM,IAAI,MAAM,2BAA2B,CAC7C,CAEA,KAAKC,EAAYC,EAAkB,CACjC,MAAM,IAAI,MAAM,uBAAuB,CACzC,CAEA,UAAUC,EAAgBC,EAAsB,CAC9C,MAAM,IAAI,MAAM,4BAA4B,CAC9C,CAEA,SAASH,EAAYC,EAAkB,CACrC,MAAM,IAAI,MAAM,2BAA2B,CAC7C,CAEA,SAASG,EAAeJ,EAAaC,EAAmB,CACtD,MAAM,IAAI,MAAM,2BAA2B,CAC7C,CAEA,QAAQI,EAAqB,CAC3B,MAAM,IAAI,MAAM,0BAA0B,CAC5C,CAEA,WAAWA,EAAqB,CAC9B,MAAM,IAAI,MAAM,6BAA6B,CAC/C,CAEA,UAAUA,EAAqB,CAC7B,MAAM,IAAI,MAAM,4BAA4B,CAC9C,CAEA,UAAUA,EAAqB,CAC7B,MAAM,IAAI,MAAM,4BAA4B,CAC9C,CAEA,UAAUA,EAAqB,CAC7B,MAAM,IAAI,MAAM,4BAA4B,CAC9C,CAEA,UAAUA,EAAqB,CAC7B,MAAM,IAAI,MAAM,4BAA4B,CAC9C,CAEA,UAAUA,EAAqB,CAC7B,MAAM,IAAI,MAAM,4BAA4B,CAC9C,CAEA,UAAUA,EAAqB,CAC7B,MAAM,IAAI,MAAM,4BAA4B,CAC9C,CAEA,UAAUA,EAAqB,CAC7B,MAAM,IAAI,MAAM,4BAA4B,CAC9C,CAEA,WAAWA,EAAqB,CAC9B,MAAM,IAAI,MAAM,6BAA6B,CAC/C,CAEA,aAAaC,EAAmB,CAC9B,MAAM,IAAI,MAAM,+BAA+B,CACjD,CAEA,YAAYA,EAAmB,CAC7B,MAAM,IAAI,MAAM,8BAA8B,CAChD,CAEA,YAAYA,EAAmB,CAC7B,MAAM,IAAI,MAAM,8BAA8B,CAChD,CAEA,iBAAiBA,EAAmB,CAClC,MAAM,IAAI,MAAM,mCAAmC,CACrD,CAEA,SAASA,EAAaC,EAA0C,CAC9D,MAAM,IAAI,MAAM,2BAA2B,CAC7C,CAEA,YAAYD,EAAmB,CAC7B,MAAM,IAAI,MAAM,8BAA8B,CAChD,CAEA,UAAUA,EAAmB,CAC3B,MAAM,IAAI,MAAM,4BAA4B,CAC9C,CAEA,aAAaA,EAAmB,CAC9B,MAAM,IAAI,MAAM,+BAA+B,CACjD,CAEA,UAAUA,EAAmB,CAC3B,MAAM,IAAI,MAAM,4BAA4B,CAC9C,CAEA,aAAoB,CAClB,MAAM,IAAI,MAAM,8BAA8B,CAChD,CAEA,YAAmB,CACjB,MAAM,IAAI,MAAM,6BAA6B,CAC/C,CAEA,aAAaE,EAAiBC,EAAuB,CACnD,MAAM,IAAI,MAAM,+BAA+B,CACjD,CAEA,UAAUD,EAAuB,CAC/B,MAAM,IAAI,MAAM,4BAA4B,CAC9C,CAEA,cAAqB,CACnB,MAAM,IAAI,MAAM,+BAA+B,CACjD,CAEA,aAAaE,EAAsB,CACjC,MAAM,IAAI,MAAM,+BAA+B,CACjD,CAEA,WAAkB,CAChB,MAAM,IAAI,MAAM,4BAA4B,CAC9C,CAEA,WAAWF,EAAuB,CAChC,MAAM,IAAI,MAAM,6BAA6B,CAC/C,CAEA,eAAsB,CACpB,MAAM,IAAI,MAAM,gCAAgC,CAClD,CAEA,UAAUE,EAAgBV,EAAaC,EAAmB,CACxD,MAAM,IAAI,MAAM,4BAA4B,CAC9C,CAEA,SAASU,EAAsB,CAC7B,MAAM,IAAI,MAAM,2BAA2B,CAC7C,CAEA,aAAaC,EAAsB,CACjC,MAAM,IAAI,MAAM,+BAA+B,CACjD,CAGA,UAAiB,CACf,MAAM,IAAI,MAAM,2BAA2B,CAC7C,CAGA,SAAgB,CACd,MAAM,IAAI,MAAM,0BAA0B,CAC5C,CAGA,iBAAwB,CACtB,MAAM,IAAI,MAAM,kCAAkC,CACpD,CAGA,kBAAyB,CACvB,MAAM,IAAI,MAAM,mCAAmC,CACrD,CAGA,WAAkB,CAChB,MAAM,IAAI,MAAM,4BAA4B,CAC9C,CAGA,WAAWC,EAAqB,CAC9B,MAAM,IAAI,MAAM,6BAA6B,CAC/C,CAGA,cAAcC,EAA0B,CACtC,MAAM,IAAI,MAAM,gCAAgC,CAClD,CAGA,QAAQC,EAAuB,CAC7B,MAAM,IAAI,MAAM,0BAA0B,CAC5C,CACF,ECrPA,OAAS,gBAAAC,OAAoB,SCA7B,OAAS,MAAAC,MAAuB,mBAChC,OAAOC,MAAmB,2BAW1B,IAAMC,EAAW,2BACXC,EAAiB,OAqBVC,EAAN,cAA+BC,CAAY,CACvC,GAAK,YAEd,MAAM,MAAMC,EAAiE,CAC3E,IAAMC,EAAc,KAAK,aAAa,eAAe,EAuDrD,OArDe,MAAM,IAAI,QAAqB,CAACC,EAASC,IAAW,CACjE,IAAMC,EAAU,WAAW,IAAM,CAC/BH,EAAY,WAAW,EACvBE,EAAO,IAAI,MAAM,iBAAiB,CAAC,CACrC,EAAG,GAAM,EAETF,EAAY,GAAG,UAAW,IAAM,CAC9B,IAAMI,EAASL,EAAQ,QAAUH,EAC3BS,EACJ,UAAWN,EACP,CAAE,SAAUA,EAAQ,SAAU,MAAOA,EAAQ,MAAO,OAAAK,CAAO,EAC3D,CACE,SAAUL,EAAQ,SAClB,SAAUA,EAAQ,SAClB,OAAAK,CACF,EAENJ,EAAY,KAAK,UAAW,CAAE,OAAQ,QAAS,KAAAK,CAAK,CAAC,CACvD,CAAC,EAEDL,EAAY,GAAG,UAAYM,GAAuB,CAChD,GAAIA,EAAI,SAAW,QAAS,OAE5B,aAAaH,CAAO,EACpBH,EAAY,WAAW,EAEvB,IAAMO,EAAWD,EAAI,KAErB,GAAI,CAACC,EAAS,QAAS,CACrBL,EAAO,IAAI,MAAM,cAAc,CAAC,EAChC,MACF,CAEA,IAAMM,EAAwB,OAAO,QAAQD,EAAS,WAAW,EAAE,IACjE,CAAC,CAACE,EAAMC,CAAU,KAAO,CAAE,KAAAD,EAAM,WAAAC,CAAW,EAC9C,EAEAT,EAAQ,CACN,QAAAO,EACA,IAAKD,EAAS,IACd,SAAUA,EAAS,SACnB,UAAWA,EAAS,UACpB,YAAaA,EAAS,aAAe,CAAC,CACxC,CAAC,CACH,CAAC,EAEDP,EAAY,GAAG,gBAAkBW,GAAe,CAC9C,aAAaR,CAAO,EACpBH,EAAY,WAAW,EACvBE,EAAO,IAAI,MAAM,4BAA4BS,EAAI,OAAO,EAAE,CAAC,CAC7D,CAAC,CACH,CAAC,CAGH,CAEA,MAAM,QACJC,EACAC,EACAd,EACiB,CAGjB,MAAM,KAAK,eAAea,EAAYb,CAAO,EAI7C,IAAMe,EAAa,KAAK,aAAa,UAAUF,EAAW,YAAY,CAAC,GAAG,EAC1E,YAAK,OAASE,EAEd,MAAM,IAAI,QAAc,CAACb,EAASC,IAAW,CAC3C,IAAIa,EAAW,GAEfD,EAAW,GAAG,UAAW,IAAM,CAC7BA,EAAW,KAAK,UAAW,CACzB,OAAQ,YACR,KAAM,CACJ,SAAUD,EAAY,SACtB,IAAKA,EAAY,IACjB,YAAa,GACb,UAAW,GACX,eAAgB,GAChB,MAAO,EACT,CACF,CAAC,CACH,CAAC,EAEDC,EAAW,GAAG,UAAYR,GAAuB,CAC/C,OAAQA,EAAI,OAAQ,CAClB,IAAK,oBAAqB,CACxBP,GAAS,gBAAgBO,EAAI,IAAmB,EAChD,KACF,CACA,IAAK,YAAa,CAChB,GAAIS,EAAU,MAId,GAHAA,EAAW,GAGP,CADaT,EAAI,KACP,QAAS,CACrBQ,EAAW,WAAW,EACtBZ,EAAO,IAAI,MAAM,kBAAkB,CAAC,EACpC,MACF,CAEAY,EAAW,KAAK,UAAW,CACzB,OAAQ,cACR,KAAM,CAAC,CACT,CAAC,EACDb,EAAQ,EACR,KACF,CACF,CACF,CAAC,EAEDa,EAAW,GAAG,gBAAkBH,GAAe,CAC7CG,EAAW,WAAW,EACtBZ,EAAO,IAAI,MAAM,2BAA2BS,EAAI,OAAO,EAAE,CAAC,CAC5D,CAAC,CACH,CAAC,EAEMG,CACT,CAEA,MAAc,eACZF,EACAb,EACe,CACf,IAAMiB,EAAc,KAAK,aAAa,eAAe,EAErD,MAAM,IAAI,QAAc,CAACf,EAASC,IAAW,CAC3C,IAAMC,EAAU,WAAW,IAAM,CAC/Ba,EAAY,WAAW,EACvBd,EAAO,IAAI,MAAM,iBAAiB,CAAC,CACrC,EAAG,GAAM,EAETc,EAAY,GAAG,UAAW,IAAM,CAC9BA,EAAY,KAAK,UAAW,CAC1B,OAAQ,oBACR,KAAM,CAAE,OAAQJ,CAAW,CAC7B,CAAC,CACH,CAAC,EAEDI,EAAY,GAAG,UAAYV,GAAuB,CAChD,OAAQA,EAAI,OAAQ,CAClB,IAAK,oBACHP,GAAS,gBAAgBO,EAAI,IAAmB,EAChD,MACF,IAAK,oBACH,aAAaH,CAAO,EACpBa,EAAY,WAAW,EACvBf,EAAQ,EACR,KACJ,CACF,CAAC,EAEDe,EAAY,KAAK,aAAc,IAAM,CACnC,aAAab,CAAO,EACpBF,EAAQ,CACV,CAAC,EAEDe,EAAY,GAAG,gBAAkBL,GAAe,CAC9C,aAAaR,CAAO,EACpBa,EAAY,WAAW,EACvBd,EAAO,IAAI,MAAM,4BAA4BS,EAAI,OAAO,EAAE,CAAC,CAC7D,CAAC,CACH,CAAC,CACH,CAEA,KAAKM,EAAgBZ,EAAqC,CACxD,GAAI,CAAC,KAAK,OAAQ,MAAM,IAAI,MAAM,eAAe,EACjD,KAAK,OAAO,KAAK,UAAW,CAAE,OAAAY,EAAQ,KAAAZ,CAAK,CAAC,CAC9C,CAEA,YAAmB,CACjB,KAAK,QAAQ,WAAW,EACxB,KAAK,OAAS,IAChB,CAES,cAAca,EAAwC,CAC7D,GAAM,CAAE,GAAAC,EAAI,SAAAC,EAAU,YAAAC,EAAa,SAAAC,EAAU,EAAAC,EAAG,EAAAC,EAAG,MAAAC,EAAO,QAAAC,EACxD,MAAAC,EAAO,KAAAC,EAAM,KAAAC,EAAM,KAAAC,EAAM,KAAAC,EAAM,KAAAC,EAAM,KAAAC,EAAM,KAAAC,EAAM,MAAAC,EACjD,GAAGC,CAAK,EAAIlB,EACd,MAAO,CACL,GAAG,KAAK,kBAAkBA,CAAG,EAC7B,GAAIC,EACJ,SAAUC,EACV,YAAaC,EACb,SAAUC,EACV,EAAIC,GAAgB,EACpB,EAAIC,GAAgB,EACpB,MAAQC,GAAoB,EAC5B,QAASC,EACT,KAAMU,EACN,KAAMlB,CACR,CACF,CAES,gBAAgBA,EAA0C,CACjE,IAAMmB,EAAOnB,EAAI,KACXoB,EAAa,KAAK,cAAcD,CAAI,EACpC,CAAE,KAAME,EAAO,MAAAC,EAAO,KAAAC,EAAM,UAAAC,EAAW,UAAAC,EAAW,SAAAC,EACtD,QAAAC,EAAS,cAAAC,EAAe,QAAAC,EAAS,OAAAC,EAAQ,GAAGZ,CAAK,EAAIlB,EACvD,MAAO,CACL,GAAGoB,EACH,KAAMpB,EACN,MAAQsB,GAAoB,EAC5B,KAAOC,GAAmB,EAC1B,UAAYC,GAA0B,CAAC,EACvC,UAAYC,GAA2B,CAAC,EACxC,SAAWC,GAA0B,CAAC,EACtC,QAAUP,EAAK,SAAuB,CAAC,EACvC,cAAgBA,EAAK,eAA8B,CAAC,EACpD,QAAUA,EAAK,SAAwB,CAAC,EACxC,OAASW,GAAwB,CAAC,EAClC,KAAM,CAAE,GAAGV,EAAW,KAAM,GAAGF,CAAK,CACtC,CACF,CAES,YAAYa,EAAuB,CAC1C,KAAK,KAAK,eAAgB,CAAE,QAAAA,CAAQ,CAAC,CACvC,CAES,UAAUC,EAAqB,CACtC,KAAK,KAAK,aAAc,CAAE,MAAAA,CAAM,CAAC,CACnC,CAES,SAASC,EAAoB,CACpC,KAAK,KAAK,YAAa,CAAE,KAAAA,CAAK,CAAC,CACjC,CAES,KAAK5B,EAAWC,EAAiB,CACxC,KAAK,KAAK,gBAAiB,CAAE,EAAAD,EAAG,EAAAC,CAAE,CAAC,CACrC,CAES,UAAUC,EAAe2B,EAAqB,CACrD,KAAK,KAAK,aAAc,CAAE,MAAA3B,EAAO,IAAA2B,CAAI,CAAC,CACxC,CAES,SAAS7B,EAAWC,EAAiB,CAC5C,KAAK,KAAK,WAAY,CAAE,EAAAD,EAAG,EAAAC,CAAE,CAAC,CAChC,CAES,SAAS6B,EAAc9B,EAAYC,EAAkB,CAC5D,KAAK,KAAK,YAAa,CAAE,KAAA6B,EAAM,EAAG9B,GAAK,EAAG,EAAGC,GAAK,CAAE,CAAC,CACvD,CAES,QAAQ8B,EAAoB,CACnC,KAAK,KAAK,WAAY,CAAE,KAAAA,CAAK,CAAC,CAChC,CAES,WAAWA,EAAoB,CACtC,KAAK,KAAK,eAAgB,CAAE,KAAAA,CAAK,CAAC,CACpC,CAES,UAAUA,EAAoB,CACrC,KAAK,KAAK,cAAe,CAAE,KAAAA,CAAK,CAAC,CACnC,CAES,UAAUA,EAAoB,CACrC,KAAK,KAAK,cAAe,CAAE,KAAAA,CAAK,CAAC,CACnC,CAES,UAAUA,EAAoB,CACrC,KAAK,KAAK,cAAe,CAAE,KAAAA,CAAK,CAAC,CACnC,CAES,UAAUA,EAAoB,CACrC,KAAK,KAAK,cAAe,CAAE,KAAAA,CAAK,CAAC,CACnC,CAES,UAAUA,EAAoB,CACrC,KAAK,KAAK,cAAe,CAAE,KAAAA,CAAK,CAAC,CACnC,CAES,UAAUA,EAAoB,CACrC,KAAK,KAAK,cAAe,CAAE,KAAAA,CAAK,CAAC,CACnC,CAES,UAAUA,EAAoB,CACrC,KAAK,KAAK,cAAe,CAAE,KAAAA,CAAK,CAAC,CACnC,CAES,WAAWA,EAAoB,CACtC,KAAK,KAAK,eAAgB,CAAE,KAAAA,CAAK,CAAC,CACpC,CAES,aAAanC,EAAkB,CACtC,KAAK,KAAK,gBAAiB,CAAE,GAAAA,CAAG,CAAC,CACnC,CAES,YAAYA,EAAkB,CACrC,KAAK,KAAK,eAAgB,CAAE,GAAAA,CAAG,CAAC,CAClC,CAES,YAAYA,EAAkB,CACrC,KAAK,KAAK,eAAgB,CAAE,GAAAA,CAAG,CAAC,CAClC,CAES,iBAAiBA,EAAkB,CAC1C,KAAK,KAAK,qBAAsB,CAAE,GAAAA,CAAG,CAAC,CACxC,CAES,SAASA,EAAYoC,EAAyC,CACrE,KAAK,KAAK,YAAa,CAAE,GAAApC,EAAI,KAAAoC,CAAK,CAAC,CACrC,CAES,YAAYpC,EAAkB,CACrC,KAAK,KAAK,eAAgB,CAAE,GAAAA,CAAG,CAAC,CAClC,CAES,UAAUA,EAAkB,CACnC,KAAK,KAAK,aAAc,CAAE,GAAAA,CAAG,CAAC,CAChC,CAES,aAAaA,EAAkB,CACtC,KAAK,KAAK,gBAAiB,CAAE,GAAAA,CAAG,CAAC,CACnC,CAES,UAAUA,EAAkB,CACnC,KAAK,KAAK,aAAc,CAAE,GAAAA,CAAG,CAAC,CAChC,CAES,aAAoB,CAC3B,KAAK,KAAK,gBAAiB,CAAC,CAAC,CAC/B,CAES,YAAmB,CAC1B,KAAK,KAAK,cAAe,CAAC,CAAC,CAC7B,CAES,aAAaqC,EAAgBC,EAAsB,CAC1D,KAAK,KAAK,gBAAiB,CAAE,OAAAD,EAAQ,OAAAC,CAAO,CAAC,CAC/C,CAES,UAAUD,EAAsB,CACvC,KAAK,KAAK,aAAc,CAAE,OAAAA,CAAO,CAAC,CACpC,CAES,cAAqB,CAC5B,KAAK,KAAK,gBAAiB,CAAC,CAAC,CAC/B,CAES,aAAaE,EAAqB,CACzC,KAAK,KAAK,iBAAkB,CAAE,MAAAA,CAAM,CAAC,CACvC,CAES,WAAkB,CACzB,KAAK,KAAK,aAAc,CAAC,CAAC,CAC5B,CAES,WAAWF,EAAsB,CACxC,KAAK,KAAK,cAAe,CAAE,OAAAA,CAAO,CAAC,CACrC,CAES,eAAsB,CAC7B,KAAK,KAAK,kBAAmB,CAAC,CAAC,CACjC,CAES,UAAUE,EAAenC,EAAYC,EAAkB,CAC9D,KAAK,KAAK,aAAc,CAAE,MAAAkC,EAAO,EAAGnC,GAAK,EAAG,EAAGC,GAAK,CAAE,CAAC,CACzD,CAES,SAASgB,EAAqB,CACrC,KAAK,KAAK,YAAa,CAAE,MAAAA,CAAM,CAAC,CAClC,CAES,aAAamB,EAAqB,CACzC,KAAK,KAAK,gBAAiB,CAAE,MAAAA,CAAM,CAAC,CACtC,CAES,UAAiB,CACxB,KAAK,KAAK,YAAa,CAAC,CAAC,CAC3B,CAES,SAAgB,CACvB,KAAK,KAAK,cAAe,CAAC,CAAC,CAC7B,CAES,iBAAwB,CAC/B,KAAK,KAAK,mBAAoB,CAAC,CAAC,CAClC,CAES,kBAAyB,CAChC,KAAK,KAAK,oBAAqB,CAAC,CAAC,CACnC,CAES,WAAkB,CACzB,KAAK,KAAK,aAAc,CAAC,CAAC,CAC5B,CAES,WAAWC,EAAoB,CACtC,KAAK,KAAK,cAAe,CAAE,KAAAA,CAAK,CAAC,CACnC,CAES,cAAcC,EAAyB,CAC9C,KAAK,KAAK,iBAAkB,CAAE,UAAAA,CAAU,CAAC,CAC3C,CAES,QAAQC,EAAsB,CACrC,KAAK,KAAK,cAAe,CAAE,OAAAA,CAAO,CAAC,CACrC,CAEQ,aAAaC,EAAsB,CACzC,OAAOC,EAAGrE,EAAU,CAClB,KAAAoE,EACA,OAAQE,EACR,WAAY,CAAC,UAAW,WAAW,EACnC,aAAc,EAChB,CAAC,CACH,CACF,EClcA,OAAS,MAAAC,MAAuB,mBAChC,OAAOC,MAAmB,2BAW1B,IAAMC,EAAY,iCACZC,EAAkB,uCAqBxB,SAASC,EAAWC,EAAqB,CACvC,IAAMC,EAAWD,EAAI,GAAG,KAAKA,CAAG,EAEhC,OAAAA,EAAI,IAAM,CAACE,EAAeC,IACpBD,IAAU,UACLD,EAASC,EAAO,CAACE,EAAiBC,IAAkB,CACzDF,EAAS,CAAE,OAAAC,EAAQ,KAAMC,GAAQ,CAAC,CAAE,CAAC,CACvC,CAAC,EAEIJ,EAASC,EAAOC,CAAQ,GAG1BH,CACT,CAEO,IAAMM,EAAN,cAA8BC,CAAY,CACtC,GAAK,WACN,QAAU,GAElB,MAAM,MAAMC,EAAiE,CAC3E,IAAMC,EAAM,UAAWD,EAAUV,EAAkBD,EAC7Ca,EACJ,UAAWF,EACP,CAAE,SAAUA,EAAQ,SAAU,MAAOA,EAAQ,KAAM,EACnD,CACE,SAAUA,EAAQ,SAClB,SAAUA,EAAQ,SAClB,QAAS,KAAK,OAChB,EAEFG,EAAO,MAAM,KAAK,UAAUF,EAAKC,CAAI,EASzC,GANI,CAACC,EAAK,SAAWA,EAAK,gBACxB,KAAK,QAAUA,EAAK,cACpBD,EAAK,QAAU,KAAK,QACpBC,EAAO,MAAM,KAAK,UAAUF,EAAKC,CAAI,GAGnC,CAACC,EAAK,QACR,MAAM,IAAI,MAAM,iBAAiBA,EAAK,SAAW,eAAe,EAAE,EAOpE,MAAO,CACL,QAL4B,OAAO,QAAQA,EAAK,aAAe,CAAC,CAAC,EAAE,IACnE,CAAC,CAACC,EAAMC,CAAU,KAAO,CAAE,KAAAD,EAAM,WAAAC,CAAW,EAC9C,EAIE,IAAKF,EAAK,IACV,SAAUA,EAAK,SACf,UAAW,GACX,YAAa,CAAC,CAChB,CACF,CAEA,MAAM,QACJG,EACAC,EACAP,EACiB,CACjB,IAAMQ,EAAQ,SAASF,EAAW,YAAY,CAAC,uBACzCG,EAAYC,EAAGF,EAAO,CAC1B,KAAM,cACN,OAAQG,EACR,WAAY,CAAC,WAAW,EACxB,aAAc,EAChB,CAAC,EACD,YAAK,OAASF,EAEd,MAAM,IAAI,QAAc,CAACG,EAASC,IAAW,CAC3C,IAAMC,EAAU,WAAW,IAAM,CAC/BL,EAAU,WAAW,EACrBI,EAAO,IAAI,MAAM,2BAA2B,CAAC,CAC/C,EAAG,IAAM,EAETJ,EAAU,GAAG,UAAW,IAAM,CAC5BA,EAAU,KAAK,UAAW,YAAa,CACrC,SAAUF,EAAY,SACtB,IAAKA,EAAY,IACjB,YAAa,GACb,MAAO,EACT,CAAC,CACH,CAAC,EAEDE,EAAU,GACR,UACA,CAACb,EAAgBC,IAAkC,CACjD,OAAQD,EAAQ,CACd,IAAK,oBAAqB,CACxBI,GAAS,gBAAgBH,CAA8B,EACvD,KACF,CACA,IAAK,YAAa,CAEhB,GAAI,CADaA,EACH,QAAS,CACrB,aAAaiB,CAAO,EACpBL,EAAU,WAAW,EACrBI,EAAO,IAAI,MAAM,kBAAkB,CAAC,EACpC,MACF,CAGAJ,EAAU,KAAK,UAAW,cAAe,CAAC,CAAC,EAC3CA,EAAU,KAAK,UAAW,cAAe,CAAC,CAAC,EAC3C,aAAaK,CAAO,EACpBF,EAAQ,EACR,KACF,CACF,CACF,CACF,EAEAH,EAAU,GAAG,gBAAkBM,GAAe,CAC5C,aAAaD,CAAO,EACpBL,EAAU,WAAW,EACrBI,EAAO,IAAI,MAAM,2BAA2BE,EAAI,OAAO,EAAE,CAAC,CAC5D,CAAC,CACH,CAAC,EAGMxB,EAAWkB,CAAS,CAC7B,CAEA,KAAKb,EAAgBC,EAAqC,CACxD,GAAI,CAAC,KAAK,OAAQ,MAAM,IAAI,MAAM,eAAe,EACjD,KAAK,OAAO,KAAK,UAAWD,EAAQC,CAAI,CAC1C,CAEA,YAAmB,CACjB,KAAK,QAAQ,WAAW,EACxB,KAAK,OAAS,IAChB,CAES,cAAcL,EAAwC,CAC7D,MAAO,CACL,GAAG,KAAK,kBAAkBA,CAAG,EAC7B,GAAIA,EAAI,GACR,SAAUA,EAAI,SACd,YAAcA,EAAI,cAA4BA,EAAI,SAClD,SAAUA,EAAI,SACd,EAAIA,EAAI,GAAgB,EACxB,EAAIA,EAAI,GAAgB,EACxB,MAAQA,EAAI,OAAoB,EAChC,QAAUA,EAAI,SAAsB,OACpC,KAAM,CACJ,iBAAkBA,EAAI,SACtB,SAAUA,EAAI,SACd,cAAeA,EAAI,cACnB,SAAUA,EAAI,SACd,SAAUA,EAAI,SACd,YAAaA,EAAI,YACjB,aAAcA,EAAI,aAClB,eAAgBA,EAAI,eACpB,eAAgBA,EAAI,eACpB,iBAAkBA,EAAI,iBACtB,YAAaA,EAAI,YACjB,iBAAkBA,EAAI,iBACtB,UAAWA,EAAI,UACf,YAAaA,EAAI,WACnB,EACA,KAAMA,CACR,CACF,CAES,gBAAgBA,EAA0C,CACjE,IAAMwB,EAAOxB,EAAI,KACjB,MAAO,CACL,GAAG,KAAK,cAAcwB,CAAI,EAC1B,KAAMxB,EACN,MAAQwB,EAAK,OAAoB,EACjC,KAAOA,EAAK,MAAmB,EAC/B,UAAYxB,EAAI,WAA0B,CAAC,EAC3C,UAAWA,EAAI,UACf,QAAS,CAAC,EACV,cACGA,EAAI,SAAiC,IAAKyB,GAAMA,EAAE,EAAE,GAAK,CAAC,EAC7D,QAAS,CAAC,EACV,OAASzB,EAAI,QAAwB,CAAC,CACxC,CACF,CAES,YAAY0B,EAAuB,CAC1C,KAAK,KAAK,eAAgB,CAAE,QAAAA,CAAQ,CAAC,CACvC,CAES,UAAUC,EAAqB,CACtC,KAAK,KAAK,aAAc,CAAE,MAAAA,CAAM,CAAC,CACnC,CAES,SAASC,EAAoB,CACpC,KAAK,KAAK,YAAa,CAAE,KAAAA,CAAK,CAAC,CACjC,CAES,KAAKC,EAAWC,EAAiB,CACxC,KAAK,KAAK,gBAAiB,CAAE,EAAAD,EAAG,EAAAC,CAAE,CAAC,CACrC,CAES,UAAUC,EAAeC,EAAqB,CACrD,KAAK,KAAK,aAAc,CAAE,MAAAD,EAAO,IAAAC,CAAI,CAAC,CACxC,CAES,SAASH,EAAWC,EAAiB,CAC5C,KAAK,KAAK,WAAY,CAAE,EAAAD,EAAG,EAAAC,CAAE,CAAC,CAChC,CAES,SAASG,EAAcJ,EAAYC,EAAkB,CAC5D,KAAK,KAAK,YAAa,CAAE,KAAAG,EAAM,EAAGJ,GAAK,EAAG,EAAGC,GAAK,CAAE,CAAC,CACvD,CAES,QAAQI,EAAoB,CACnC,KAAK,KAAK,WAAY,CAAE,KAAAA,CAAK,CAAC,CAChC,CAES,WAAWA,EAAoB,CACtC,KAAK,KAAK,eAAgB,CAAE,KAAAA,CAAK,CAAC,CACpC,CAES,UAAUA,EAAoB,CACrC,KAAK,KAAK,cAAe,CAAE,KAAAA,CAAK,CAAC,CACnC,CAES,UAAUA,EAAoB,CACrC,KAAK,KAAK,cAAe,CAAE,KAAAA,CAAK,CAAC,CACnC,CAES,UAAUA,EAAoB,CACrC,KAAK,KAAK,cAAe,CAAE,KAAAA,CAAK,CAAC,CACnC,CAES,UAAUA,EAAoB,CACrC,KAAK,KAAK,cAAe,CAAE,KAAAA,CAAK,CAAC,CACnC,CAES,UAAUA,EAAoB,CACrC,KAAK,KAAK,cAAe,CAAE,KAAAA,CAAK,CAAC,CACnC,CAES,UAAUA,EAAoB,CACrC,KAAK,KAAK,cAAe,CAAE,KAAAA,CAAK,CAAC,CACnC,CAES,UAAUA,EAAoB,CACrC,KAAK,KAAK,cAAe,CAAE,KAAAA,CAAK,CAAC,CACnC,CAES,WAAWA,EAAoB,CACtC,KAAK,KAAK,eAAgB,CAAE,KAAAA,CAAK,CAAC,CACpC,CAES,aAAaC,EAAkB,CACtC,KAAK,KAAK,gBAAiB,CAAE,GAAAA,CAAG,CAAC,CACnC,CAES,YAAYA,EAAkB,CACrC,KAAK,KAAK,eAAgB,CAAE,GAAAA,CAAG,CAAC,CAClC,CAES,YAAYA,EAAkB,CACrC,KAAK,KAAK,eAAgB,CAAE,GAAAA,CAAG,CAAC,CAClC,CAES,YAAYA,EAAkB,CACrC,KAAK,KAAK,eAAgB,CAAE,GAAAA,CAAG,CAAC,CAClC,CAES,UAAUA,EAAkB,CACnC,KAAK,KAAK,aAAc,CAAE,GAAAA,CAAG,CAAC,CAChC,CAES,aAAaA,EAAkB,CACtC,KAAK,KAAK,gBAAiB,CAAE,GAAAA,CAAG,CAAC,CACnC,CAES,UAAUA,EAAkB,CACnC,KAAK,KAAK,aAAc,CAAE,GAAAA,CAAG,CAAC,CAChC,CAES,UAAUC,EAAsB,CACvC,KAAK,KAAK,aAAc,CAAE,OAAAA,CAAO,CAAC,CACpC,CAES,cAAqB,CAC5B,KAAK,KAAK,gBAAiB,CAAC,CAAC,CAC/B,CAES,UAAUC,EAAeR,EAAYC,EAAkB,CAC9D,KAAK,KAAK,aAAc,CAAE,MAAAO,EAAO,EAAGR,GAAK,EAAG,EAAGC,GAAK,CAAE,CAAC,CACzD,CAES,SAASQ,EAAqB,CACrC,KAAK,KAAK,YAAa,CAAE,MAAAA,CAAM,CAAC,CAClC,CAES,aAAaC,EAAqB,CACzC,KAAK,KAAK,gBAAiB,CAAE,MAAAA,CAAM,CAAC,CACtC,CAEA,MAAc,UACZ9B,EACAC,EACwB,CAUxB,OATa,MAAM,MAAMD,EAAK,CAC5B,OAAQ,OACR,QAAS,CACP,eAAgB,mBAChB,OAAQ,kBACV,EACA,KAAM,KAAK,UAAUC,CAAI,CAC3B,CAAC,GAEW,KAAK,CACnB,CACF,EC3VA,OAAS,cAAA8B,MAAkB,SAC3B,OAAS,gBAAAC,MAAoB,SAC7B,OAAOC,MAAe,KAStB,IAAMC,EAAe,gCACfC,GAAc,mCACdC,EAAc,MACdC,EAAa,KACbC,EAAM,KAMNC,EAAI,CACR,GAAI,EACJ,SAAU,EAEV,MAAO,EACP,KAAM,EACN,KAAM,EACN,KAAM,EACN,KAAM,EACN,KAAM,EACN,KAAM,EACN,MAAO,GACP,MAAO,GACP,KAAM,GACN,KAAM,GACN,KAAM,GACN,MAAO,GACP,KAAM,GACN,MAAO,GACP,EAAG,GACH,EAAG,GACH,MAAO,GAEP,KAAM,EACR,EAEA,SAASC,GAAIC,EAAuB,CAClC,OAAOC,EAAW,KAAK,EAAE,OAAOD,CAAK,EAAE,OAAO,KAAK,CACrD,CAGA,SAASE,GAAQF,EAAuB,CACtC,IAAMG,EAAOJ,GAAIC,CAAK,EACtB,OAAOG,EAAK,UAAU,GAAI,EAAE,EAAIA,EAAK,UAAU,EAAG,EAAE,CACtD,CAEA,SAASC,EAAIC,EAA+B,CAC1C,IAAMC,EAAI,OAAOD,CAAC,EAClB,OAAO,OAAO,MAAMC,CAAC,EAAI,EAAIA,CAC/B,CAMA,SAASC,EAAgBC,EAAsC,CAC7D,IAAMC,EAAID,EAAI,MAAM,GAAG,EACvB,MAAO,CACL,GAAIJ,EAAIK,EAAEX,EAAE,EAAE,CAAC,EACf,SAAUW,EAAEX,EAAE,QAAQ,GAAK,GAC3B,MAAOM,EAAIK,EAAEX,EAAE,KAAK,CAAC,EACrB,KAAMM,EAAIK,EAAEX,EAAE,IAAI,CAAC,EACnB,KAAMM,EAAIK,EAAEX,EAAE,IAAI,CAAC,EACnB,KAAMM,EAAIK,EAAEX,EAAE,IAAI,CAAC,EACnB,KAAMM,EAAIK,EAAEX,EAAE,IAAI,CAAC,EACnB,KAAMM,EAAIK,EAAEX,EAAE,IAAI,CAAC,EACnB,KAAMM,EAAIK,EAAEX,EAAE,IAAI,CAAC,EACnB,MAAOM,EAAIK,EAAEX,EAAE,KAAK,CAAC,EACrB,MAAOM,EAAIK,EAAEX,EAAE,KAAK,CAAC,EACrB,KAAMM,EAAIK,EAAEX,EAAE,IAAI,CAAC,EACnB,KAAMM,EAAIK,EAAEX,EAAE,IAAI,CAAC,EACnB,KAAMM,EAAIK,EAAEX,EAAE,IAAI,CAAC,EACnB,MAAOM,EAAIK,EAAEX,EAAE,KAAK,CAAC,EACrB,KAAMM,EAAIK,EAAEX,EAAE,IAAI,CAAC,EACnB,MAAOM,EAAIK,EAAEX,EAAE,KAAK,CAAC,EACrB,EAAGM,EAAIK,EAAEX,EAAE,CAAC,CAAC,EACb,EAAGM,EAAIK,EAAEX,EAAE,CAAC,CAAC,EACb,MAAOM,EAAIK,EAAEX,EAAE,KAAK,CAAC,EACrB,KAAMM,EAAIK,EAAEX,EAAE,IAAI,CAAC,CACrB,CACF,CAOA,IAAMY,EAAN,cAA6BC,CAAa,CAChC,GACA,QAAU,GACV,WAAa,GACb,QAA+D,CAAC,EAExE,YAAYC,EAAe,CACzB,MAAM,EACN,KAAK,GAAKA,EAEVA,EAAG,GAAG,QAAS,IAAM,CACnB,KAAK,QAAU,GACf,KAAK,KAAK,YAAY,CACxB,CAAC,EAEDA,EAAG,GAAG,QAAUC,GAAQ,CACtB,KAAK,KAAK,gBAAiBA,CAAG,CAChC,CAAC,CACH,CAGA,gBAAgBC,EAAgBC,EAAqC,CAC/D,KAAK,YACP,KAAK,QAAQ,KAAK,CAAE,OAAAD,EAAQ,KAAAC,CAAK,CAAC,EAEpC,KAAK,KAAK,UAAW,CAAE,OAAAD,EAAQ,KAAAC,CAAK,CAAC,CACvC,CAOA,OAAc,CACZ,KAAK,WAAa,GAClB,IAAMC,EAAW,KAAK,QACtB,KAAK,QAAU,CAAC,EAChB,WAAW,IAAM,CACf,QAAWC,KAAOD,EAChB,KAAK,KAAK,UAAWC,CAAG,CAE5B,EAAG,CAAC,CACN,CAEA,KAAKC,EAAoB,CAClB,KAAK,SAAS,KAAK,GAAG,KAAKA,EAAOrB,CAAG,CAC5C,CAEA,YAAmB,CACZ,KAAK,UACR,KAAK,QAAU,GACf,KAAK,GAAG,MAAM,EAElB,CAEA,IAAI,WAAqB,CACvB,MAAO,CAAC,KAAK,SAAW,KAAK,GAAG,aAAesB,EAAU,IAC3D,CACF,EAMA,SAASC,GACPC,EACAC,EAC0D,CAC1D,OAAQD,EAAK,CACX,IAAK,KAAM,CAET,IAAME,EAAOhB,EAAgBe,EAAM,CAAC,GAAK,EAAE,EACrCE,EAAQpB,EAAIkB,EAAM,CAAC,CAAC,EACpBG,EAAOF,EAAK,KAClB,MAAO,CACL,OAAQ,cACR,KAAM,CAAE,KAAAA,EAAM,MAAAC,EAAO,KAAAC,CAAK,CAC5B,CACF,CAEA,IAAK,KAAM,CAET,IAAMC,EAAOtB,EAAIkB,EAAM,CAAC,CAAC,EACnBK,EAAQL,EAAM,MAAM,CAAC,EAAE,OAAO,OAAO,EAAE,IAAIf,CAAe,EAChE,MAAO,CAAE,OAAQ,YAAa,KAAM,CAAE,KAAAmB,EAAM,MAAAC,CAAM,CAAE,CACtD,CAEA,IAAK,KAGH,MAAO,CAAE,OAAQ,aAAc,KAAM,CAAE,KAD1BpB,EAAgBe,EAAM,CAAC,GAAK,EAAE,CACC,CAAE,EAGhD,IAAK,KAEH,MAAO,CAAE,OAAQ,gBAAiB,KAAM,CAAE,KAAMlB,EAAIkB,EAAM,CAAC,CAAC,CAAE,CAAE,EAGlE,IAAK,KAEH,MAAO,CACL,OAAQ,gBACR,KAAM,CAAE,GAAIlB,EAAIkB,EAAM,CAAC,CAAC,EAAG,EAAGlB,EAAIkB,EAAM,CAAC,CAAC,EAAG,EAAGlB,EAAIkB,EAAM,CAAC,CAAC,CAAE,CAChE,EAGF,IAAK,KAEH,MAAO,CACL,OAAQ,aACR,KAAM,CAAE,GAAIlB,EAAIkB,EAAM,CAAC,CAAC,EAAG,MAAOlB,EAAIkB,EAAM,CAAC,CAAC,CAAE,CAClD,EAGF,IAAK,KAEH,MAAO,CACL,OAAQ,eACR,KAAM,CAAE,GAAIlB,EAAIkB,EAAM,CAAC,CAAC,EAAG,QAASA,EAAM,CAAC,GAAK,EAAG,CACrD,EAGF,IAAK,KAEH,MAAO,CACL,OAAQ,aACR,KAAM,CAAE,GAAIlB,EAAIkB,EAAM,CAAC,CAAC,EAAG,MAAOlB,EAAIkB,EAAM,CAAC,CAAC,CAAE,CAClD,EAGF,IAAK,KAEH,MAAO,CACL,OAAQ,YACR,KAAM,CAAE,GAAIlB,EAAIkB,EAAM,CAAC,CAAC,EAAG,KAAMlB,EAAIkB,EAAM,CAAC,CAAC,CAAE,CACjD,EAGF,IAAK,KAEH,MAAO,CACL,OAAQ,WACR,KAAM,CAAE,GAAIlB,EAAIkB,EAAM,CAAC,CAAC,EAAG,EAAGlB,EAAIkB,EAAM,CAAC,CAAC,EAAG,EAAGlB,EAAIkB,EAAM,CAAC,CAAC,CAAE,CAChE,EAGF,IAAK,KAGH,MAAO,CAAE,OAAQ,aAAc,KAAM,CAAE,KAD1Bf,EAAgBe,EAAM,CAAC,GAAK,EAAE,CACC,CAAE,EAIhD,IAAK,MACH,MAAO,CACL,OAAQ,gBACR,KAAM,CAAE,GAAIlB,EAAIkB,EAAM,CAAC,CAAC,EAAG,KAAMlB,EAAIkB,EAAM,CAAC,CAAC,EAAG,KAAM,OAAQ,CAChE,EACF,IAAK,MACH,MAAO,CACL,OAAQ,gBACR,KAAM,CAAE,GAAIlB,EAAIkB,EAAM,CAAC,CAAC,EAAG,KAAMlB,EAAIkB,EAAM,CAAC,CAAC,EAAG,KAAM,MAAO,CAC/D,EACF,IAAK,MACH,MAAO,CACL,OAAQ,gBACR,KAAM,CAAE,GAAIlB,EAAIkB,EAAM,CAAC,CAAC,EAAG,KAAMlB,EAAIkB,EAAM,CAAC,CAAC,EAAG,KAAM,MAAO,CAC/D,EACF,IAAK,MACH,MAAO,CACL,OAAQ,gBACR,KAAM,CAAE,GAAIlB,EAAIkB,EAAM,CAAC,CAAC,EAAG,KAAMlB,EAAIkB,EAAM,CAAC,CAAC,EAAG,KAAM,MAAO,CAC/D,EACF,IAAK,MACH,MAAO,CACL,OAAQ,gBACR,KAAM,CAAE,GAAIlB,EAAIkB,EAAM,CAAC,CAAC,EAAG,KAAMlB,EAAIkB,EAAM,CAAC,CAAC,EAAG,KAAM,MAAO,CAC/D,EACF,IAAK,MACH,MAAO,CACL,OAAQ,gBACR,KAAM,CAAE,GAAIlB,EAAIkB,EAAM,CAAC,CAAC,EAAG,KAAMlB,EAAIkB,EAAM,CAAC,CAAC,EAAG,KAAM,MAAO,CAC/D,EACF,IAAK,MACH,MAAO,CACL,OAAQ,gBACR,KAAM,CAAE,GAAIlB,EAAIkB,EAAM,CAAC,CAAC,EAAG,KAAMlB,EAAIkB,EAAM,CAAC,CAAC,EAAG,KAAM,MAAO,CAC/D,EACF,IAAK,MACH,MAAO,CACL,OAAQ,gBACR,KAAM,CAAE,GAAIlB,EAAIkB,EAAM,CAAC,CAAC,EAAG,KAAMlB,EAAIkB,EAAM,CAAC,CAAC,EAAG,KAAM,MAAO,CAC/D,EACF,IAAK,MACH,MAAO,CACL,OAAQ,gBACR,KAAM,CAAE,GAAIlB,EAAIkB,EAAM,CAAC,CAAC,EAAG,KAAMlB,EAAIkB,EAAM,CAAC,CAAC,EAAG,KAAM,OAAQ,CAChE,EACF,IAAK,OACH,MAAO,CACL,OAAQ,gBACR,KAAM,CAAE,GAAIlB,EAAIkB,EAAM,CAAC,CAAC,EAAG,KAAMlB,EAAIkB,EAAM,CAAC,CAAC,EAAG,KAAM,MAAO,CAC/D,EACF,IAAK,MACH,MAAO,CACL,OAAQ,gBACR,KAAM,CAAE,GAAIlB,EAAIkB,EAAM,CAAC,CAAC,EAAG,KAAMlB,EAAIkB,EAAM,CAAC,CAAC,EAAG,KAAM,OAAQ,CAChE,EAEF,IAAK,KAEH,MAAO,CACL,OAAQ,WACR,KAAM,CAAE,KAAMlB,EAAIkB,EAAM,CAAC,CAAC,EAAG,MAAOlB,EAAIkB,EAAM,CAAC,CAAC,CAAE,CACpD,EAGF,IAAK,KAEH,MAAO,CAAE,OAAQ,iBAAkB,KAAM,CAAE,KAAMlB,EAAIkB,EAAM,CAAC,CAAC,CAAE,CAAE,EAGnE,IAAK,IAEH,MAAO,CAAE,OAAQ,QAAS,KAAM,CAAE,MAAOA,EAAM,CAAC,GAAK,SAAU,CAAE,EAGnE,QACE,OAAO,IACX,CACF,CAEO,IAAMM,EAAN,cAA4BC,CAAY,CACpC,GAAK,SACN,IAA6B,KAErC,MAAM,MAAMC,EAAiE,CAC3E,GAAI,UAAWA,EACb,MAAM,IAAI,MAAM,qCAAqC,EAGvD,IAAMC,EAAYD,EAAQ,OAC1B,GAAI,CAACC,EACH,MAAM,IAAI,MACR,6DACF,EAGF,IAAMnB,EAAK,IAAIO,EAAU1B,CAAY,EA6ErC,OA5Ee,MAAM,IAAI,QAAqB,CAACuC,EAASC,IAAW,CACjE,IAAMC,EAAU,WAAW,IAAM,CAC/BtB,EAAG,MAAM,EACTqB,EAAO,IAAI,MAAM,iBAAiB,CAAC,CACrC,EAAG,IAAM,EAELE,EAAQ,GAEZvB,EAAG,GAAG,OAAQ,IAAM,CAClBA,EAAG,KAAKwB,EAAO,SAAU,IAAK,WAAWzC,CAAW,MAAM,EAAIE,CAAG,CACnE,CAAC,EAEDe,EAAG,GAAG,UAAYyB,GAAgB,CAChC,IAAMC,EAAWD,EAAI,SAAS,OAAO,EAAE,MAAMxC,CAAG,EAAE,OAAO,OAAO,EAChE,QAAWoB,KAAOqB,EAAU,CAC1B,GACErB,EAAI,SAAS,gBAAgB,GAC7BA,EAAI,SAAS,gBAAgB,EAC7B,CACAL,EAAG,KAAKwB,EAAO,OAAQ,KAAM,EAAE,EAAIvC,CAAG,EACtC,QACF,CAEA,IAAM0C,EAAStB,EAAI,MAAM,eAAe,EACxC,GAAIsB,EAAQ,CACVJ,EAAQI,EAAO,CAAC,EAChB,IAAMC,EAAWC,GAASX,EAAQ,SAAUC,CAAS,EACrDnB,EAAG,KAAK4B,EAAW3C,CAAG,EACtB,QACF,CAEA,GAAIoB,EAAI,WAAW,QAAQ,EAAG,CAC5B,IAAMyB,EAAUzB,EAAI,MAAM,GAAG,EAAE,OAAO,OAAO,EAEvC0B,EAAaD,EAAQ,CAAC,GAAK,GAC3BE,EAAkBF,EAAQ,CAAC,GAAK,GAChCG,EAAaF,EAAW,MAAM,GAAG,EAEvC,aAAaT,CAAO,EACpBtB,EAAG,MAAM,EAET,IAAMkC,EAAS1C,EAAIyC,EAAW,CAAC,CAAC,EAC1BE,EAAWF,EAAW,CAAC,GAAKf,EAAQ,SAC1CE,EAAQ,CACN,QAAS,CAAC,CAAE,KAAM,WAAY,WAAY,CAAE,CAAC,EAC7C,IAAK,GAAGc,CAAM,IAAIH,CAAU,IAAIC,CAAe,GAC/C,SAAAG,EACA,UAAW,GACX,YAAa,CAAC,CAChB,CAAC,EACD,MACF,CAEA,GAAI9B,EAAI,WAAW,QAAQ,EAAG,CAC5B,aAAaiB,CAAO,EACpBtB,EAAG,MAAM,EACT,IAAMoC,EAAW/B,EAAI,MAAM,GAAG,EAAE,OAAO,OAAO,EAC9CgB,EACE,IAAI,MAAM,uBAAuBe,EAAS,CAAC,GAAK,SAAS,EAAE,CAC7D,EACA,MACF,CACF,CACF,CAAC,EAEDpC,EAAG,GAAG,QAAUC,GAAQ,CACtB,aAAaqB,CAAO,EACpBtB,EAAG,MAAM,EACTqB,EAAO,IAAI,MAAM,mBAAoBpB,EAAc,OAAO,EAAE,CAAC,CAC/D,CAAC,EAEDD,EAAG,GAAG,QAAS,IAAM,CACnB,aAAasB,CAAO,CACtB,CAAC,CACH,CAAC,CAGH,CAEA,MAAM,QACJe,EACAC,EACAC,EAC4C,CAE5C,IAAMC,EAAWF,EAAY,IAAI,MAAM,GAAG,EACpCJ,EAASM,EAAS,CAAC,GAAK,GACxBT,EAAaS,EAAS,MAAM,EAAG,EAAE,EAAE,KAAK,GAAG,EAC3CR,EAAkBQ,EAASA,EAAS,OAAS,CAAC,GAAK,GACnDC,EAAWV,EAAW,MAAM,GAAG,EAAE,CAAC,GAAK,GAEvC/B,EAAK,IAAIO,EAAUzB,EAAW,EAC9B4D,EAAM,IAAI5C,EAAeE,CAAE,EACjC,YAAK,IAAM0C,EAEX,KAAK,OAASA,EAEd,MAAM,IAAI,QAAc,CAACtB,EAASC,IAAW,CAC3C,IAAMC,EAAU,WAAW,IAAM,CAC/BtB,EAAG,MAAM,EACTqB,EAAO,IAAI,MAAM,2BAA2B,CAAC,CAC/C,EAAG,IAAM,EAETrB,EAAG,GAAG,OAAQ,IAAM,CAClB0C,EAAI,KAAKlB,EAAO,SAAU,IAAK,WAAWzC,CAAW,MAAM,CAAC,CAC9D,CAAC,EAEDiB,EAAG,GAAG,UAAYyB,GAAgB,CAChC,IAAMC,EAAWD,EAAI,SAAS,OAAO,EAAE,MAAMxC,CAAG,EAAE,OAAO,OAAO,EAChE,QAAWoB,KAAOqB,EAAU,CAE1B,GACErB,EAAI,SAAS,gBAAgB,GAC7BA,EAAI,SAAS,gBAAgB,EAC7B,CACAqC,EAAI,KAAKlB,EAAO,OAAQ,KAAM,EAAE,CAAC,EACjC,QACF,CAEA,IAAMG,EAAStB,EAAI,MAAM,eAAe,EACxC,GAAIsB,EAAQ,CACV,IAAMgB,EAAOhB,EAAO,CAAC,EACfiB,EAAY,GAAGtD,GAAQmD,EAAWE,CAAI,CAAC,GAAGF,CAAQ,IAAIT,CAAe,GAC3EU,EAAI,KAAKG,GAAad,EAAYa,CAAS,CAAC,EAC5C,QACF,CAkBA,GAfIvC,EAAI,WAAW,MAAM,IACvB,KAAK,eAAeA,EAAKqC,CAAG,EAGxBrC,EAAI,SAAS,QAAQ,GACvBqC,EAAI,KAAK,iBAAiBR,CAAM,IAAIO,CAAQ,MAAM,EAIhDpC,EAAI,SAAS,SAAS,IACxB,aAAaiB,CAAO,EACpBF,EAAQ,IAIRf,EAAI,SAAS,QAAQ,EAAG,CAC1B,aAAaiB,CAAO,EACpBtB,EAAG,MAAM,EACT,IAAMoC,EAAW/B,EAAI,MAAM,GAAG,EAAE,OAAO,OAAO,EAC9CgB,EACE,IAAI,MAAM,2BAA2Be,EAAS,CAAC,GAAK,SAAS,EAAE,CACjE,EACA,MACF,CACF,CACF,CAAC,EAEDpC,EAAG,GAAG,QAAUC,GAAQ,CACtB,aAAaqB,CAAO,EACpBD,EAAO,IAAI,MAAM,kBAAmBpB,EAAc,OAAO,EAAE,CAAC,CAC9D,CAAC,CACH,CAAC,EAGDD,EAAG,GAAG,UAAYyB,GAAgB,CAChC,IAAMC,EAAWD,EAAI,SAAS,OAAO,EAAE,MAAMxC,CAAG,EAAE,OAAO,OAAO,EAChE,QAAWoB,KAAOqB,EACZrB,EAAI,WAAW,MAAM,GACvB,KAAK,eAAeA,EAAKqC,CAAG,CAGlC,CAAC,EAGDA,EAAI,MAAM,EAGHA,CACT,CAEA,KAAKxC,EAAgBC,EAAqC,CACxD,GAAI,CAAC,KAAK,IAAK,MAAM,IAAI,MAAM,eAAe,EAC9C,IAAM2C,EAAKC,GAAW7C,EAAQC,CAAI,EAC9B2C,GAAI,KAAK,IAAI,KAAKA,CAAE,CAC1B,CAEA,YAAmB,CACjB,KAAK,KAAK,WAAW,EACrB,KAAK,IAAM,KACX,KAAK,OAAS,IAChB,CAES,cAAcrB,EAAwC,CAC7D,MAAO,CACL,GAAG,KAAK,kBAAkBA,CAAG,EAC7B,GAAIA,EAAI,GACR,SAAUA,EAAI,SACd,EAAIA,EAAI,GAAgB,EACxB,EAAIA,EAAI,GAAgB,EACxB,MAAQA,EAAI,OAAoB,EAChC,KAAM,CACJ,KAAMA,EAAI,KACV,MAAOA,EAAI,MACX,MAAOA,EAAI,MACX,KAAMA,EAAI,KACV,KAAMA,EAAI,KACV,MAAOA,EAAI,MACX,KAAMA,EAAI,IACZ,EACA,KAAMA,CACR,CACF,CAES,gBAAgBA,EAA0C,CACjE,IAAMd,EAAOc,EAAI,KACjB,MAAO,CACL,GAAG,KAAK,cAAcd,CAAI,EAC1B,KAAMc,EACN,MAAQA,EAAI,OAAoB,EAChC,KAAOd,EAAK,MAAmB,EAC/B,UAAW,CAAC,EACZ,QAAS,CAAC,EACV,QAAS,CAAC,CACZ,CACF,CAES,YAAYqC,EAAuB,CAC1C,GAAI,CAAC,KAAK,IAAK,MAAM,IAAI,MAAM,eAAe,EAE9C,KAAK,IAAI,KAAK,mBAA2BA,CAAO,GAAG,CACrD,CAES,UAAUC,EAAqB,CACtC,GAAI,CAAC,KAAK,IAAK,MAAM,IAAI,MAAM,eAAe,EAC9C,KAAK,IAAI,KAAK,iBAAiBA,CAAK,GAAG,CACzC,CAES,SAASC,EAAoB,CACpC,GAAI,CAAC,KAAK,IAAK,MAAM,IAAI,MAAM,eAAe,EAC9C,KAAK,IAAI,KAAK,iBAAiBA,CAAI,GAAG,CACxC,CAES,KAAKC,EAAWC,EAAiB,CACxC,GAAI,CAAC,KAAK,IAAK,MAAM,IAAI,MAAM,eAAe,EAC9C,KAAK,IAAI,KAAK,iBAAiBD,CAAC,IAAIC,CAAC,GAAG,CAC1C,CAES,UAAUC,EAAqB,CACtC,GAAI,CAAC,KAAK,IAAK,MAAM,IAAI,MAAM,eAAe,EAC9C,KAAK,IAAI,KAAK,iBAAiBA,CAAK,GAAG,CACzC,CAES,SAASF,EAAWC,EAAiB,CAC5C,GAAI,CAAC,KAAK,IAAK,MAAM,IAAI,MAAM,eAAe,EAC9C,KAAK,IAAI,KAAK,iBAAiBD,CAAC,IAAIC,CAAC,GAAG,CAC1C,CAES,SAAStC,EAAcqC,EAAYC,EAAkB,CAC5D,GAAI,CAAC,KAAK,IAAK,MAAM,IAAI,MAAM,eAAe,EAC9C,KAAK,IAAI,KAAK,iBAAiBtC,CAAI,IAAIqC,GAAK,CAAC,IAAIC,GAAK,CAAC,GAAG,CAC5D,CAES,QAAQE,EAAoB,CACnC,GAAI,CAAC,KAAK,IAAK,MAAM,IAAI,MAAM,eAAe,EAC9C,KAAK,IAAI,KAAK,iBAAiBA,CAAI,GAAG,CACxC,CAES,WAAWA,EAAoB,CACtC,GAAI,CAAC,KAAK,IAAK,MAAM,IAAI,MAAM,eAAe,EAC9C,KAAK,IAAI,KAAK,kBAAkBA,CAAI,GAAG,CACzC,CAES,UAAUA,EAAoB,CACrC,GAAI,CAAC,KAAK,IAAK,MAAM,IAAI,MAAM,eAAe,EAC9C,KAAK,IAAI,KAAK,kBAAkBA,CAAI,GAAG,CACzC,CAES,UAAUA,EAAoB,CACrC,GAAI,CAAC,KAAK,IAAK,MAAM,IAAI,MAAM,eAAe,EAC9C,KAAK,IAAI,KAAK,kBAAkBA,CAAI,GAAG,CACzC,CAES,UAAUA,EAAoB,CACrC,GAAI,CAAC,KAAK,IAAK,MAAM,IAAI,MAAM,eAAe,EAC9C,KAAK,IAAI,KAAK,kBAAkBA,CAAI,GAAG,CACzC,CAES,UAAUA,EAAoB,CACrC,GAAI,CAAC,KAAK,IAAK,MAAM,IAAI,MAAM,eAAe,EAC9C,KAAK,IAAI,KAAK,kBAAkBA,CAAI,GAAG,CACzC,CAES,UAAUA,EAAoB,CACrC,GAAI,CAAC,KAAK,IAAK,MAAM,IAAI,MAAM,eAAe,EAC9C,KAAK,IAAI,KAAK,kBAAkBA,CAAI,GAAG,CACzC,CAES,UAAUA,EAAoB,CACrC,GAAI,CAAC,KAAK,IAAK,MAAM,IAAI,MAAM,eAAe,EAC9C,KAAK,IAAI,KAAK,kBAAkBA,CAAI,GAAG,CACzC,CAES,UAAUA,EAAoB,CACrC,GAAI,CAAC,KAAK,IAAK,MAAM,IAAI,MAAM,eAAe,EAC9C,KAAK,IAAI,KAAK,kBAAkBA,CAAI,GAAG,CACzC,CAES,WAAWA,EAAoB,CACtC,GAAI,CAAC,KAAK,IAAK,MAAM,IAAI,MAAM,eAAe,EAC9C,KAAK,IAAI,KAAK,kBAAkBA,CAAI,GAAG,CACzC,CAES,UAAUC,EAAkB,CACnC,GAAI,CAAC,KAAK,IAAK,MAAM,IAAI,MAAM,eAAe,EAC9C,KAAK,IAAI,KAAK,iBAAiBA,CAAE,GAAG,CACtC,CAES,UAAUC,EAAeC,EAAaC,EAAmB,CAChE,GAAI,CAAC,KAAK,IAAK,MAAM,IAAI,MAAM,eAAe,EAC9C,KAAK,IAAI,KAAK,iBAAiBF,CAAK,SAAS,CAC/C,CAMQ,eAAe/B,EAAaiB,EAA2B,CAE7D,IAAMiB,EAAalC,EAChB,MAAM,UAAU,EAChB,IAAK,GAAM,EAAE,KAAK,CAAC,EACnB,OAAO,OAAO,EAEjB,QAAWqB,KAAMa,EAAY,CAC3B,IAAMjD,EAAQoC,EAAG,MAAM,GAAG,EAAE,OAAO,OAAO,EAE1C,GAAIpC,EAAM,CAAC,IAAM,MAAQA,EAAM,OAAS,EAAG,SAE3C,IAAMD,EAAMC,EAAM,CAAC,EACbkD,EAASlD,EAAM,MAAM,CAAC,EAEtBmD,EAAarD,GAAYC,EAAKmD,CAAM,EACtCC,GACFnB,EAAI,gBAAgBmB,EAAW,OAAQA,EAAW,IAAI,CAE1D,CACF,CACF,EAIA,SAASrC,EAAOtB,EAAgB4D,EAAWC,EAAsB,CAC/D,MAAO,8BAA8B7D,CAAM,QAAQ4D,CAAC,KAAKC,CAAI,eAC/D,CAEA,SAASlC,GAASM,EAAkB6B,EAAuB,CACzD,OAAOxC,EACL,QACA,IACA,aAAaxC,CAAU,oBAAoBmD,CAAQ,6BAA6B6B,CAAK,qBACvF,CACF,CAEA,SAASnB,GAAaoB,EAAcD,EAAuB,CACzD,OAAOxC,EACL,QACA,IACA,aAAaxC,CAAU,oBAAoBiF,CAAI,6BAA6BD,CAAK,qBACnF,CACF,CAMA,SAASjB,GACP7C,EACAC,EACe,CACf,OAAQD,EAAQ,CACd,IAAK,gBACH,MAAO,iBAAiBC,EAAK,CAAC,IAAIA,EAAK,CAAC,IAC1C,IAAK,aACH,MAAO,iBAAiBA,EAAK,KAAK,IACpC,IAAK,eACH,MAAO,mBAAmBA,EAAK,OAAO,IACxC,IAAK,aACH,MAAO,iBAAiBA,EAAK,KAAK,IACpC,IAAK,YACH,MAAO,iBAAiBA,EAAK,IAAI,IACnC,IAAK,WACH,MAAO,iBAAiBA,EAAK,CAAC,IAAIA,EAAK,CAAC,IAC1C,IAAK,YACH,MAAO,iBAAiBA,EAAK,IAAI,IAAIA,EAAK,GAAK,CAAC,IAAIA,EAAK,GAAK,CAAC,IACjE,IAAK,WACH,MAAO,iBAAiBA,EAAK,IAAI,IACnC,IAAK,aACH,MAAO,iBAAiBA,EAAK,EAAE,IACjC,QACE,OAAO,IACX,CACF,CC1uBA,OAAS,kBAAA+D,GAAgB,oBAAAC,GAAkB,eAAAC,OAAmB,SAC9D,OAAS,MAAAC,OAAuB,mBAChC,OAAOC,MAAU,YAWjB,IAAMC,GACJ,8DAyBIC,EAAN,KAAgB,CACN,OAAwB,KACxB,QAAUC,EAAK,IAAI,QAAQ,EAEnC,IAAI,WAAoB,CACtB,OAAO,OAAO,KAAK,KAAK,QAAQ,SAAS,EAAE,SAAS,QAAQ,CAC9D,CAEA,IAAI,WAAqB,CACvB,OAAO,KAAK,SAAW,IACzB,CAEA,WAAWC,EAAsBC,EAAwC,CACvE,IAAMC,EAAO,OAAO,KAAKF,EAAc,QAAQ,EACzCG,EAAe,OAAO,KAAKF,EAAiB,QAAQ,EACpDG,EAAQF,EAAK,SAAS,EAAGH,EAAK,IAAI,WAAW,EAC7CM,EAAaH,EAAK,SAASH,EAAK,IAAI,WAAW,EAC/CO,EAAYP,EAAK,IAAI,KACzB,IAAI,WAAWM,CAAU,EACzB,IAAI,WAAWD,CAAK,EACpB,IAAI,WAAWD,CAAY,EAC3B,KAAK,QAAQ,SACf,EACA,OAAOG,EAAY,IAAI,YAAY,EAAE,OAAOA,CAAS,EAAI,IAC3D,CAEA,OAAOC,EAAyB,CAC9B,KAAK,OAAS,OAAO,KAAKA,EAAW,OAAO,CAC9C,CAEA,QAAQD,EAA2B,CACjC,GAAI,CAAC,KAAK,OAAQ,MAAM,IAAI,MAAM,wBAAwB,EAC1D,IAAME,EAAKC,GAAY,EAAE,EACnBC,EAASC,GAAe,cAAe,KAAK,OAAQH,CAAE,EACtDI,EAAY,OAAO,OAAO,CAC9BF,EAAO,OAAOJ,EAAW,OAAO,EAChCI,EAAO,MAAM,CACf,CAAC,EAED,OADe,OAAO,OAAO,CAACF,EAAII,CAAS,CAAC,EAC9B,SAAS,QAAQ,CACjC,CAEA,QAAQV,EAAsB,CAC5B,GAAI,CAAC,KAAK,OAAQ,MAAM,IAAI,MAAM,wBAAwB,EAC1D,IAAMW,EAAM,OAAO,KAAKX,EAAM,QAAQ,EAChCM,EAAKK,EAAI,SAAS,EAAG,EAAE,EACvBR,EAAaQ,EAAI,SAAS,EAAE,EAC5BC,EAAWC,GAAiB,cAAe,KAAK,OAAQP,CAAE,EAChE,OAAO,OAAO,OAAO,CACnBM,EAAS,OAAOT,CAAU,EAC1BS,EAAS,MAAM,CACjB,CAAC,EAAE,SAAS,OAAO,CACrB,CAEA,OAAOZ,EAAuC,CAC5C,OAAO,KAAK,UACR,KAAK,QAAQ,KAAK,UAAUA,CAAI,CAAC,EACjC,KAAK,UAAUA,CAAI,CACzB,CAEA,OAAOA,EAAwC,CAC7C,OAAI,KAAK,WAAa,OAAOA,GAAS,SAC7B,KAAK,MAAM,KAAK,QAAQA,CAAI,CAAC,EAE/B,OAAOA,GAAS,SAClB,KAAK,MAAMA,CAAI,EACfA,CACP,CACF,EAEA,SAASc,EAAiBC,EAAgBC,EAAqC,CAC7E,OAAO,IAAI,QAAQ,CAACC,EAASC,IAAW,CACtC,IAAMC,EAAU,WAAW,IAAM,CAC/BD,EAAO,IAAI,MAAM,qBAAqB,CAAC,CACzC,EAAG,GAAM,EAETH,EAAO,KACL,YACA,CAACK,EAAsBrB,IAA4B,CACjD,aAAaoB,CAAO,EACpB,IAAME,EAAML,EAAU,WAAWI,EAAcrB,CAAe,EAC9D,GAAI,CAACsB,EAAK,CACRH,EAAO,IAAI,MAAM,iCAAiC,CAAC,EACnD,MACF,CAEA,IAAMI,EAAS,KAAK,MAAMD,CAAG,EAC7B,GACEC,EAAO,MACP,OAAOA,EAAO,MAAS,UACvB,KAAK,IAAI,KAAK,IAAI,EAAIA,EAAO,IAAI,EAAI,IACrC,CACAJ,EAAO,IAAI,MAAM,oBAAoB,CAAC,EACtC,MACF,CAEAF,EAAU,OAAOM,EAAO,GAAG,EAC3BL,EAAQ,CACV,CACF,EAEAF,EAAO,KAAK,YAAaC,EAAU,SAAS,CAC9C,CAAC,CACH,CAMA,SAASO,GAAWF,EAAaL,EAA8B,CAC7D,IAAMQ,EAAWH,EAAI,GAAG,KAAKA,CAAG,EAEhC,OAAAA,EAAI,IAAM,CAACI,EAAeC,IACpBD,IAAU,UACLD,EAASC,EAAQE,GAAiB,CACvC,GAAI,CACF,IAAMC,EAAUZ,EAAU,OAAOW,CAAG,EACpCD,EAAS,CAAE,OAAQE,EAAQ,OAAQ,KAAMA,EAAQ,MAAQ,CAAC,CAAE,CAAC,CAC/D,MAAQ,CAER,CACF,CAAC,EAEIJ,EAASC,EAAOC,CAAQ,GAG1BL,CACT,CAEO,IAAMQ,EAAN,cAA2BC,CAAY,CACnC,GAAK,QACN,UAAY,IAAIlC,EAChB,OAA8B,KAEtC,MAAM,MAAMmC,EAAiE,CACtE,KAAK,QACR,MAAM,KAAK,WAAW,EAGxB,IAAMC,EAAa,OAAO,OAAO,KAAK,QAAU,CAAC,CAAC,EAAE,KAAMC,GAAMA,EAAE,KAAK,EACvE,GAAI,CAACD,EAAY,MAAM,IAAI,MAAM,iCAAiC,EAElE,IAAME,EAAc,KAAK,aAAaF,EAAW,KAAMA,EAAW,IAAI,EACtE,YAAK,UAAY,IAAIpC,EAEN,MAAM,IAAI,QAAqB,CAACqB,EAASC,IAAW,CACjE,IAAMC,EAAU,WAAW,IAAM,CAC/Be,EAAY,WAAW,EACvBhB,EAAO,IAAI,MAAM,iBAAiB,CAAC,CACrC,EAAG,IAAM,EAETgB,EAAY,GAAG,UAAW,SAAY,CACpC,GAAI,CACF,MAAMpB,EAAiBoB,EAAa,KAAK,SAAS,EAElD,IAAMC,EACJ,UAAWJ,EACP,CAAE,SAAUA,EAAQ,SAAU,MAAOA,EAAQ,KAAM,EACnD,CAAE,SAAUA,EAAQ,SAAU,SAAUA,EAAQ,QAAS,EAEzDrB,EAAY,KAAK,UAAU,OAAO,CAAE,OAAQ,QAAS,KAAAyB,CAAK,CAAC,EACjED,EAAY,KAAK,UAAWxB,CAAS,CACvC,OAAS0B,EAAK,CACZ,aAAajB,CAAO,EACpBe,EAAY,WAAW,EACvBhB,EAAOkB,CAAG,CACZ,CACF,CAAC,EAEDF,EAAY,GAAG,UAAYP,GAAiB,CAC1C,GAAI,CACF,IAAMC,EAAU,KAAK,UAAU,OAAOD,CAAG,EACzC,GAAIC,EAAQ,SAAW,QAAS,OAEhC,aAAaT,CAAO,EACpBe,EAAY,WAAW,EAEvB,IAAMG,EAAWT,EAAQ,KAEzB,GAAI,CAACS,EAAS,QAAS,CACrBnB,EAAO,IAAI,MAAM,cAAc,CAAC,EAChC,MACF,CAEA,IAAMoB,EAAwB,OAAO,QACnCD,EAAS,aAAe,CAAC,CAC3B,EAAE,IAAI,CAAC,CAACE,EAAMC,CAAU,KAAO,CAAE,KAAAD,EAAM,WAAAC,CAAW,EAAE,EAEpDvB,EAAQ,CACN,QAAAqB,EACA,IAAKD,EAAS,IACd,SAAUA,EAAS,SACnB,UAAWA,EAAS,WAAa,GACjC,YAAaA,EAAS,aAAe,CAAC,CACxC,CAAC,CACH,OAASD,EAAK,CACZ,aAAajB,CAAO,EACpBe,EAAY,WAAW,EACvBhB,EAAOkB,CAAG,CACZ,CACF,CAAC,EAEDF,EAAY,GAAG,gBAAkBE,GAAe,CAC9C,aAAajB,CAAO,EACpBe,EAAY,WAAW,EACvBhB,EAAO,IAAI,MAAM,4BAA4BkB,EAAI,OAAO,EAAE,CAAC,CAC7D,CAAC,CACH,CAAC,CAGH,CAEA,MAAM,QACJK,EACAC,EACAX,EACiB,CACZ,KAAK,QACR,MAAM,KAAK,WAAW,EAGxB,IAAMY,EAAc,KAAK,SAASF,CAAU,EAC5C,GAAI,CAACE,EACH,MAAM,IAAI,MAAM,+BAA+BF,CAAU,EAAE,EAE7D,KAAK,UAAY,IAAI7C,EACrB,IAAMgD,EAAa,KAAK,aAAaD,EAAY,KAAMA,EAAY,IAAI,EACvE,YAAK,OAASC,EAEd,MAAM,IAAI,QAAc,CAAC3B,EAASC,IAAW,CAC3C,IAAMC,EAAU,WAAW,IAAM,CAC/ByB,EAAW,WAAW,EACtB1B,EAAO,IAAI,MAAM,2BAA2B,CAAC,CAC/C,EAAG,IAAM,EAET0B,EAAW,GAAG,UAAW,SAAY,CACnC,GAAI,CACF,MAAM9B,EAAiB8B,EAAY,KAAK,SAAS,EAEjD,IAAMlC,EAAY,KAAK,UAAU,OAAO,CACtC,OAAQ,YACR,KAAM,CACJ,SAAUgC,EAAY,SACtB,IAAKA,EAAY,IACjB,YAAa,EACf,CACF,CAAC,EACDE,EAAW,KAAK,UAAWlC,CAAS,CACtC,OAAS0B,EAAK,CACZ,aAAajB,CAAO,EACpByB,EAAW,WAAW,EACtB1B,EAAOkB,CAAG,CACZ,CACF,CAAC,EAEDQ,EAAW,GAAG,UAAYjB,GAAiB,CACzC,GAAI,CACF,IAAMC,EAAU,KAAK,UAAU,OAAOD,CAAG,EAEzC,OAAQC,EAAQ,OAAQ,CACtB,IAAK,oBAAqB,CACxBG,GAAS,gBAAgBH,EAAQ,IAA8B,EAC/D,KACF,CACA,IAAK,YAAa,CAEhB,GAAI,CADaA,EAAQ,KACX,QAAS,CACrB,aAAaT,CAAO,EACpByB,EAAW,WAAW,EACtB1B,EAAO,IAAI,MAAM,kBAAkB,CAAC,EACpC,MACF,CAEA,IAAM2B,EAAgB,KAAK,UAAU,OAAO,CAC1C,OAAQ,cACR,KAAM,CAAC,CACT,CAAC,EACDD,EAAW,KAAK,UAAWC,CAAa,EACxC,aAAa1B,CAAO,EACpBF,EAAQ,EACR,KACF,CACF,CACF,MAAQ,CAER,CACF,CAAC,EAED2B,EAAW,GAAG,gBAAkBR,GAAe,CAC7C,aAAajB,CAAO,EACpByB,EAAW,WAAW,EACtB1B,EAAO,IAAI,MAAM,2BAA2BkB,EAAI,OAAO,EAAE,CAAC,CAC5D,CAAC,CACH,CAAC,EAEMb,GAAWqB,EAAY,KAAK,SAAS,CAC9C,CAEA,KAAKE,EAAgBX,EAAqC,CACxD,GAAI,CAAC,KAAK,OAAQ,MAAM,IAAI,MAAM,eAAe,EACjD,IAAMzB,EAAY,KAAK,UAAU,OAAO,CAAE,OAAAoC,EAAQ,KAAAX,CAAK,CAAC,EACxD,KAAK,OAAO,KAAK,UAAWzB,CAAS,CACvC,CAEA,YAAmB,CACjB,KAAK,QAAQ,WAAW,EACxB,KAAK,OAAS,IAChB,CAES,cAAcW,EAAwC,CAC7D,MAAO,CACL,GAAG,KAAK,kBAAkBA,CAAG,EAC7B,GAAIA,EAAI,GACR,SAAUA,EAAI,SACd,YAAaA,EAAI,SACjB,EAAIA,EAAI,GAAgB,EACxB,EAAIA,EAAI,GAAgB,EACxB,MAAQA,EAAI,OAAoB,EAChC,KAAM,CACJ,SAAUA,EAAI,SACd,iBAAkBA,EAAI,iBACtB,gBAAiBA,EAAI,gBACrB,kBAAmBA,EAAI,kBACvB,sBAAuBA,EAAI,sBAC3B,UAAWA,EAAI,UACf,UAAWA,EAAI,UACf,UAAWA,EAAI,UACf,SAAUA,EAAI,SACd,QAASA,EAAI,OACf,EACA,KAAMA,CACR,CACF,CAES,gBAAgBA,EAA0C,CACjE,IAAM0B,EAAO1B,EAAI,KACjB,MAAO,CACL,GAAG,KAAK,cAAc0B,CAAI,EAC1B,KAAM1B,EACN,MAAQA,EAAI,OAAoB,EAChC,KAAOA,EAAI,MAAmB,EAC9B,UAAYA,EAAI,WAA0B,CAAC,EAC3C,QAAUA,EAAI,SAAuB,CAAC,EACtC,QAAUA,EAAI,SAAwB,CAAC,EACvC,UAAWA,EAAI,UACf,SAAWA,EAAI,WAA2B,CAAC,EAC3C,OAASA,EAAI,QAAwB,CAAC,CACxC,CACF,CAES,YAAY2B,EAAuB,CAC1C,KAAK,KAAK,eAAgB,CAAE,QAAAA,CAAQ,CAAC,CACvC,CAES,UAAUC,EAAqB,CACtC,KAAK,KAAK,aAAc,CAAE,MAAAA,CAAM,CAAC,CACnC,CAES,SAASC,EAAoB,CACpC,KAAK,KAAK,YAAa,CAAE,KAAAA,CAAK,CAAC,CACjC,CAES,KAAKC,EAAWC,EAAiB,CACxC,KAAK,KAAK,gBAAiB,CAAE,EAAAD,EAAG,EAAAC,CAAE,CAAC,CACrC,CAES,UAAUC,EAAeC,EAAqB,CACrD,KAAK,KAAK,aAAc,CAAE,MAAAD,EAAO,IAAAC,CAAI,CAAC,CACxC,CAES,SAASH,EAAWC,EAAiB,CAC5C,KAAK,KAAK,WAAY,CAAE,EAAAD,EAAG,EAAAC,CAAE,CAAC,CAChC,CAES,SAASG,EAAcJ,EAAYC,EAAkB,CAC5D,KAAK,KAAK,YAAa,CAAE,KAAAG,EAAM,EAAGJ,GAAK,EAAG,EAAGC,GAAK,CAAE,CAAC,CACvD,CAES,QAAQI,EAAoB,CACnC,KAAK,KAAK,WAAY,CAAE,KAAAA,CAAK,CAAC,CAChC,CAES,WAAWA,EAAoB,CACtC,KAAK,KAAK,eAAgB,CAAE,KAAAA,CAAK,CAAC,CACpC,CAES,UAAUA,EAAoB,CACrC,KAAK,KAAK,cAAe,CAAE,KAAAA,CAAK,CAAC,CACnC,CAES,UAAUA,EAAoB,CACrC,KAAK,KAAK,cAAe,CAAE,KAAAA,CAAK,CAAC,CACnC,CAES,UAAUA,EAAoB,CACrC,KAAK,KAAK,cAAe,CAAE,KAAAA,CAAK,CAAC,CACnC,CAES,UAAUA,EAAoB,CACrC,KAAK,KAAK,cAAe,CAAE,KAAAA,CAAK,CAAC,CACnC,CAES,UAAUA,EAAoB,CACrC,KAAK,KAAK,cAAe,CAAE,KAAAA,CAAK,CAAC,CACnC,CAES,UAAUA,EAAoB,CACrC,KAAK,KAAK,cAAe,CAAE,KAAAA,CAAK,CAAC,CACnC,CAES,UAAUA,EAAoB,CACrC,KAAK,KAAK,cAAe,CAAE,KAAAA,CAAK,CAAC,CACnC,CAES,WAAWA,EAAoB,CACtC,KAAK,KAAK,eAAgB,CAAE,KAAAA,CAAK,CAAC,CACpC,CAES,aAAaC,EAAkB,CACtC,KAAK,KAAK,gBAAiB,CAAE,GAAAA,CAAG,CAAC,CACnC,CAES,YAAYA,EAAkB,CACrC,KAAK,KAAK,eAAgB,CAAE,GAAAA,CAAG,CAAC,CAClC,CAES,YAAYA,EAAkB,CACrC,KAAK,KAAK,eAAgB,CAAE,GAAAA,CAAG,CAAC,CAClC,CAES,YAAYA,EAAkB,CACrC,KAAK,KAAK,eAAgB,CAAE,GAAAA,CAAG,CAAC,CAClC,CAES,UAAUA,EAAkB,CACnC,KAAK,KAAK,aAAc,CAAE,GAAAA,CAAG,CAAC,CAChC,CAES,aAAaA,EAAkB,CACtC,KAAK,KAAK,gBAAiB,CAAE,GAAAA,CAAG,CAAC,CACnC,CAES,UAAUA,EAAkB,CACnC,KAAK,KAAK,aAAc,CAAE,GAAAA,CAAG,CAAC,CAChC,CAES,UAAUC,EAAeP,EAAYC,EAAkB,CAC9D,KAAK,KAAK,aAAc,CAAE,MAAAM,EAAO,EAAGP,GAAK,EAAG,EAAGC,GAAK,CAAE,CAAC,CACzD,CAEQ,aAAaO,EAAcC,EAAsB,CACvD,OAAOC,GAAGF,EAAM,CACd,KAAAC,EACA,WAAY,CAAC,UAAW,WAAW,EACnC,aAAc,EAChB,CAAC,CACH,CAEA,MAAc,YAA4B,CACxC,IAAME,EAAO,MAAM,MAAMnE,EAAU,EACnC,GAAI,CAACmE,EAAK,GAAI,MAAM,IAAI,MAAM,2BAA2BA,EAAK,MAAM,EAAE,EACtE,IAAMC,EAAU,MAAMD,EAAK,KAAK,EAChC,KAAK,OAASC,EAAO,MACvB,CACF,ECvfA,OAAS,MAAAC,OAAuB,mBAUhC,IAAMC,GAAW,qCAmBJC,EAAN,cAAoCC,CAAY,CAC5C,GAAK,iBAEd,MAAM,MAAMC,EAAiE,CAC3E,IAAMC,EAAc,KAAK,aAAa,eAAe,EAmDrD,OAjDe,MAAM,IAAI,QAAqB,CAACC,EAASC,IAAW,CACjE,IAAMC,EAAU,WAAW,IAAM,CAC/BH,EAAY,WAAW,EACvBE,EAAO,IAAI,MAAM,iBAAiB,CAAC,CACrC,EAAG,GAAM,EAETF,EAAY,GAAG,UAAW,IAAM,CAC9B,IAAMI,EAAS,UAAWL,EAAU,cAAgB,QAC9CM,EACJ,UAAWN,EACP,CAAE,SAAUA,EAAQ,SAAU,MAAOA,EAAQ,KAAM,EACnD,CAAE,SAAUA,EAAQ,SAAU,SAAUA,EAAQ,QAAS,EAE/DC,EAAY,KAAK,UAAW,CAAE,OAAAI,EAAQ,KAAAC,CAAK,CAAC,CAC9C,CAAC,EAEDL,EAAY,GAAG,UAAYM,GAAuB,CAChD,GAAIA,EAAI,SAAW,QAAS,OAE5B,aAAaH,CAAO,EACpBH,EAAY,WAAW,EAEvB,IAAMO,EAAWD,EAAI,KAErB,GAAI,CAACC,EAAS,QAAS,CACrBL,EAAO,IAAI,MAAM,cAAc,CAAC,EAChC,MACF,CAEA,IAAMM,EAAU,OAAO,QAAQD,EAAS,WAAW,EAAE,IACnD,CAAC,CAACE,EAAMC,CAAU,KAAO,CAAE,KAAAD,EAAM,WAAAC,CAAW,EAC9C,EAEAT,EAAQ,CACN,QAAAO,EACA,IAAKD,EAAS,IACd,SAAUA,EAAS,SACnB,UAAW,GACX,YAAa,CAAC,CAChB,CAAC,CACH,CAAC,EAEDP,EAAY,GAAG,gBAAkBW,GAAe,CAC9C,aAAaR,CAAO,EACpBH,EAAY,WAAW,EACvBE,EAAO,IAAI,MAAM,4BAA4BS,EAAI,OAAO,EAAE,CAAC,CAC7D,CAAC,CACH,CAAC,CAGH,CAEA,MAAM,QACJC,EACAC,EACAd,EACiB,CACjB,IAAMe,EAAa,KAAK,aAAa,UAAUF,EAAW,YAAY,CAAC,GAAG,EAC1E,YAAK,OAASE,EAEd,MAAM,IAAI,QAAc,CAACb,EAASC,IAAW,CAC3C,IAAIa,EAAW,GAEfD,EAAW,GAAG,UAAW,IAAM,CAC7BA,EAAW,KAAK,UAAW,CACzB,OAAQ,YACR,KAAM,CACJ,SAAUD,EAAY,SACtB,IAAKA,EAAY,IACjB,YAAa,GACb,MAAO,EACT,CACF,CAAC,CACH,CAAC,EAEDC,EAAW,GAAG,UAAYR,GAAuB,CAC/C,OAAQA,EAAI,OAAQ,CAClB,IAAK,oBAAqB,CACxBP,GAAS,gBAAgBO,EAAI,IAAmB,EAChD,KACF,CACA,IAAK,YAAa,CAChB,GAAIS,EAAU,MAId,GAHAA,EAAW,GAGP,CADaT,EAAI,KACP,QAAS,CACrBQ,EAAW,WAAW,EACtBZ,EAAO,IAAI,MAAM,kBAAkB,CAAC,EACpC,MACF,CAEAY,EAAW,KAAK,UAAW,CACzB,OAAQ,cACR,KAAM,CAAC,CACT,CAAC,EACDb,EAAQ,EACR,KACF,CACF,CACF,CAAC,EAEDa,EAAW,GAAG,gBAAkBH,GAAe,CAC7CG,EAAW,WAAW,EACtBZ,EAAO,IAAI,MAAM,2BAA2BS,EAAI,OAAO,EAAE,CAAC,CAC5D,CAAC,CACH,CAAC,EAEMG,CACT,CAEA,KAAKV,EAAgBC,EAAqC,CACxD,GAAI,CAAC,KAAK,OAAQ,MAAM,IAAI,MAAM,eAAe,EACjD,KAAK,OAAO,KAAK,UAAW,CAAE,OAAAD,EAAQ,KAAAC,CAAK,CAAC,CAC9C,CAEA,YAAmB,CACjB,KAAK,QAAQ,WAAW,EACxB,KAAK,OAAS,IAChB,CAES,cAAcW,EAAwC,CAC7D,MAAO,CACL,GAAG,KAAK,kBAAkBA,CAAG,EAC7B,GAAIA,EAAI,GACR,SAAUA,EAAI,SACd,YAAcA,EAAI,UAAwBA,EAAI,SAC9C,SAAUA,EAAI,SACd,EAAIA,EAAI,GAAgB,EACxB,EAAIA,EAAI,GAAgB,EACxB,MAAQA,EAAI,OAAoB,EAChC,KAAM,CACJ,IAAKA,EAAI,GACX,EACA,KAAMA,CACR,CACF,CAES,gBAAgBA,EAA0C,CACjE,IAAMC,EAAOD,EAAI,KACXE,EAAa,KAAK,cAAcD,CAAI,EAC1C,MAAO,CACL,GAAGC,EACH,KAAMF,EACN,MAAQA,EAAI,OAAoB,EAChC,KAAOA,EAAI,MAAmB,EAC9B,UAAYA,EAAI,WAA0B,CAAC,EAC3C,UAAYA,EAAI,WAA2B,CAAC,EAC5C,SAAWA,EAAI,UAA0B,CAAC,EAC1C,QAAUA,EAAI,SAAqC,CAAC,EACpD,cAAgBA,EAAI,eAA8B,CAAC,EACnD,QAAUA,EAAI,SAAwB,CAAC,EACvC,OAASA,EAAI,QAAwB,CAAC,EACtC,KAAM,CACJ,GAAGE,EAAW,KACd,UAAWF,EAAI,UACf,QAASA,EAAI,QACb,KAAMA,EAAI,IACZ,CACF,CACF,CAES,YAAYG,EAAuB,CAC1C,KAAK,KAAK,eAAgB,CAAE,QAAAA,CAAQ,CAAC,CACvC,CAES,UAAUC,EAAqB,CACtC,KAAK,KAAK,aAAc,CAAE,MAAAA,CAAM,CAAC,CACnC,CAES,SAASC,EAAoB,CACpC,KAAK,KAAK,YAAa,CAAE,KAAAA,CAAK,CAAC,CACjC,CAES,KAAKC,EAAWC,EAAiB,CACxC,KAAK,KAAK,gBAAiB,CAAE,EAAAD,EAAG,EAAAC,CAAE,CAAC,CACrC,CAES,UAAUC,EAAeC,EAAqB,CACrD,KAAK,KAAK,aAAc,CAAE,MAAAD,EAAO,IAAKC,GAAO,EAAM,CAAC,CACtD,CAES,SAASH,EAAWC,EAAiB,CAC5C,KAAK,KAAK,WAAY,CAAE,EAAAD,EAAG,EAAAC,CAAE,CAAC,CAChC,CAES,SAASG,EAAcJ,EAAYC,EAAkB,CAC5D,KAAK,KAAK,YAAa,CAAE,KAAAG,EAAM,EAAGJ,GAAK,EAAG,EAAGC,GAAK,CAAE,CAAC,CACvD,CAES,QAAQI,EAAoB,CACnC,KAAK,KAAK,WAAY,CAAE,KAAAA,CAAK,CAAC,CAChC,CAES,WAAWA,EAAoB,CACtC,KAAK,KAAK,gBAAiB,CAAE,KAAAA,CAAK,CAAC,CACrC,CAES,UAAUA,EAAoB,CACrC,KAAK,KAAK,gBAAiB,CAAE,KAAAA,CAAK,CAAC,CACrC,CAES,UAAUA,EAAoB,CACrC,KAAK,KAAK,gBAAiB,CAAE,KAAAA,CAAK,CAAC,CACrC,CAES,UAAUA,EAAoB,CACrC,KAAK,KAAK,gBAAiB,CAAE,KAAAA,CAAK,CAAC,CACrC,CAES,UAAUA,EAAoB,CACrC,KAAK,KAAK,gBAAiB,CAAE,KAAAA,CAAK,CAAC,CACrC,CAES,UAAUA,EAAoB,CACrC,KAAK,KAAK,gBAAiB,CAAE,KAAAA,CAAK,CAAC,CACrC,CAES,UAAUA,EAAoB,CACrC,KAAK,KAAK,gBAAiB,CAAE,KAAAA,CAAK,CAAC,CACrC,CAES,UAAUA,EAAoB,CACrC,KAAK,KAAK,gBAAiB,CAAE,KAAAA,CAAK,CAAC,CACrC,CAES,WAAWA,EAAoB,CACtC,KAAK,KAAK,gBAAiB,CAAE,KAAAA,CAAK,CAAC,CACrC,CAES,aAAaC,EAAkB,CACtC,KAAK,KAAK,gBAAiB,CAAE,GAAAA,CAAG,CAAC,CACnC,CAES,YAAYA,EAAkB,CACrC,KAAK,KAAK,eAAgB,CAAE,GAAAA,CAAG,CAAC,CAClC,CAES,UAAUA,EAAkB,CACnC,KAAK,KAAK,aAAc,CAAE,GAAAA,CAAG,CAAC,CAChC,CAES,aAAaA,EAAkB,CACtC,KAAK,KAAK,gBAAiB,CAAE,GAAAA,CAAG,CAAC,CACnC,CAES,aAAaC,EAAqB,CACzC,KAAK,KAAK,iBAAkB,CAAE,MAAAA,CAAM,CAAC,CACvC,CAES,UAAUA,EAAeP,EAAYC,EAAkB,CAC9D,KAAK,KAAK,aAAc,CAAE,MAAAM,EAAO,EAAGP,GAAK,EAAG,EAAGC,GAAK,CAAE,CAAC,CACzD,CAES,SAASO,EAAqB,CACrC,KAAK,KAAK,YAAa,CAAE,MAAAA,CAAM,CAAC,CAClC,CAEQ,aAAaC,EAAsB,CACzC,OAAOC,GAAGpC,GAAU,CAClB,KAAAmC,EACA,WAAY,CAAC,UAAW,WAAW,EACnC,aAAc,EAChB,CAAC,CACH,CACF,ECrSA,IAAME,GAAW,CACf,UAAWC,EACX,SAAUC,EACV,OAAQC,EACR,MAAOC,EACP,eAAgBC,CAClB,EAIO,SAASC,EAAcC,EAAgC,CAC5D,OAAO,IAAIP,GAASO,CAAI,CAC1B,CCXO,IAAMC,EAAN,KAAgB,CACrB,YACUC,EACAC,EACR,CAFQ,aAAAD,EACA,aAAAC,CACP,CAFO,QACA,QAIV,UAAiD,CAC/C,YAAK,QAAQ,SAAS,EACf,KAAK,QAAQ,WAAW,CACjC,CAGA,SAAkD,CAChD,YAAK,QAAQ,QAAQ,EACd,KAAK,QAAQ,aAAa,CACnC,CAGA,QAAQC,EAAsB,CAC5B,KAAK,QAAQ,QAAQA,CAAM,CAC7B,CAGA,iBAA+D,CAC7D,YAAK,QAAQ,gBAAgB,EACtB,KAAK,QAAQ,kBAAkB,CACxC,CAGA,kBAAyB,CACvB,KAAK,QAAQ,iBAAiB,CAChC,CAGA,WAAmD,CACjD,YAAK,QAAQ,UAAU,EAChB,KAAK,QAAQ,YAAY,CAClC,CAGA,WAAWC,EAAuD,CAChE,YAAK,QAAQ,WAAWA,CAAI,EACrB,KAAK,QAAQ,cAAc,CACpC,CAGA,cAAcC,EAAyB,CACrC,KAAK,QAAQ,cAAcA,CAAS,CACtC,CACF,EP3CA,IAAMC,GAAgB,IAAI,IAAY,CAErC,cAAe,YAAa,aAAc,gBAC1C,gBAAiB,aAAc,gBAAiB,OAAQ,mBAExD,eAAgB,aAAc,WAAY,cAAe,eACzD,cAAe,eAAgB,QAAS,eAAgB,YACxD,iBAAkB,YAAa,cAAe,gBAC9C,mBAAoB,mBAAoB,aAAc,YACtD,kBAAmB,cAAe,eAAgB,cAClD,eAAgB,cAAe,aAAc,iBAAkB,WAC/D,aAAc,gBAAiB,eAAgB,eAC/C,qBAAsB,YAAa,gBAAiB,gBACpD,aAAc,gBAAiB,WAAY,gBAC3C,iBAAkB,aAAc,kBAAmB,aAAc,cACjE,cAAe,oBAAqB,OACpC,WAAY,YAAa,eAAgB,eAAgB,mBACzD,oBACA,aAAc,gBACf,CAAC,EAiBD,SAASC,EAAiBC,EAAqC,CAC7D,OACE,OAAOA,GAAQ,UAAYA,IAAQ,MAAQ,WAAYA,GAAO,SAAUA,CAE5E,CAEO,IAAMC,EAAN,cAAqBC,EAAa,CACvC,OAA4B,KAC5B,KAAsB,KACtB,MAA+B,IAAI,IACnC,UAAY,GAEJ,QACA,YAAkC,KAClC,IAAoB,KACpB,WAA+B,KAEvC,IAAI,WAAuB,CACzB,OAAK,KAAK,aACR,KAAK,WAAa,IAAIC,EAAU,KAAK,QAAS,KAAK,QAAQ,KAAK,IAAI,CAAC,GAChE,KAAK,UACd,CAEA,YAAYC,EAAqBC,EAAyB,CACxD,MAAM,EACN,KAAK,QAAUC,EAAcF,CAAM,EAE/BC,GAAS,QACX,KAAK,IACH,OAAOA,EAAQ,OAAU,WACrBA,EAAQ,MACR,QAAQ,IAAI,KAAK,OAAO,EAElC,CAEA,MAAM,MACJA,EACuB,CACvB,YAAK,MAAM,wBAAyBA,EAAQ,QAAQ,EACpD,KAAK,YAAc,MAAM,KAAK,QAAQ,MAAMA,CAAO,EACnD,KAAK,MAAM,yBAAqB,KAAK,YAAY,QAAQ,OAAQ,SAAS,EACnE,KAAK,YAAY,OAC1B,CAEA,MAAM,QAAQE,EAAoBF,EAAyC,CACzE,GAAI,CAAC,KAAK,YAAa,MAAM,IAAI,MAAM,yBAAyB,EAEhE,KAAK,MAAM,oBAAqBE,CAAU,EAE1C,IAAMC,EAAiC,CACrC,GAAGH,EACH,cAAgBI,GAAwB,CACtC,KAAK,MAAM,UAAW,IAAIA,EAAO,QAAQ,IAAIA,EAAO,WAAW,EAAE,EACjE,KAAK,KAAK,oBAAqBA,CAAM,EACrCJ,GAAS,gBAAgBI,CAAM,CACjC,CACF,EAEMC,EAAS,MAAM,KAAK,QAAQ,QAChCH,EACA,KAAK,YACLC,CACF,EAEAE,EAAO,GAAG,UAAYV,GAAiB,CAChCD,EAAiBC,CAAG,GACzB,KAAK,cAAcA,CAAG,CACxB,CAAC,EAEDU,EAAO,GAAG,aAAc,IAAM,CAC5B,KAAK,MAAM,8BAA8B,EACzC,KAAK,QAAQ,EACb,KAAK,KAAK,YAAY,CACxB,CAAC,EAED,MAAM,IAAI,QAAc,CAACC,EAASC,IAAW,CAC3C,IAAMC,EAAU,WAAW,IAAM,CAC/BD,EAAO,IAAI,MAAM,mCAAmC,CAAC,CACvD,EAAG,GAAM,EAELE,EAAe,GACfC,EAAa,GAEXC,EAAa,IAAY,CACzBF,GAAgBC,IAClB,aAAaF,CAAO,EACpB,KAAK,UAAY,GACjBF,EAAQ,EAEZ,EAEMM,EAAajB,GAAuB,CACxC,GAAKD,EAAiBC,CAAG,EACzB,OAAQA,EAAI,OAAQ,CAClB,IAAK,cACHc,EAAe,GACfE,EAAW,EACX,MACF,IAAK,YACHD,EAAa,GACbC,EAAW,EACX,MACF,IAAK,OACH,aAAaH,CAAO,EACpBH,EAAO,IAAI,UAAWO,CAAS,EAC/BL,EACE,IAAI,MACF,WAAYZ,EAAI,KAA6B,QAAU,SAAS,EAClE,CACF,EACA,MACF,IAAK,mBACH,aAAaa,CAAO,EACpBH,EAAO,IAAI,UAAWO,CAAS,EAC/BL,EACE,IAAI,MACF,WAAYZ,EAAI,KAA4B,OAAS,SAAS,EAChE,CACF,EACA,MACF,IAAK,QACH,aAAaa,CAAO,EACpBH,EAAO,IAAI,UAAWO,CAAS,EAC/BL,EACE,IAAI,MACF,iBAAkBZ,EAAI,KAAqC,OAAS,SAAS,EAC/E,CACF,EACA,KACJ,CACF,EAEMkB,EAAe,IAAY,EAC3B,CAACJ,GAAgB,CAACC,KACpB,aAAaF,CAAO,EACpBD,EAAO,IAAI,MAAM,kCAAkC,CAAC,EAExD,EAEAF,EAAO,GAAG,UAAWO,CAAS,EAC9BP,EAAO,KAAK,aAAcQ,CAAY,CACxC,CAAC,CACH,CAOA,GAAGC,EAAeC,EAA8C,CAC9D,OAAO,MAAM,GAAGD,EAAOC,CAAQ,CACjC,CAOA,IAAID,EAAeC,EAA8C,CAC/D,OAAO,MAAM,IAAID,EAAOC,CAAQ,CAClC,CAOA,KAAKD,EAAeC,EAA8C,CAChE,OAAO,MAAM,KAAKD,EAAOC,CAAQ,CACnC,CAOA,KAAKD,KAAkBE,EAA0B,CAC/C,OAAO,MAAM,KAAKF,EAAO,GAAGE,CAAI,CAClC,CAGA,QACEF,EACAN,EAC4B,CAC5B,OAAO,IAAI,QAA2B,CAACF,EAASC,IAAW,CACzD,IAAIU,EAEEC,EAAU,IAAY,CACtBD,GAAO,aAAaA,CAAK,EAC7B,KAAK,IAAIH,EAAOK,CAAkD,EAClE,KAAK,IAAI,aAAcN,CAAY,CACrC,EAEMM,GAAYH,GAA4B,CAC5CE,EAAQ,EACRZ,EAAQU,CAAI,CACd,GAEMH,EAAe,IAAY,CAC/BK,EAAQ,EACRX,EAAO,IAAI,MAAM,kCAAkC,OAAOO,CAAK,CAAC,EAAE,CAAC,CACrE,EAEIN,IAAY,SACdS,EAAQ,WAAW,IAAM,CACvBC,EAAQ,EACRX,EAAO,IAAI,MAAM,yBAAyB,OAAOO,CAAK,CAAC,EAAE,CAAC,CAC5D,EAAGN,CAAO,GAGZ,KAAK,KAAKM,EAAOK,CAAO,EACxB,KAAK,KAAK,aAAcN,CAAY,CACtC,CAAC,CACH,CAEA,YAAYO,EAAuB,CACjC,KAAK,QAAQ,YAAYA,CAAO,CAClC,CACA,UAAUC,EAAqB,CAC7B,KAAK,QAAQ,UAAUA,CAAK,CAC9B,CACA,SAASC,EAAoB,CAC3B,KAAK,QAAQ,SAASA,CAAI,CAC5B,CACA,KAAKC,EAAWC,EAAiB,CAC/B,KAAK,QAAQ,KAAKD,EAAGC,CAAC,CACxB,CACA,UAAUC,EAAeC,EAAqB,CAC5C,KAAK,QAAQ,UAAUD,EAAOC,CAAG,CACnC,CACA,SAASH,EAAWC,EAAiB,CACnC,KAAK,QAAQ,SAASD,EAAGC,CAAC,CAC5B,CACA,SACEG,EACAJ,EACAC,EACsC,CACtC,YAAK,QAAQ,SAASG,EAAMJ,EAAGC,CAAC,EACzB,KAAK,QAAQ,WAAW,CACjC,CACA,QAAQI,EAAmD,CACzD,YAAK,QAAQ,QAAQA,CAAI,EAClB,KAAK,QAAQ,UAAU,CAChC,CACA,WAAWA,EAAoB,CAC7B,KAAK,QAAQ,WAAWA,CAAI,CAC9B,CACA,UAAUA,EAAoB,CAC5B,KAAK,QAAQ,UAAUA,CAAI,CAC7B,CACA,UAAUA,EAAoB,CAC5B,KAAK,QAAQ,UAAUA,CAAI,CAC7B,CACA,UAAUA,EAAoB,CAC5B,KAAK,QAAQ,UAAUA,CAAI,CAC7B,CACA,UAAUA,EAAoB,CAC5B,KAAK,QAAQ,UAAUA,CAAI,CAC7B,CACA,UAAUA,EAAoB,CAC5B,KAAK,QAAQ,UAAUA,CAAI,CAC7B,CACA,UAAUA,EAAoB,CAC5B,KAAK,QAAQ,UAAUA,CAAI,CAC7B,CACA,UAAUA,EAAoB,CAC5B,KAAK,QAAQ,UAAUA,CAAI,CAC7B,CACA,WAAWA,EAAoB,CAC7B,KAAK,QAAQ,WAAWA,CAAI,CAC9B,CACA,aAAaC,EAAkB,CAC7B,KAAK,QAAQ,aAAaA,CAAE,CAC9B,CACA,YAAYA,EAAqD,CAC/D,YAAK,QAAQ,YAAYA,CAAE,EACpB,KAAK,QAAQ,cAAc,CACpC,CACA,YAAYA,EAAqD,CAC/D,YAAK,QAAQ,YAAYA,CAAE,EACpB,KAAK,QAAQ,cAAc,CACpC,CACA,iBAAiBA,EAA2D,CAC1E,YAAK,QAAQ,iBAAiBA,CAAE,EACzB,KAAK,QAAQ,oBAAoB,CAC1C,CACA,SACEA,EACAC,EACsC,CACtC,YAAK,QAAQ,SAASD,EAAIC,CAAI,EACvB,KAAK,QAAQ,WAAW,CACjC,CACA,YAAYD,EAAkB,CAC5B,KAAK,QAAQ,YAAYA,CAAE,CAC7B,CACA,UAAUA,EAAmD,CAC3D,YAAK,QAAQ,UAAUA,CAAE,EAClB,KAAK,QAAQ,YAAY,CAClC,CACA,aAAaA,EAAsD,CACjE,YAAK,QAAQ,aAAaA,CAAE,EACrB,KAAK,QAAQ,eAAe,CACrC,CACA,UAAUA,EAAmD,CAC3D,YAAK,QAAQ,UAAUA,CAAE,EAClB,KAAK,QAAQ,YAAY,CAClC,CACA,aAA+C,CAC7C,YAAK,QAAQ,YAAY,EAClB,KAAK,QAAQ,MAAM,CAC5B,CACA,YAAqD,CACnD,YAAK,QAAQ,WAAW,EACjB,KAAK,QAAQ,aAAa,CACnC,CACA,aACEE,EACAC,EAC0C,CAC1C,YAAK,QAAQ,aAAaD,EAAQC,CAAM,EACjC,KAAK,QAAQ,eAAe,CACrC,CACA,UAAUD,EAA0D,CAClE,YAAK,QAAQ,UAAUA,CAAM,EACtB,KAAK,QAAQ,eAAe,CACrC,CACA,cAAyD,CACvD,YAAK,QAAQ,aAAa,EACnB,KAAK,QAAQ,eAAe,CACrC,CACA,aAAaE,EAA0D,CACrE,YAAK,QAAQ,aAAaA,CAAK,EACxB,KAAK,QAAQ,gBAAgB,CACtC,CACA,WAAmD,CACjD,YAAK,QAAQ,UAAU,EAChB,KAAK,QAAQ,YAAY,CAClC,CACA,WAAWF,EAAwD,CACjE,YAAK,QAAQ,WAAWA,CAAM,EACvB,KAAK,QAAQ,aAAa,CACnC,CACA,eAA4D,CAC1D,YAAK,QAAQ,cAAc,EACpB,KAAK,QAAQ,iBAAiB,CACvC,CACA,UACEE,EACAV,EACAC,EACuC,CACvC,YAAK,QAAQ,UAAUS,EAAOV,EAAGC,CAAC,EAC3B,KAAK,QAAQ,YAAY,CAClC,CACA,SAASU,EAAqD,CAC5D,YAAK,QAAQ,SAASA,CAAK,EACpB,KAAK,QAAQ,WAAW,CACjC,CACA,aAAaC,EAAwD,CACnE,YAAK,QAAQ,aAAaA,CAAK,EACxB,KAAK,QAAQ,cAAc,CACpC,CAEA,MAAMC,EAA2B,CAC/B,OAAO,IAAI,QAAS9B,GAAY,WAAWA,EAAS8B,CAAE,CAAC,CACzD,CAEA,YAAmB,CACjB,KAAK,MAAM,iCAAiC,EAC5C,KAAK,QAAQ,WAAW,EACxB,KAAK,QAAQ,CACf,CAEQ,SAAgB,CACtB,KAAK,UAAY,GACjB,KAAK,OAAS,KACd,KAAK,KAAO,KACZ,KAAK,MAAM,MAAM,CACnB,CAEQ,cAAczC,EAA2B,CAC/C,GAAM,CAAE,OAAA0C,EAAQ,KAAArB,CAAK,EAAIrB,EACrB2C,EAAoBtB,EAExB,OAAQqB,EAAQ,CACd,IAAK,cAAe,CAClB,IAAME,EAAS,KAAK,QAAQ,gBAAgBvB,CAAI,EAChD,KAAK,OAASuB,EACdD,EAAW,CAAE,KAAMC,CAAO,EAC1B,KAAK,MACH,gBACAA,EAAO,SACP,MAAMA,EAAO,EAAE,GACf,SAASA,EAAO,KAAK,GACrB,aAAaA,EAAO,UAAU,MAAM,EACtC,EACA,KACF,CACA,IAAK,YAAa,CAChB,IAAMZ,EAAOX,EAAK,KACZwB,EAAWxB,EAAK,MACtB,KAAK,KAAOW,EACZ,KAAK,MAAM,MAAM,EACjB,IAAMc,EAAoB,CAAC,EAC3B,QAAWC,KAAWF,EAAU,CAC9B,IAAMG,EAAO,KAAK,QAAQ,cAAcD,CAAO,EAC/C,KAAK,MAAM,IAAIC,EAAK,GAAIA,CAAI,EAC5BF,EAAM,KAAKE,CAAI,CACjB,CACAL,EAAW,CAAE,KAAAX,EAAM,MAAAc,CAAM,EACzB,KAAK,MAAM,cAAe,QAAQd,CAAI,GAAI,SAASc,EAAM,MAAM,EAAE,EACjE,KACF,CACA,IAAK,aAAc,CACjB,IAAME,EAAO,KAAK,QAAQ,cACxB3B,EAAK,IACP,EACA,KAAK,MAAM,IAAI2B,EAAK,GAAIA,CAAI,EAC5BL,EAAW,CAAE,KAAAK,CAAK,EAClB,KAAK,MAAM,eAAgBA,EAAK,SAAU,MAAMA,EAAK,EAAE,EAAE,EACzD,KACF,CACA,IAAK,gBAAiB,CACpB,IAAMd,EAAKb,EAAK,KAChB,KAAK,MAAM,OAAOa,CAAE,EACpB,KAAK,MAAM,kBAAmB,MAAMA,CAAE,EAAE,EACxC,KACF,CACA,IAAK,gBAAiB,CACpB,IAAMA,EAAKb,EAAK,GACV2B,EAAO,KAAK,MAAM,IAAId,CAAE,EAC1Bc,IACFA,EAAK,EAAI3B,EAAK,EACd2B,EAAK,EAAI3B,EAAK,GAEhB,KACF,CACA,IAAK,aAAc,CACjB,IAAMa,EAAKb,EAAK,GACV2B,EAAO,KAAK,MAAM,IAAId,CAAE,EAC1Bc,IACFA,EAAK,MAAQ3B,EAAK,OAEpB,KACF,CACA,IAAK,aAAc,CACjB,IAAMiB,EAAQjB,EAAK,MACbwB,EAAWxB,EAAK,MACtB,KAAK,KAAOiB,EACZ,KAAK,MAAM,MAAM,EACjB,IAAMW,EAAyB,CAAC,EAChC,QAAWF,KAAWF,EAAU,CAC9B,IAAMG,EAAO,KAAK,QAAQ,cAAcD,CAAO,EAC/C,KAAK,MAAM,IAAIC,EAAK,GAAIA,CAAI,EAC5BC,EAAW,KAAKD,CAAI,CACtB,CACAL,EAAW,CAAE,GAAGtB,EAAM,MAAO4B,CAAW,EACxC,KAAK,MAAM,eAAgB,SAASX,CAAK,GAAI,SAASW,EAAW,MAAM,EAAE,EACzE,KACF,CACA,IAAK,gBAAiB,CACpB,IAAMf,EAAKb,EAAK,GACV6B,EAAO7B,EAAK,KACZY,EAAOZ,EAAK,KACZ2B,EAAO,KAAK,MAAM,IAAId,CAAE,EAC1Bc,GAAQE,KAAQF,IACjBA,EAAiCE,CAAI,EAAIjB,GAE5C,KACF,CACA,IAAK,OAAQ,CACX,IAAMkB,EAAU9B,EAA6B,QAAU,UACvD,KAAK,MAAM,SAAU8B,CAAM,EAC3B,KAAK,QAAQ,EACb,KACF,CACA,IAAK,mBAAoB,CACvB,IAAMC,EAAS/B,EAA4B,OAAS,UACpD,KAAK,MAAM,SAAU+B,CAAK,EAC1B,KAAK,QAAQ,EACb,KACF,CACA,QAAS,CACFtD,GAAc,IAAI4C,CAAM,IAC3B,KAAK,MAAM,mBAAoBA,EAAQ,KAAK,UAAUrB,CAAI,CAAC,EAC3D,KAAK,KAAK,iBAAkB,CAAE,OAAAqB,EAAQ,KAAArB,CAAK,CAAC,GAE9C,KACF,CACF,CAEA,IAAMgC,EAAYX,IAAW,QAAU,eAAiBA,EACxD,KAAK,KAAKW,EAAWV,CAAQ,CAC/B,CACF","names":["BaseAdapter","_raw","raw","_message","_emote","_safe","_x","_y","_frame","_set","_room","_item","_id","_type","_userId","_cardId","_igloo","_coins","_stamp","_slot","_animation","_waddle","EventEmitter","io","msgpackParser","BASE_URL","DEFAULT_SECRET","CpjourneyAdapter","BaseAdapter","options","loginSocket","resolve","reject","timeout","secret","args","msg","response","servers","name","population","err","serverName","loginResult","gameSocket","authSent","queueSocket","action","raw","id","username","displayName","joinTime","x","y","frame","walking","color","head","face","neck","body","hand","feet","flag","photo","rest","user","normalized","_user","coins","rank","inventory","furniture","flooring","buddies","buddyRequests","ignores","igloos","message","emote","safe","set","room","item","type","userId","cardId","igloo","stamp","slot","animation","waddle","path","io","msgpackParser","io","msgpackParser","LOGIN_URL","TOKEN_LOGIN_URL","wrapSocket","raw","original","event","listener","action","args","CplegacyAdapter","BaseAdapter","options","url","body","data","name","population","serverName","loginResult","wsUrl","rawSocket","io","msgpackParser","resolve","reject","timeout","err","user","b","message","emote","safe","x","y","frame","set","room","item","id","userId","igloo","coins","stamp","createHash","EventEmitter","WebSocket","LOGIN_WS_URL","GAME_WS_URL","API_VERSION","LOGIN_ZONE","NUL","U","md5","input","createHash","swapMD5","hash","int","v","n","parseUserString","str","f","SmartFoxSocket","EventEmitter","ws","err","action","args","buffered","msg","data","WebSocket","translateXt","cmd","parts","user","coins","rank","room","users","CpzeroAdapter","BaseAdapter","options","loginHash","resolve","reject","timeout","_rndK","xmlMsg","raw","messages","kMatch","loginXml","xmlLogin","xtParts","nickString","confirmationKey","nickFields","userId","username","errParts","_serverName","loginResult","_options","keyParts","loginKey","sfs","rndK","gamePword","xmlGameLogin","xt","actionToXt","message","emote","safe","x","y","frame","item","id","igloo","_x","_y","xtMessages","xtArgs","translated","r","body","pword","nick","createCipheriv","createDecipheriv","randomBytes","io","nacl","CRUMBS_URL","Encryptor","nacl","encryptedB64","serverPubKeyB64","data","serverPubKey","nonce","ciphertext","plaintext","keyString","iv","randomBytes","cipher","createCipheriv","encrypted","buf","decipher","createDecipheriv","performHandshake","socket","encryptor","resolve","reject","timeout","encryptedKey","raw","parsed","wrapSocket","original","event","listener","msg","decoded","NewcpAdapter","BaseAdapter","options","loginWorld","w","loginSocket","args","err","response","servers","name","population","serverName","loginResult","worldConfig","gameSocket","joinEncrypted","action","user","message","emote","safe","x","y","frame","set","room","item","id","igloo","host","path","io","resp","crumbs","io","BASE_URL","PenguinoriginsAdapter","BaseAdapter","options","loginSocket","resolve","reject","timeout","action","args","msg","response","servers","name","population","err","serverName","loginResult","gameSocket","authSent","raw","user","normalized","message","emote","safe","x","y","frame","set","room","item","id","igloo","coins","path","io","ADAPTERS","CpjourneyAdapter","CplegacyAdapter","CpzeroAdapter","NewcpAdapter","PenguinoriginsAdapter","createAdapter","name","CardJitsu","adapter","waitFor","waddle","slot","animation","KNOWN_ACTIONS","isMessagePayload","msg","Client","EventEmitter","CardJitsu","server","options","createAdapter","serverName","connectOptions","update","socket","resolve","reject","timeout","playerLoaded","roomJoined","checkReady","onMessage","onDisconnect","event","listener","args","timer","cleanup","handler","message","emote","safe","x","y","frame","set","room","item","id","type","userId","cardId","igloo","coins","stamp","ms","action","emitArgs","player","rawUsers","users","rawUser","user","iglooUsers","slot","reason","error","eventName"]}
|
|
1
|
+
{"version":3,"sources":["../src/adapters/base-adapter.ts","../src/client.ts","../src/adapters/cpjourney-adapter.ts","../src/adapters/cplegacy-adapter.ts","../src/adapters/cpzero-adapter.ts","../src/adapters/newcp-adapter.ts","../src/adapters/penguinorigins-adapter.ts","../src/adapters/index.ts","../src/games/card-jitsu.ts"],"sourcesContent":["import type { Socket } from \"socket.io-client\";\nimport type {\n LoginOptions,\n LoginResult,\n QueueUpdate,\n TokenLoginOptions,\n} from \"../types/adapter-types.js\";\nimport type {\n PlayerAppearance,\n PlayerData,\n RoomUser,\n} from \"../types/player-types.js\";\n\nexport type ConnectOptions = {\n onQueueUpdate?: (update: QueueUpdate) => void;\n};\n\nexport abstract class BaseAdapter {\n abstract readonly id: string;\n protected socket: Socket | null = null;\n\n abstract login(\n options: LoginOptions | TokenLoginOptions,\n ): Promise<LoginResult>;\n abstract connect(\n serverName: string,\n loginResult: LoginResult,\n options?: ConnectOptions,\n ): Promise<Socket>;\n abstract disconnect(): void;\n abstract send(action: string, args: Record<string, unknown>): void;\n\n normalizeUser(_raw: Record<string, unknown>): RoomUser {\n throw new Error(\"Not implemented: normalizeUser\");\n }\n\n normalizePlayer(_raw: Record<string, unknown>): PlayerData {\n throw new Error(\"Not implemented: normalizePlayer\");\n }\n\n protected extractAppearance(raw: Record<string, unknown>): PlayerAppearance {\n return {\n color: (raw.color as number) ?? 0,\n head: (raw.head as number) ?? 0,\n face: (raw.face as number) ?? 0,\n neck: (raw.neck as number) ?? 0,\n body: (raw.body as number) ?? 0,\n hand: (raw.hand as number) ?? 0,\n feet: (raw.feet as number) ?? 0,\n flag: (raw.flag as number) ?? 0,\n photo: (raw.photo as number) ?? 0,\n };\n }\n\n sendMessage(_message: string): void {\n throw new Error(\"Not implemented: sendMessage\");\n }\n\n sendEmote(_emote: number): void {\n throw new Error(\"Not implemented: sendEmote\");\n }\n\n sendSafe(_safe: number): void {\n throw new Error(\"Not implemented: sendSafe\");\n }\n\n walk(_x: number, _y: number): void {\n throw new Error(\"Not implemented: walk\");\n }\n\n sendFrame(_frame: number, _set?: boolean): void {\n throw new Error(\"Not implemented: sendFrame\");\n }\n\n snowball(_x: number, _y: number): void {\n throw new Error(\"Not implemented: snowball\");\n }\n\n joinRoom(_room: number, _x?: number, _y?: number): void {\n throw new Error(\"Not implemented: joinRoom\");\n }\n\n addItem(_item: number): void {\n throw new Error(\"Not implemented: addItem\");\n }\n\n equipColor(_item: number): void {\n throw new Error(\"Not implemented: equipColor\");\n }\n\n equipHead(_item: number): void {\n throw new Error(\"Not implemented: equipHead\");\n }\n\n equipFace(_item: number): void {\n throw new Error(\"Not implemented: equipFace\");\n }\n\n equipNeck(_item: number): void {\n throw new Error(\"Not implemented: equipNeck\");\n }\n\n equipBody(_item: number): void {\n throw new Error(\"Not implemented: equipBody\");\n }\n\n equipHand(_item: number): void {\n throw new Error(\"Not implemented: equipHand\");\n }\n\n equipFeet(_item: number): void {\n throw new Error(\"Not implemented: equipFeet\");\n }\n\n equipFlag(_item: number): void {\n throw new Error(\"Not implemented: equipFlag\");\n }\n\n equipPhoto(_item: number): void {\n throw new Error(\"Not implemented: equipPhoto\");\n }\n\n buddyRequest(_id: number): void {\n throw new Error(\"Not implemented: buddyRequest\");\n }\n\n buddyAccept(_id: number): void {\n throw new Error(\"Not implemented: buddyAccept\");\n }\n\n buddyReject(_id: number): void {\n throw new Error(\"Not implemented: buddyReject\");\n }\n\n buddyRequestSeen(_id: number): void {\n throw new Error(\"Not implemented: buddyRequestSeen\");\n }\n\n getBuddy(_id: number, _type: \"buddies\" | \"buddyRequests\"): void {\n throw new Error(\"Not implemented: getBuddy\");\n }\n\n removeBuddy(_id: number): void {\n throw new Error(\"Not implemented: removeBuddy\");\n }\n\n addIgnore(_id: number): void {\n throw new Error(\"Not implemented: addIgnore\");\n }\n\n removeIgnore(_id: number): void {\n throw new Error(\"Not implemented: removeIgnore\");\n }\n\n getPlayer(_id: number): void {\n throw new Error(\"Not implemented: getPlayer\");\n }\n\n getAllSlots(): void {\n throw new Error(\"Not implemented: getAllSlots\");\n }\n\n getMascots(): void {\n throw new Error(\"Not implemented: getMascots\");\n }\n\n sendPostcard(_userId: number, _cardId: string): void {\n throw new Error(\"Not implemented: sendPostcard\");\n }\n\n getStamps(_userId: number): void {\n throw new Error(\"Not implemented: getStamps\");\n }\n\n getPostcards(): void {\n throw new Error(\"Not implemented: getPostcards\");\n }\n\n getIglooOpen(_igloo: number): void {\n throw new Error(\"Not implemented: getIglooOpen\");\n }\n\n getIgloos(): void {\n throw new Error(\"Not implemented: getIgloos\");\n }\n\n getPuffles(_userId: number): void {\n throw new Error(\"Not implemented: getPuffles\");\n }\n\n adoptPuffle(_type: number, _name: string): void {\n throw new Error(\"Not implemented: adoptPuffle\");\n }\n\n getIglooLikes(): void {\n throw new Error(\"Not implemented: getIglooLikes\");\n }\n\n checkPuffleSprite(_puffleSprite: boolean): void {\n throw new Error(\"Not implemented: checkPuffleSprite\");\n }\n\n joinIgloo(_igloo: number, _x?: number, _y?: number): void {\n throw new Error(\"Not implemented: joinIgloo\");\n }\n\n gameOver(_coins: number): void {\n throw new Error(\"Not implemented: gameOver\");\n }\n\n collectStamp(_stamp: number): void {\n throw new Error(\"Not implemented: collectStamp\");\n }\n\n /** Fetch ninja rank, progress, and card deck. Listen for `get_ninja` event. */\n getNinja(): void {\n throw new Error(\"Not implemented: getNinja\");\n }\n\n /** Fetch state of all Dojo mats. Listen for `get_waddles` event. */\n getMats(): void {\n throw new Error(\"Not implemented: getMats\");\n }\n\n /** Join Sensei matchmaking queue. Listen for `tick_matchmaking` events. */\n joinMatchmaking(): void {\n throw new Error(\"Not implemented: joinMatchmaking\");\n }\n\n /** Leave Sensei matchmaking queue. */\n leaveMatchmaking(): void {\n throw new Error(\"Not implemented: leaveMatchmaking\");\n }\n\n /** Start a Card-Jitsu match after entering a game room. Listen for `start_game` event. */\n startGame(): void {\n throw new Error(\"Not implemented: startGame\");\n }\n\n /** Play a card from your hand by slot index. Listen for `move_my_card` event. */\n selectCard(_slot: number): void {\n throw new Error(\"Not implemented: selectCard\");\n }\n\n /** Preload a power card animation asset. */\n loadAnimation(_animation: string): void {\n throw new Error(\"Not implemented: loadAnimation\");\n }\n\n /** Sit on a Dojo mat to wait for an opponent. Listen for `update_waddle` events. */\n joinMat(_waddle: number): void {\n throw new Error(\"Not implemented: joinMat\");\n }\n}\n","import { EventEmitter } from \"node:events\";\nimport type { BaseAdapter, ConnectOptions } from \"./adapters/base-adapter.js\";\nimport { type AdapterName, createAdapter } from \"./adapters/index.js\";\nimport { CardJitsu } from \"./games/card-jitsu.js\";\nimport type {\n LoginOptions,\n LoginResult,\n QueueUpdate,\n ServerInfo,\n TokenLoginOptions,\n} from \"./types/adapter-types.js\";\nimport type { ServerMessages } from \"./types/message-types.js\";\nimport type { PlayerData, RoomUser } from \"./types/player-types.js\";\n\n/** Actions with explicit switch-case handling or typed in ServerMessages — not truly unknown. */\nconst KNOWN_ACTIONS = new Set<string>([\n\t// Handled in switch\n\t\"load_player\", \"join_room\", \"add_player\", \"remove_player\",\n\t\"send_position\", \"send_frame\", \"update_player\", \"kick\", \"close_with_error\",\n\t// Typed passthrough (emitted as-is, no state updates needed)\n\t\"send_message\", \"send_emote\", \"cpj_ping\", \"open_sprite\", \"close_sprite\",\n\t\"set_weather\", \"server_error\", \"error\", \"stamp_earned\", \"game_over\",\n\t\"join_game_room\", \"get_ninja\", \"get_waddles\", \"update_waddle\",\n\t\"join_matchmaking\", \"tick_matchmaking\", \"start_game\", \"set_cards\",\n\t\"add_enemy_cards\", \"start_round\", \"enable_cards\", \"remove_card\",\n\t\"move_my_card\", \"card_effect\", \"round_over\", \"play_animation\", \"game_won\",\n\t\"get_player\", \"buddy_request\", \"buddy_accept\", \"buddy_reject\",\n\t\"buddy_request_seen\", \"get_buddy\", \"send_postcard\", \"stamps_result\",\n\t\"ignore_add\", \"ignore_remove\", \"add_item\", \"get_postcards\",\n\t\"get_igloo_open\", \"get_igloos\", \"get_igloo_likes\", \"join_igloo\", \"get_puffles\",\n\t\"get_mascots\", \"wait_queue_update\", \"slot\",\n\t\"snowball\", \"send_safe\", \"stop_walking\", \"update_table\", \"transform_player\",\n\t\"adopt_puffle\", \"info\",\n\t\"queue_server_join\",\n\t\"disconnect\", \"unknown_packet\",\n]);\n\ntype ServerMessageHandler<K extends keyof ServerMessages> = (\n args: ServerMessages[K],\n) => void;\n\nexport type LogFn = (message: string, ...args: unknown[]) => void;\n\nexport type ClientOptions = {\n debug?: boolean | LogFn;\n};\n\ntype MessagePayload = {\n action: string;\n args: Record<string, unknown>;\n};\n\nfunction isMessagePayload(msg: unknown): msg is MessagePayload {\n return (\n typeof msg === \"object\" && msg !== null && \"action\" in msg && \"args\" in msg\n );\n}\n\nexport class Client extends EventEmitter {\n player: PlayerData | null = null;\n room: number | null = null;\n users: Map<number, RoomUser> = new Map();\n connected = false;\n\n private adapter: BaseAdapter;\n private loginResult: LoginResult | null = null;\n private log: LogFn | null = null;\n private _cardJitsu: CardJitsu | null = null;\n\n get cardJitsu(): CardJitsu {\n if (!this._cardJitsu)\n this._cardJitsu = new CardJitsu(this.adapter, this.waitFor.bind(this));\n return this._cardJitsu;\n }\n\n constructor(server: AdapterName, options?: ClientOptions) {\n super();\n this.adapter = createAdapter(server);\n\n if (options?.debug) {\n this.log =\n typeof options.debug === \"function\"\n ? options.debug\n : console.log.bind(console);\n }\n }\n\n async login(\n options: LoginOptions | TokenLoginOptions,\n ): Promise<ServerInfo[]> {\n this.log?.(\"[login] logging in as\", options.username);\n this.loginResult = await this.adapter.login(options);\n this.log?.(\"[login] success —\", this.loginResult.servers.length, \"servers\");\n return this.loginResult.servers;\n }\n\n async connect(serverName: string, options?: ConnectOptions): Promise<void> {\n if (!this.loginResult) throw new Error(\"Must call login() first\");\n\n this.log?.(\"[connect] joining\", serverName);\n\n const connectOptions: ConnectOptions = {\n ...options,\n onQueueUpdate: (update: QueueUpdate) => {\n this.log?.(\"[queue]\", `#${update.position}/${update.queueLength}`);\n this.emit(\"wait_queue_update\", update);\n options?.onQueueUpdate?.(update);\n },\n };\n\n const socket = await this.adapter.connect(\n serverName,\n this.loginResult,\n connectOptions,\n );\n\n socket.on(\"message\", (msg: unknown) => {\n if (!isMessagePayload(msg)) return;\n this.handleMessage(msg);\n });\n\n socket.on(\"disconnect\", () => {\n this.log?.(\"[disconnect] connection lost\");\n this.cleanup();\n this.emit(\"disconnect\");\n });\n\n await new Promise<void>((resolve, reject) => {\n const timeout = setTimeout(() => {\n reject(new Error(\"Waiting for load_player timed out\"));\n }, 10_000);\n\n let playerLoaded = false;\n let roomJoined = false;\n\n const checkReady = (): void => {\n if (playerLoaded && roomJoined) {\n clearTimeout(timeout);\n this.connected = true;\n resolve();\n }\n };\n\n const onMessage = (msg: unknown): void => {\n if (!isMessagePayload(msg)) return;\n switch (msg.action) {\n case \"load_player\":\n playerLoaded = true;\n checkReady();\n break;\n case \"join_room\":\n roomJoined = true;\n checkReady();\n break;\n case \"kick\":\n clearTimeout(timeout);\n socket.off(\"message\", onMessage);\n reject(\n new Error(\n `Kicked: ${(msg.args as { reason?: string }).reason ?? \"unknown\"}`,\n ),\n );\n break;\n case \"close_with_error\":\n clearTimeout(timeout);\n socket.off(\"message\", onMessage);\n reject(\n new Error(\n `Kicked: ${(msg.args as { error?: string }).error ?? \"unknown\"}`,\n ),\n );\n break;\n case \"error\":\n clearTimeout(timeout);\n socket.off(\"message\", onMessage);\n reject(\n new Error(\n `Server error: ${(msg.args as { error?: string | number }).error ?? \"unknown\"}`,\n ),\n );\n break;\n }\n };\n\n const onDisconnect = (): void => {\n if (!playerLoaded || !roomJoined) {\n clearTimeout(timeout);\n reject(new Error(\"Disconnected before fully loaded\"));\n }\n };\n\n socket.on(\"message\", onMessage);\n socket.once(\"disconnect\", onDisconnect);\n });\n }\n\n on<K extends keyof ServerMessages>(\n event: K,\n listener: ServerMessageHandler<K>,\n ): this;\n on(event: string, listener: (...args: unknown[]) => void): this;\n on(event: string, listener: (...args: unknown[]) => void): this {\n return super.on(event, listener);\n }\n\n off<K extends keyof ServerMessages>(\n event: K,\n listener: ServerMessageHandler<K>,\n ): this;\n off(event: string, listener: (...args: unknown[]) => void): this;\n off(event: string, listener: (...args: unknown[]) => void): this {\n return super.off(event, listener);\n }\n\n once<K extends keyof ServerMessages>(\n event: K,\n listener: ServerMessageHandler<K>,\n ): this;\n once(event: string, listener: (...args: unknown[]) => void): this;\n once(event: string, listener: (...args: unknown[]) => void): this {\n return super.once(event, listener);\n }\n\n emit<K extends keyof ServerMessages>(\n event: K,\n args: ServerMessages[K],\n ): boolean;\n emit(event: string, ...args: unknown[]): boolean;\n emit(event: string, ...args: unknown[]): boolean {\n return super.emit(event, ...args);\n }\n\n /** Wait for a server event. Resolves with the event payload. Optional timeout in ms. Rejects on disconnect. */\n waitFor<K extends keyof ServerMessages>(\n event: K,\n timeout?: number,\n ): Promise<ServerMessages[K]> {\n return new Promise<ServerMessages[K]>((resolve, reject) => {\n let timer: ReturnType<typeof setTimeout> | undefined;\n\n const cleanup = (): void => {\n if (timer) clearTimeout(timer);\n this.off(event, handler as unknown as (...args: unknown[]) => void);\n this.off(\"disconnect\", onDisconnect);\n };\n\n const handler = ((args: ServerMessages[K]) => {\n cleanup();\n resolve(args);\n }) as ServerMessageHandler<K>;\n\n const onDisconnect = (): void => {\n cleanup();\n reject(new Error(`Disconnected while waiting for ${String(event)}`));\n };\n\n if (timeout !== undefined) {\n timer = setTimeout(() => {\n cleanup();\n reject(new Error(`Timed out waiting for ${String(event)}`));\n }, timeout);\n }\n\n this.once(event, handler);\n this.once(\"disconnect\", onDisconnect);\n });\n }\n\n sendMessage(message: string): void {\n this.adapter.sendMessage(message);\n }\n sendEmote(emote: number): void {\n this.adapter.sendEmote(emote);\n }\n sendSafe(safe: number): void {\n this.adapter.sendSafe(safe);\n }\n walk(x: number, y: number): void {\n this.adapter.walk(x, y);\n }\n sendFrame(frame: number, set?: boolean): void {\n this.adapter.sendFrame(frame, set);\n }\n snowball(x: number, y: number): void {\n this.adapter.snowball(x, y);\n }\n joinRoom(\n room: number,\n x?: number,\n y?: number,\n ): Promise<ServerMessages[\"join_room\"]> {\n this.adapter.joinRoom(room, x, y);\n return this.waitFor(\"join_room\");\n }\n addItem(item: number): Promise<ServerMessages[\"add_item\"]> {\n this.adapter.addItem(item);\n return this.waitFor(\"add_item\");\n }\n equipColor(item: number): void {\n this.adapter.equipColor(item);\n }\n equipHead(item: number): void {\n this.adapter.equipHead(item);\n }\n equipFace(item: number): void {\n this.adapter.equipFace(item);\n }\n equipNeck(item: number): void {\n this.adapter.equipNeck(item);\n }\n equipBody(item: number): void {\n this.adapter.equipBody(item);\n }\n equipHand(item: number): void {\n this.adapter.equipHand(item);\n }\n equipFeet(item: number): void {\n this.adapter.equipFeet(item);\n }\n equipFlag(item: number): void {\n this.adapter.equipFlag(item);\n }\n equipPhoto(item: number): void {\n this.adapter.equipPhoto(item);\n }\n buddyRequest(id: number): void {\n this.adapter.buddyRequest(id);\n }\n buddyAccept(id: number): Promise<ServerMessages[\"buddy_accept\"]> {\n this.adapter.buddyAccept(id);\n return this.waitFor(\"buddy_accept\");\n }\n buddyReject(id: number): Promise<ServerMessages[\"buddy_reject\"]> {\n this.adapter.buddyReject(id);\n return this.waitFor(\"buddy_reject\");\n }\n buddyRequestSeen(id: number): Promise<ServerMessages[\"buddy_request_seen\"]> {\n this.adapter.buddyRequestSeen(id);\n return this.waitFor(\"buddy_request_seen\");\n }\n getBuddy(\n id: number,\n type: \"buddies\" | \"buddyRequests\",\n ): Promise<ServerMessages[\"get_buddy\"]> {\n this.adapter.getBuddy(id, type);\n return this.waitFor(\"get_buddy\");\n }\n removeBuddy(id: number): void {\n this.adapter.removeBuddy(id);\n }\n addIgnore(id: number): Promise<ServerMessages[\"ignore_add\"]> {\n this.adapter.addIgnore(id);\n return this.waitFor(\"ignore_add\");\n }\n removeIgnore(id: number): Promise<ServerMessages[\"ignore_remove\"]> {\n this.adapter.removeIgnore(id);\n return this.waitFor(\"ignore_remove\");\n }\n getPlayer(id: number): Promise<ServerMessages[\"get_player\"]> {\n this.adapter.getPlayer(id);\n return this.waitFor(\"get_player\");\n }\n getAllSlots(): Promise<ServerMessages[\"slot\"]> {\n this.adapter.getAllSlots();\n return this.waitFor(\"slot\");\n }\n getMascots(): Promise<ServerMessages[\"get_mascots\"]> {\n this.adapter.getMascots();\n return this.waitFor(\"get_mascots\");\n }\n sendPostcard(\n userId: number,\n cardId: string,\n ): Promise<ServerMessages[\"send_postcard\"]> {\n this.adapter.sendPostcard(userId, cardId);\n return this.waitFor(\"send_postcard\");\n }\n getStamps(userId: number): Promise<ServerMessages[\"stamps_result\"]> {\n this.adapter.getStamps(userId);\n return this.waitFor(\"stamps_result\");\n }\n getPostcards(): Promise<ServerMessages[\"get_postcards\"]> {\n this.adapter.getPostcards();\n return this.waitFor(\"get_postcards\");\n }\n getIglooOpen(igloo: number): Promise<ServerMessages[\"get_igloo_open\"]> {\n this.adapter.getIglooOpen(igloo);\n return this.waitFor(\"get_igloo_open\");\n }\n getIgloos(): Promise<ServerMessages[\"get_igloos\"]> {\n this.adapter.getIgloos();\n return this.waitFor(\"get_igloos\");\n }\n getPuffles(userId: number): Promise<ServerMessages[\"get_puffles\"]> {\n this.adapter.getPuffles(userId);\n return this.waitFor(\"get_puffles\");\n }\n adoptPuffle(type: number, name: string): Promise<ServerMessages[\"adopt_puffle\"]> {\n this.adapter.adoptPuffle(type, name);\n return this.waitFor(\"adopt_puffle\");\n }\n getIglooLikes(): Promise<ServerMessages[\"get_igloo_likes\"]> {\n this.adapter.getIglooLikes();\n return this.waitFor(\"get_igloo_likes\");\n }\n checkPuffleSprite(puffleSprite: boolean): void {\n this.adapter.checkPuffleSprite(puffleSprite);\n }\n joinIgloo(\n igloo: number,\n x?: number,\n y?: number,\n ): Promise<ServerMessages[\"join_igloo\"]> {\n this.adapter.joinIgloo(igloo, x, y);\n return this.waitFor(\"join_igloo\");\n }\n gameOver(coins: number): Promise<ServerMessages[\"game_over\"]> {\n this.adapter.gameOver(coins);\n return this.waitFor(\"game_over\");\n }\n collectStamp(stamp: number): Promise<ServerMessages[\"stamp_earned\"]> {\n this.adapter.collectStamp(stamp);\n return this.waitFor(\"stamp_earned\");\n }\n\n sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n }\n\n disconnect(): void {\n this.log?.(\"[disconnect] closing connection\");\n this.adapter.disconnect();\n this.cleanup();\n }\n\n private cleanup(): void {\n this.connected = false;\n this.player = null;\n this.room = null;\n this.users.clear();\n }\n\n private handleMessage(msg: MessagePayload): void {\n const { action, args } = msg;\n let emitArgs: unknown = args;\n\n switch (action) {\n case \"load_player\": {\n const player = this.adapter.normalizePlayer(args);\n this.player = player;\n emitArgs = { user: player };\n this.log?.(\n \"[load_player]\",\n player.username,\n `id=${player.id}`,\n `coins=${player.coins}`,\n `inventory=${player.inventory.length}`,\n );\n break;\n }\n case \"join_room\": {\n const room = args.room as number;\n const rawUsers = args.users as Record<string, unknown>[];\n this.room = room;\n this.users.clear();\n const users: RoomUser[] = [];\n for (const rawUser of rawUsers) {\n const user = this.adapter.normalizeUser(rawUser);\n this.users.set(user.id, user);\n users.push(user);\n }\n emitArgs = { room, users };\n this.log?.(\"[join_room]\", `room=${room}`, `users=${users.length}`);\n break;\n }\n case \"add_player\": {\n const user = this.adapter.normalizeUser(\n args.user as Record<string, unknown>,\n );\n this.users.set(user.id, user);\n emitArgs = { user };\n this.log?.(\"[add_player]\", user.username, `id=${user.id}`);\n break;\n }\n case \"remove_player\": {\n const id = args.user as number;\n this.users.delete(id);\n this.log?.(\"[remove_player]\", `id=${id}`);\n break;\n }\n case \"send_position\": {\n const id = args.id as number;\n const user = this.users.get(id);\n if (user) {\n user.x = args.x as number;\n user.y = args.y as number;\n }\n break;\n }\n case \"send_frame\": {\n const id = args.id as number;\n const user = this.users.get(id);\n if (user) {\n user.frame = args.frame as number;\n }\n break;\n }\n case \"join_igloo\": {\n const igloo = args.igloo as number;\n const rawUsers = args.users as Record<string, unknown>[];\n this.room = igloo;\n this.users.clear();\n const iglooUsers: RoomUser[] = [];\n for (const rawUser of rawUsers) {\n const user = this.adapter.normalizeUser(rawUser);\n this.users.set(user.id, user);\n iglooUsers.push(user);\n }\n emitArgs = { ...args, users: iglooUsers };\n this.log?.(\"[join_igloo]\", `igloo=${igloo}`, `users=${iglooUsers.length}`);\n break;\n }\n case \"update_player\": {\n const id = args.id as number;\n const slot = args.slot as string;\n const item = args.item as number;\n const user = this.users.get(id);\n if (user && slot in user) {\n (user as Record<string, unknown>)[slot] = item;\n }\n break;\n }\n case \"kick\": {\n const reason = (args as { reason?: string }).reason ?? \"unknown\";\n this.log?.(\"[kick]\", reason);\n this.cleanup();\n break;\n }\n case \"close_with_error\": {\n const error = (args as { error?: string }).error ?? \"unknown\";\n this.log?.(\"[kick]\", error);\n this.cleanup();\n break;\n }\n default: {\n if (!KNOWN_ACTIONS.has(action)) {\n this.log?.(`[unknown_packet]`, action, JSON.stringify(args));\n this.emit(\"unknown_packet\", { action, args });\n }\n break;\n }\n }\n\n const eventName = action === \"error\" ? \"server_error\" : action;\n this.emit(eventName, emitArgs);\n }\n}\n","import { io, type Socket } from \"socket.io-client\";\nimport msgpackParser from \"socket.io-msgpack-parser\";\nimport type {\n LoginOptions,\n LoginResult,\n QueueUpdate,\n ServerInfo,\n TokenLoginOptions,\n} from \"../types/adapter-types.js\";\nimport type { Buddy, PlayerData, RoomUser } from \"../types/player-types.js\";\nimport { BaseAdapter, type ConnectOptions } from \"./base-adapter.js\";\n\nconst BASE_URL = \"wss://play.cpjourney.net\";\nconst DEFAULT_SECRET = \"skip\";\n\ntype LoginResponse = {\n success: boolean;\n username: string;\n key: string;\n populations: Record<string, number>;\n moderator: boolean;\n buddyWorlds: string[];\n};\n\ntype GameAuthResponse = {\n success: boolean;\n token?: string;\n};\n\ntype ServerMessage = {\n action: string;\n args: Record<string, unknown>;\n};\n\nexport class CpjourneyAdapter extends BaseAdapter {\n readonly id = \"CPJourney\";\n\n async login(options: LoginOptions | TokenLoginOptions): Promise<LoginResult> {\n const loginSocket = this.createSocket(\"/world/login/\");\n\n const result = await new Promise<LoginResult>((resolve, reject) => {\n const timeout = setTimeout(() => {\n loginSocket.disconnect();\n reject(new Error(\"Login timed out\"));\n }, 10_000);\n\n loginSocket.on(\"connect\", () => {\n const secret = options.secret ?? DEFAULT_SECRET;\n const args =\n \"token\" in options\n ? { username: options.username, token: options.token, secret }\n : {\n username: options.username,\n password: options.password,\n secret,\n };\n\n loginSocket.emit(\"message\", { action: \"login\", args });\n });\n\n loginSocket.on(\"message\", (msg: ServerMessage) => {\n if (msg.action !== \"login\") return;\n\n clearTimeout(timeout);\n loginSocket.disconnect();\n\n const response = msg.args as LoginResponse;\n\n if (!response.success) {\n reject(new Error(\"Login failed\"));\n return;\n }\n\n const servers: ServerInfo[] = Object.entries(response.populations).map(\n ([name, population]) => ({ name, population }),\n );\n\n resolve({\n servers,\n key: response.key,\n username: response.username,\n moderator: response.moderator,\n buddyWorlds: response.buddyWorlds ?? [],\n });\n });\n\n loginSocket.on(\"connect_error\", (err: Error) => {\n clearTimeout(timeout);\n loginSocket.disconnect();\n reject(new Error(`Login connection failed: ${err.message}`));\n });\n });\n\n return result;\n }\n\n async connect(\n serverName: string,\n loginResult: LoginResult,\n options?: ConnectOptions,\n ): Promise<Socket> {\n // Queue step on a fresh login socket (matches browser flow).\n // The original login socket is dead — server disconnects after login response.\n await this.queueForServer(serverName, options);\n\n // Connect game socket — still needs game_auth in Node.js\n // (browser uses cookies from HTTP polling, not available cross-Manager)\n const gameSocket = this.createSocket(`/world/${serverName.toLowerCase()}/`);\n this.socket = gameSocket;\n\n await new Promise<void>((resolve, reject) => {\n let authSent = false;\n\n gameSocket.on(\"connect\", () => {\n gameSocket.emit(\"message\", {\n action: \"game_auth\",\n args: {\n username: loginResult.username,\n key: loginResult.key,\n createToken: false,\n joinInvis: false,\n takeoverMascot: false,\n token: \"\",\n },\n });\n });\n\n gameSocket.on(\"message\", (msg: ServerMessage) => {\n switch (msg.action) {\n case \"wait_queue_update\": {\n options?.onQueueUpdate?.(msg.args as QueueUpdate);\n break;\n }\n case \"game_auth\": {\n if (authSent) break;\n authSent = true;\n\n const response = msg.args as GameAuthResponse;\n if (!response.success) {\n gameSocket.disconnect();\n reject(new Error(\"Game auth failed\"));\n return;\n }\n\n gameSocket.emit(\"message\", {\n action: \"join_server\",\n args: {},\n });\n resolve();\n break;\n }\n }\n });\n\n gameSocket.on(\"connect_error\", (err: Error) => {\n gameSocket.disconnect();\n reject(new Error(`Game connection failed: ${err.message}`));\n });\n });\n\n return gameSocket;\n }\n\n private async queueForServer(\n serverName: string,\n options?: ConnectOptions,\n ): Promise<void> {\n const queueSocket = this.createSocket(\"/world/login/\");\n\n await new Promise<void>((resolve, reject) => {\n const timeout = setTimeout(() => {\n queueSocket.disconnect();\n reject(new Error(\"Queue timed out\"));\n }, 60_000);\n\n queueSocket.on(\"connect\", () => {\n queueSocket.emit(\"message\", {\n action: \"queue_server_join\",\n args: { server: serverName },\n });\n });\n\n queueSocket.on(\"message\", (msg: ServerMessage) => {\n switch (msg.action) {\n case \"wait_queue_update\":\n options?.onQueueUpdate?.(msg.args as QueueUpdate);\n break;\n case \"queue_server_join\":\n clearTimeout(timeout);\n queueSocket.disconnect();\n resolve();\n break;\n }\n });\n\n queueSocket.once(\"disconnect\", () => {\n clearTimeout(timeout);\n resolve();\n });\n\n queueSocket.on(\"connect_error\", (err: Error) => {\n clearTimeout(timeout);\n queueSocket.disconnect();\n reject(new Error(`Queue connection failed: ${err.message}`));\n });\n });\n }\n\n send(action: string, args: Record<string, unknown>): void {\n if (!this.socket) throw new Error(\"Not connected\");\n this.socket.emit(\"message\", { action, args });\n }\n\n disconnect(): void {\n this.socket?.disconnect();\n this.socket = null;\n }\n\n override normalizeUser(raw: Record<string, unknown>): RoomUser {\n const { id, username, displayName, joinTime, x, y, frame, walking,\n color, head, face, neck, body, hand, feet, flag, photo,\n ...rest } = raw;\n return {\n ...this.extractAppearance(raw),\n id: id as number,\n username: username as string,\n displayName: displayName as string | undefined,\n joinTime: joinTime as string | undefined,\n x: (x as number) ?? 0,\n y: (y as number) ?? 0,\n frame: (frame as number) ?? 0,\n walking: walking as number | undefined,\n meta: rest,\n _raw: raw,\n };\n }\n\n override normalizePlayer(raw: Record<string, unknown>): PlayerData {\n const user = raw.user as Record<string, unknown>;\n const normalized = this.normalizeUser(user);\n const { user: _user, coins, rank, inventory, furniture, flooring,\n buddies, buddyRequests, ignores, igloos, ...rest } = raw;\n return {\n ...normalized,\n _raw: raw,\n coins: (coins as number) ?? 0,\n rank: (rank as number) ?? 0,\n inventory: (inventory as number[]) ?? [],\n furniture: (furniture as unknown[]) ?? [],\n flooring: (flooring as unknown[]) ?? [],\n buddies: (user.buddies as Buddy[]) ?? [],\n buddyRequests: (user.buddyRequests as number[]) ?? [],\n ignores: (user.ignores as number[]) ?? [],\n igloos: (igloos as unknown[]) ?? [],\n meta: { ...normalized.meta, ...rest },\n };\n }\n\n override sendMessage(message: string): void {\n this.send(\"send_message\", { message });\n }\n\n override sendEmote(emote: number): void {\n this.send(\"send_emote\", { emote });\n }\n\n override sendSafe(safe: number): void {\n this.send(\"send_safe\", { safe });\n }\n\n override walk(x: number, y: number): void {\n this.send(\"send_position\", { x, y });\n }\n\n override sendFrame(frame: number, set?: boolean): void {\n this.send(\"send_frame\", { frame, set });\n }\n\n override snowball(x: number, y: number): void {\n this.send(\"snowball\", { x, y });\n }\n\n override joinRoom(room: number, x?: number, y?: number): void {\n this.send(\"join_room\", { room, x: x ?? 0, y: y ?? 0 });\n }\n\n override addItem(item: number): void {\n this.send(\"add_item\", { item });\n }\n\n override equipColor(item: number): void {\n this.send(\"update_color\", { item });\n }\n\n override equipHead(item: number): void {\n this.send(\"update_head\", { item });\n }\n\n override equipFace(item: number): void {\n this.send(\"update_face\", { item });\n }\n\n override equipNeck(item: number): void {\n this.send(\"update_neck\", { item });\n }\n\n override equipBody(item: number): void {\n this.send(\"update_body\", { item });\n }\n\n override equipHand(item: number): void {\n this.send(\"update_hand\", { item });\n }\n\n override equipFeet(item: number): void {\n this.send(\"update_feet\", { item });\n }\n\n override equipFlag(item: number): void {\n this.send(\"update_flag\", { item });\n }\n\n override equipPhoto(item: number): void {\n this.send(\"update_photo\", { item });\n }\n\n override buddyRequest(id: number): void {\n this.send(\"buddy_request\", { id });\n }\n\n override buddyAccept(id: number): void {\n this.send(\"buddy_accept\", { id });\n }\n\n override buddyReject(id: number): void {\n this.send(\"buddy_reject\", { id });\n }\n\n override buddyRequestSeen(id: number): void {\n this.send(\"buddy_request_seen\", { id });\n }\n\n override getBuddy(id: number, type: \"buddies\" | \"buddyRequests\"): void {\n this.send(\"get_buddy\", { id, type });\n }\n\n override removeBuddy(id: number): void {\n this.send(\"remove_buddy\", { id });\n }\n\n override addIgnore(id: number): void {\n this.send(\"ignore_add\", { id });\n }\n\n override removeIgnore(id: number): void {\n this.send(\"ignore_remove\", { id });\n }\n\n override getPlayer(id: number): void {\n this.send(\"get_player\", { id });\n }\n\n override getAllSlots(): void {\n this.send(\"get_all_slots\", {});\n }\n\n override getMascots(): void {\n this.send(\"get_mascots\", {});\n }\n\n override sendPostcard(userId: number, cardId: string): void {\n this.send(\"send_postcard\", { userId, cardId });\n }\n\n override getStamps(userId: number): void {\n this.send(\"get_stamps\", { userId });\n }\n\n override getPostcards(): void {\n this.send(\"get_postcards\", {});\n }\n\n override getIglooOpen(igloo: number): void {\n this.send(\"get_igloo_open\", { igloo });\n }\n\n override getIgloos(): void {\n this.send(\"get_igloos\", {});\n }\n\n override getPuffles(userId: number): void {\n this.send(\"get_puffles\", { userId });\n }\n\n override adoptPuffle(type: number, name: string): void {\n this.send(\"adopt_puffle\", { type, name });\n }\n\n override getIglooLikes(): void {\n this.send(\"get_igloo_likes\", {});\n }\n\n override checkPuffleSprite(puffleSprite: boolean): void {\n this.send(\"check_puffle_sprite\", { puffleSprite });\n }\n\n override joinIgloo(igloo: number, x?: number, y?: number): void {\n this.send(\"join_igloo\", { igloo, x: x ?? 0, y: y ?? 0 });\n }\n\n override gameOver(coins: number): void {\n this.send(\"game_over\", { coins });\n }\n\n override collectStamp(stamp: number): void {\n this.send(\"collect_stamp\", { stamp });\n }\n\n override getNinja(): void {\n this.send(\"get_ninja\", {});\n }\n\n override getMats(): void {\n this.send(\"get_waddles\", {});\n }\n\n override joinMatchmaking(): void {\n this.send(\"join_matchmaking\", {});\n }\n\n override leaveMatchmaking(): void {\n this.send(\"leave_matchmaking\", {});\n }\n\n override startGame(): void {\n this.send(\"start_game\", {});\n }\n\n override selectCard(slot: number): void {\n this.send(\"select_card\", { slot });\n }\n\n override loadAnimation(animation: string): void {\n this.send(\"load_animation\", { animation });\n }\n\n override joinMat(waddle: number): void {\n this.send(\"join_waddle\", { waddle });\n }\n\n private createSocket(path: string): Socket {\n return io(BASE_URL, {\n path,\n parser: msgpackParser,\n transports: [\"polling\", \"websocket\"],\n reconnection: false,\n });\n }\n}\n","import { io, type Socket } from \"socket.io-client\";\nimport msgpackParser from \"socket.io-msgpack-parser\";\nimport type {\n LoginOptions,\n LoginResult,\n QueueUpdate,\n ServerInfo,\n TokenLoginOptions,\n} from \"../types/adapter-types.js\";\nimport type { Buddy, PlayerData, RoomUser } from \"../types/player-types.js\";\nimport { BaseAdapter, type ConnectOptions } from \"./base-adapter.js\";\n\nconst LOGIN_URL = \"https://api.cplegacy.com/login\";\nconst TOKEN_LOGIN_URL = \"https://api.cplegacy.com/token_login\";\n\ntype LoginResponse = {\n success: boolean;\n username: string;\n key: string;\n populations: Record<string, number>;\n requires2FA: boolean;\n message?: string;\n wantedVersion?: string;\n};\n\ntype GameAuthResponse = {\n success: boolean;\n};\n\n/**\n * Wraps a CPLegacy socket to normalize its positional message format\n * `(\"message\", action, args)` into the `{ action, args }` envelope\n * that the Client class expects.\n */\nfunction wrapSocket(raw: Socket): Socket {\n const original = raw.on.bind(raw);\n\n raw.on = ((event: string, listener: (...args: unknown[]) => void) => {\n if (event === \"message\") {\n return original(event, (action: unknown, args: unknown) => {\n listener({ action, args: args ?? {} });\n });\n }\n return original(event, listener);\n }) as typeof raw.on;\n\n return raw;\n}\n\nexport class CplegacyAdapter extends BaseAdapter {\n readonly id = \"CPLegacy\";\n private version = \"\";\n\n async login(options: LoginOptions | TokenLoginOptions): Promise<LoginResult> {\n const url = \"token\" in options ? TOKEN_LOGIN_URL : LOGIN_URL;\n const body: Record<string, unknown> =\n \"token\" in options\n ? { username: options.username, token: options.token }\n : {\n username: options.username,\n password: options.password,\n version: this.version,\n };\n\n let data = await this.postLogin(url, body);\n\n // Version negotiation: server returns wantedVersion when ours is stale/empty\n if (!data.success && data.wantedVersion) {\n this.version = data.wantedVersion;\n body.version = this.version;\n data = await this.postLogin(url, body);\n }\n\n if (!data.success) {\n throw new Error(`Login failed: ${data.message ?? \"unknown error\"}`);\n }\n\n const servers: ServerInfo[] = Object.entries(data.populations ?? {}).map(\n ([name, population]) => ({ name, population }),\n );\n\n return {\n servers,\n key: data.key,\n username: data.username,\n moderator: false,\n buddyWorlds: [],\n };\n }\n\n async connect(\n serverName: string,\n loginResult: LoginResult,\n options?: ConnectOptions,\n ): Promise<Socket> {\n const wsUrl = `wss://${serverName.toLowerCase()}.server.cplegacy.com`;\n const rawSocket = io(wsUrl, {\n path: \"/socket.io/\",\n parser: msgpackParser,\n transports: [\"websocket\"],\n reconnection: false,\n });\n this.socket = rawSocket;\n\n await new Promise<void>((resolve, reject) => {\n const timeout = setTimeout(() => {\n rawSocket.disconnect();\n reject(new Error(\"Game connection timed out\"));\n }, 15_000);\n\n rawSocket.on(\"connect\", () => {\n rawSocket.emit(\"message\", \"game_auth\", {\n username: loginResult.username,\n key: loginResult.key,\n createToken: false,\n token: \"\",\n });\n });\n\n rawSocket.on(\n \"message\",\n (action: string, args: Record<string, unknown>) => {\n switch (action) {\n case \"wait_queue_update\": {\n options?.onQueueUpdate?.(args as unknown as QueueUpdate);\n break;\n }\n case \"game_auth\": {\n const response = args as unknown as GameAuthResponse;\n if (!response.success) {\n clearTimeout(timeout);\n rawSocket.disconnect();\n reject(new Error(\"Game auth failed\"));\n return;\n }\n\n // CPLegacy requires explicitly requesting load_player before join_server\n rawSocket.emit(\"message\", \"load_player\", {});\n rawSocket.emit(\"message\", \"join_server\", {});\n clearTimeout(timeout);\n resolve();\n break;\n }\n }\n },\n );\n\n rawSocket.on(\"connect_error\", (err: Error) => {\n clearTimeout(timeout);\n rawSocket.disconnect();\n reject(new Error(`Game connection failed: ${err.message}`));\n });\n });\n\n // Return wrapped socket so Client receives normalized { action, args } messages\n return wrapSocket(rawSocket);\n }\n\n send(action: string, args: Record<string, unknown>): void {\n if (!this.socket) throw new Error(\"Not connected\");\n this.socket.emit(\"message\", action, args);\n }\n\n disconnect(): void {\n this.socket?.disconnect();\n this.socket = null;\n }\n\n override normalizeUser(raw: Record<string, unknown>): RoomUser {\n return {\n ...this.extractAppearance(raw),\n id: raw.id as number,\n username: raw.username as string,\n displayName: (raw.realUsername as string) ?? (raw.username as string),\n joinTime: raw.joinTime as string | undefined,\n x: (raw.x as number) ?? 0,\n y: (raw.y as number) ?? 0,\n frame: (raw.frame as number) ?? 0,\n walking: (raw.walking as number) ?? undefined,\n meta: {\n internalUsername: raw.username as string,\n approved: raw.approved,\n emailVerified: raw.emailVerified,\n safeChat: raw.safeChat,\n tutorial: raw.tutorial,\n loginStreak: raw.loginStreak,\n walkingColor: raw.walkingColor,\n stampbookColor: raw.stampbookColor,\n stampbookClasp: raw.stampbookClasp,\n stampbookPattern: raw.stampbookPattern,\n ninjaPoints: raw.ninjaPoints,\n highestNinjaRank: raw.highestNinjaRank,\n character: raw.character,\n transformed: raw.transformed,\n },\n _raw: raw,\n };\n }\n\n override normalizePlayer(raw: Record<string, unknown>): PlayerData {\n const user = raw.user as Record<string, unknown>;\n return {\n ...this.normalizeUser(user),\n _raw: raw,\n coins: (user.coins as number) ?? 0,\n rank: (user.rank as number) ?? 0,\n inventory: (raw.inventory as number[]) ?? [],\n furniture: raw.furniture as Record<string, unknown> | undefined,\n buddies: [],\n buddyRequests:\n (raw.pending as Buddy[] | undefined)?.map((b) => b.id) ?? [],\n ignores: [],\n igloos: (raw.igloos as unknown[]) ?? [],\n };\n }\n\n override sendMessage(message: string): void {\n this.send(\"send_message\", { message });\n }\n\n override sendEmote(emote: number): void {\n this.send(\"send_emote\", { emote });\n }\n\n override sendSafe(safe: number): void {\n this.send(\"send_safe\", { safe });\n }\n\n override walk(x: number, y: number): void {\n this.send(\"send_position\", { x, y });\n }\n\n override sendFrame(frame: number, set?: boolean): void {\n this.send(\"send_frame\", { frame, set });\n }\n\n override snowball(x: number, y: number): void {\n this.send(\"snowball\", { x, y });\n }\n\n override joinRoom(room: number, x?: number, y?: number): void {\n this.send(\"join_room\", { room, x: x ?? 0, y: y ?? 0 });\n }\n\n override addItem(item: number): void {\n this.send(\"add_item\", { item });\n }\n\n override equipColor(item: number): void {\n this.send(\"update_color\", { item });\n }\n\n override equipHead(item: number): void {\n this.send(\"update_head\", { item });\n }\n\n override equipFace(item: number): void {\n this.send(\"update_face\", { item });\n }\n\n override equipNeck(item: number): void {\n this.send(\"update_neck\", { item });\n }\n\n override equipBody(item: number): void {\n this.send(\"update_body\", { item });\n }\n\n override equipHand(item: number): void {\n this.send(\"update_hand\", { item });\n }\n\n override equipFeet(item: number): void {\n this.send(\"update_feet\", { item });\n }\n\n override equipFlag(item: number): void {\n this.send(\"update_flag\", { item });\n }\n\n override equipPhoto(item: number): void {\n this.send(\"update_photo\", { item });\n }\n\n override buddyRequest(id: number): void {\n this.send(\"buddy_request\", { id });\n }\n\n override buddyAccept(id: number): void {\n this.send(\"buddy_accept\", { id });\n }\n\n override buddyReject(id: number): void {\n this.send(\"buddy_reject\", { id });\n }\n\n override removeBuddy(id: number): void {\n this.send(\"remove_buddy\", { id });\n }\n\n override addIgnore(id: number): void {\n this.send(\"ignore_add\", { id });\n }\n\n override removeIgnore(id: number): void {\n this.send(\"ignore_remove\", { id });\n }\n\n override getPlayer(id: number): void {\n this.send(\"get_player\", { id });\n }\n\n override getStamps(userId: number): void {\n this.send(\"get_stamps\", { userId });\n }\n\n override getPostcards(): void {\n this.send(\"get_postcards\", {});\n }\n\n override joinIgloo(igloo: number, x?: number, y?: number): void {\n this.send(\"join_igloo\", { igloo, x: x ?? 0, y: y ?? 0 });\n }\n\n override gameOver(coins: number): void {\n this.send(\"game_over\", { coins });\n }\n\n override collectStamp(stamp: number): void {\n this.send(\"collect_stamp\", { stamp });\n }\n\n private async postLogin(\n url: string,\n body: Record<string, unknown>,\n ): Promise<LoginResponse> {\n const resp = await fetch(url, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n Accept: \"application/json\",\n },\n body: JSON.stringify(body),\n });\n\n return resp.json() as Promise<LoginResponse>;\n }\n}\n","import { createHash } from \"node:crypto\";\nimport { EventEmitter } from \"node:events\";\nimport WebSocket from \"ws\";\nimport type {\n LoginOptions,\n LoginResult,\n TokenLoginOptions,\n} from \"../types/adapter-types.js\";\nimport type { PlayerData, RoomUser } from \"../types/player-types.js\";\nimport { BaseAdapter, type ConnectOptions } from \"./base-adapter.js\";\n\nconst LOGIN_WS_URL = \"wss://server.cpzero.net/login\";\nconst GAME_WS_URL = \"wss://server.cpzero.net/sub_zero\";\nconst API_VERSION = \"253\";\nconst LOGIN_ZONE = \"w1\";\nconst NUL = \"\\0\";\n\n/**\n * CPZero user string field indices.\n * Extended Houdini format with 15 clothing slots (indices 3–17).\n */\nconst U = {\n ID: 0,\n USERNAME: 1,\n // 2 = agent/approval\n COLOR: 3,\n HEAD: 4,\n FACE: 5,\n NECK: 6,\n BODY: 7,\n HAND: 8,\n BACK: 9,\n BODY2: 10,\n HAND2: 11,\n BEAK: 12,\n HAIR: 13,\n FEET: 14,\n MOUNT: 15,\n FLAG: 16,\n PHOTO: 17,\n X: 18,\n Y: 19,\n FRAME: 20,\n // 21 = member\n RANK: 22,\n} as const;\n\nfunction md5(input: string): string {\n return createHash(\"md5\").update(input).digest(\"hex\");\n}\n\n/** MD5 then swap the two 16-char halves — classic Houdini password hash. */\nfunction swapMD5(input: string): string {\n const hash = md5(input);\n return hash.substring(16, 32) + hash.substring(0, 16);\n}\n\nfunction int(v: string | undefined): number {\n const n = Number(v);\n return Number.isNaN(n) ? 0 : n;\n}\n\n/**\n * Parse a pipe-delimited user string into a keyed object.\n * Example: `32924|kingofxiaomi|1|15|674|0|0|...|x|y|frame|...`\n */\nfunction parseUserString(str: string): Record<string, unknown> {\n const f = str.split(\"|\");\n return {\n id: int(f[U.ID]),\n username: f[U.USERNAME] ?? \"\",\n color: int(f[U.COLOR]),\n head: int(f[U.HEAD]),\n face: int(f[U.FACE]),\n neck: int(f[U.NECK]),\n body: int(f[U.BODY]),\n hand: int(f[U.HAND]),\n back: int(f[U.BACK]),\n body2: int(f[U.BODY2]),\n hand2: int(f[U.HAND2]),\n beak: int(f[U.BEAK]),\n hair: int(f[U.HAIR]),\n feet: int(f[U.FEET]),\n mount: int(f[U.MOUNT]),\n flag: int(f[U.FLAG]),\n photo: int(f[U.PHOTO]),\n x: int(f[U.X]),\n y: int(f[U.Y]),\n frame: int(f[U.FRAME]),\n rank: int(f[U.RANK]),\n };\n}\n\n/**\n * Minimal Socket-like wrapper around a raw WebSocket.\n * Emits `\"message\"` with `{ action, args }` payloads so the Client class\n * can consume CPZero messages identically to Socket.IO adapters.\n */\nclass SmartFoxSocket extends EventEmitter {\n private ws: WebSocket;\n private _closed = false;\n private _buffering = true;\n private _buffer: { action: string; args: Record<string, unknown> }[] = [];\n\n constructor(ws: WebSocket) {\n super();\n this.ws = ws;\n\n ws.on(\"close\", () => {\n this._closed = true;\n this.emit(\"disconnect\");\n });\n\n ws.on(\"error\", (err) => {\n this.emit(\"connect_error\", err);\n });\n }\n\n /** Emit a `\"message\"` event with the standard `{ action, args }` shape. */\n dispatchMessage(action: string, args: Record<string, unknown>): void {\n if (this._buffering) {\n this._buffer.push({ action, args });\n }\n this.emit(\"message\", { action, args });\n }\n\n /**\n * Stop buffering and replay all buffered messages on the next microtask.\n * This gives the Client time to attach its `socket.on(\"message\", ...)` listener\n * after `connect()` resolves.\n */\n flush(): void {\n this._buffering = false;\n const buffered = this._buffer;\n this._buffer = [];\n setTimeout(() => {\n for (const msg of buffered) {\n this.emit(\"message\", msg);\n }\n }, 0);\n }\n\n send(data: string): void {\n if (!this._closed) this.ws.send(data + NUL);\n }\n\n disconnect(): void {\n if (!this._closed) {\n this._closed = true;\n this.ws.close();\n }\n }\n\n get connected(): boolean {\n return !this._closed && this.ws.readyState === WebSocket.OPEN;\n }\n}\n\n/**\n * Map `%xt%` command names to the normalized action + args shape\n * that the Client class expects.\n */\nfunction translateXt(\n cmd: string,\n parts: string[],\n): { action: string; args: Record<string, unknown> } | null {\n switch (cmd) {\n case \"lp\": {\n // load_player: parts[0] = user string, parts[1..] = extra fields\n const user = parseUserString(parts[0] ?? \"\");\n const coins = int(parts[1]);\n const rank = user.rank as number;\n return {\n action: \"load_player\",\n args: { user, coins, rank },\n };\n }\n\n case \"jr\": {\n // join_room: parts[0] = roomId, parts[1..] = user strings\n const room = int(parts[0]);\n const users = parts.slice(1).filter(Boolean).map(parseUserString);\n return { action: \"join_room\", args: { room, users } };\n }\n\n case \"ap\": {\n // add_player: single user string\n const user = parseUserString(parts[0] ?? \"\");\n return { action: \"add_player\", args: { user } };\n }\n\n case \"rp\": {\n // remove_player: user id\n return { action: \"remove_player\", args: { user: int(parts[0]) } };\n }\n\n case \"sp\": {\n // send_position: userId, x, y\n return {\n action: \"send_position\",\n args: { id: int(parts[0]), x: int(parts[1]), y: int(parts[2]) },\n };\n }\n\n case \"sf\": {\n // send_frame: userId, frame\n return {\n action: \"send_frame\",\n args: { id: int(parts[0]), frame: int(parts[1]) },\n };\n }\n\n case \"sm\": {\n // send_message: userId, message\n return {\n action: \"send_message\",\n args: { id: int(parts[0]), message: parts[1] ?? \"\" },\n };\n }\n\n case \"se\": {\n // send_emote: userId, emote\n return {\n action: \"send_emote\",\n args: { id: int(parts[0]), emote: int(parts[1]) },\n };\n }\n\n case \"sa\": {\n // send_action (safe chat): userId, action\n return {\n action: \"send_safe\",\n args: { id: int(parts[0]), safe: int(parts[1]) },\n };\n }\n\n case \"sb\": {\n // snowball: userId, x, y\n return {\n action: \"snowball\",\n args: { id: int(parts[0]), x: int(parts[1]), y: int(parts[2]) },\n };\n }\n\n case \"gp\": {\n // get_player response: user string\n const user = parseUserString(parts[0] ?? \"\");\n return { action: \"get_player\", args: { user } };\n }\n\n // Equip updates: userId, itemId\n case \"upc\":\n return {\n action: \"update_player\",\n args: { id: int(parts[0]), item: int(parts[1]), slot: \"color\" },\n };\n case \"uph\":\n return {\n action: \"update_player\",\n args: { id: int(parts[0]), item: int(parts[1]), slot: \"head\" },\n };\n case \"upf\":\n return {\n action: \"update_player\",\n args: { id: int(parts[0]), item: int(parts[1]), slot: \"face\" },\n };\n case \"upn\":\n return {\n action: \"update_player\",\n args: { id: int(parts[0]), item: int(parts[1]), slot: \"neck\" },\n };\n case \"upb\":\n return {\n action: \"update_player\",\n args: { id: int(parts[0]), item: int(parts[1]), slot: \"body\" },\n };\n case \"upa\":\n return {\n action: \"update_player\",\n args: { id: int(parts[0]), item: int(parts[1]), slot: \"hand\" },\n };\n case \"upe\":\n return {\n action: \"update_player\",\n args: { id: int(parts[0]), item: int(parts[1]), slot: \"feet\" },\n };\n case \"upl\":\n return {\n action: \"update_player\",\n args: { id: int(parts[0]), item: int(parts[1]), slot: \"flag\" },\n };\n case \"upp\":\n return {\n action: \"update_player\",\n args: { id: int(parts[0]), item: int(parts[1]), slot: \"photo\" },\n };\n case \"upba\":\n return {\n action: \"update_player\",\n args: { id: int(parts[0]), item: int(parts[1]), slot: \"back\" },\n };\n case \"upm\":\n return {\n action: \"update_player\",\n args: { id: int(parts[0]), item: int(parts[1]), slot: \"mount\" },\n };\n\n case \"ai\": {\n // add_item response: itemId, coins remaining\n return {\n action: \"add_item\",\n args: { item: int(parts[0]), coins: int(parts[1]) },\n };\n }\n\n case \"jg\": {\n // join_game_room\n return { action: \"join_game_room\", args: { game: int(parts[0]) } };\n }\n\n case \"e\": {\n // error\n return { action: \"error\", args: { error: parts[0] ?? \"unknown\" } };\n }\n\n default:\n return null;\n }\n}\n\nexport class CpzeroAdapter extends BaseAdapter {\n readonly id = \"CPZero\";\n private sfs: SmartFoxSocket | null = null;\n\n async login(options: LoginOptions | TokenLoginOptions): Promise<LoginResult> {\n if (\"token\" in options) {\n throw new Error(\"CPZero does not support token login\");\n }\n\n const loginHash = options.secret;\n if (!loginHash) {\n throw new Error(\n \"CPZero requires a pre-computed login hash in options.secret\",\n );\n }\n\n const ws = new WebSocket(LOGIN_WS_URL);\n const result = await new Promise<LoginResult>((resolve, reject) => {\n const timeout = setTimeout(() => {\n ws.close();\n reject(new Error(\"Login timed out\"));\n }, 15_000);\n\n let _rndK = \"\";\n\n ws.on(\"open\", () => {\n ws.send(xmlMsg(\"verChk\", \"0\", `<ver v='${API_VERSION}' />`) + NUL);\n });\n\n ws.on(\"message\", (raw: Buffer) => {\n const messages = raw.toString(\"utf-8\").split(NUL).filter(Boolean);\n for (const msg of messages) {\n if (\n msg.includes('action=\"apiOK\"') ||\n msg.includes(\"action='apiOK'\")\n ) {\n ws.send(xmlMsg(\"rndK\", \"-1\", \"\") + NUL);\n continue;\n }\n\n const kMatch = msg.match(/<k>(.*?)<\\/k>/);\n if (kMatch) {\n _rndK = kMatch[1];\n const loginXml = xmlLogin(options.username, loginHash);\n ws.send(loginXml + NUL);\n continue;\n }\n\n if (msg.startsWith(\"%xt%l%\")) {\n const xtParts = msg.split(\"%\").filter(Boolean);\n // xt, l, -1, nickString, confirmationKey, ...\n const nickString = xtParts[3] ?? \"\";\n const confirmationKey = xtParts[4] ?? \"\";\n const nickFields = nickString.split(\"|\");\n\n clearTimeout(timeout);\n ws.close();\n\n const userId = int(nickFields[0]);\n const username = nickFields[2] ?? options.username;\n resolve({\n servers: [{ name: \"Sub Zero\", population: 0 }],\n key: `${userId}|${nickString}|${confirmationKey}`,\n username,\n moderator: false,\n buddyWorlds: [],\n });\n return;\n }\n\n if (msg.startsWith(\"%xt%e%\")) {\n clearTimeout(timeout);\n ws.close();\n const errParts = msg.split(\"%\").filter(Boolean);\n reject(\n new Error(`Login failed: error ${errParts[3] ?? \"unknown\"}`),\n );\n return;\n }\n }\n });\n\n ws.on(\"error\", (err) => {\n clearTimeout(timeout);\n ws.close();\n reject(new Error(`Login WS error: ${(err as Error).message}`));\n });\n\n ws.on(\"close\", () => {\n clearTimeout(timeout);\n });\n });\n\n return result;\n }\n\n async connect(\n _serverName: string,\n loginResult: LoginResult,\n _options?: ConnectOptions,\n ): Promise<import(\"socket.io-client\").Socket> {\n // loginResult.key = \"userId|nickString|confirmationKey\"\n const keyParts = loginResult.key.split(\"|\");\n const userId = keyParts[0] ?? \"\";\n const nickString = keyParts.slice(1, -1).join(\"|\");\n const confirmationKey = keyParts[keyParts.length - 1] ?? \"\";\n const loginKey = nickString.split(\"|\")[3] ?? \"\";\n\n const ws = new WebSocket(GAME_WS_URL);\n const sfs = new SmartFoxSocket(ws);\n this.sfs = sfs;\n // Store as unknown since SmartFoxSocket is not a Socket.IO Socket\n this.socket = sfs as unknown as import(\"socket.io-client\").Socket;\n\n await new Promise<void>((resolve, reject) => {\n const timeout = setTimeout(() => {\n ws.close();\n reject(new Error(\"Game connection timed out\"));\n }, 15_000);\n\n ws.on(\"open\", () => {\n sfs.send(xmlMsg(\"verChk\", \"0\", `<ver v='${API_VERSION}' />`));\n });\n\n ws.on(\"message\", (raw: Buffer) => {\n const messages = raw.toString(\"utf-8\").split(NUL).filter(Boolean);\n for (const msg of messages) {\n // XML phase\n if (\n msg.includes('action=\"apiOK\"') ||\n msg.includes(\"action='apiOK'\")\n ) {\n sfs.send(xmlMsg(\"rndK\", \"-1\", \"\"));\n continue;\n }\n\n const kMatch = msg.match(/<k>(.*?)<\\/k>/);\n if (kMatch) {\n const rndK = kMatch[1];\n const gamePword = `${swapMD5(loginKey + rndK)}${loginKey}#${confirmationKey}`;\n sfs.send(xmlGameLogin(nickString, gamePword));\n continue;\n }\n\n // xt phase — may contain multiple messages concatenated\n if (msg.startsWith(\"%xt%\")) {\n this.processXtBatch(msg, sfs);\n\n // Detect login success and send join_server\n if (msg.includes(\"%xt%l%\")) {\n sfs.send(`%xt%s%j#js%-1%${userId}%${loginKey}%en%`);\n }\n\n // Resolve once we get load_player + join_room\n if (msg.includes(\"%xt%jr%\")) {\n clearTimeout(timeout);\n resolve();\n }\n }\n\n if (msg.includes(\"%xt%e%\")) {\n clearTimeout(timeout);\n ws.close();\n const errParts = msg.split(\"%\").filter(Boolean);\n reject(\n new Error(`Game auth failed: error ${errParts[3] ?? \"unknown\"}`),\n );\n return;\n }\n }\n });\n\n ws.on(\"error\", (err) => {\n clearTimeout(timeout);\n reject(new Error(`Game WS error: ${(err as Error).message}`));\n });\n });\n\n // Wire up ongoing message handling\n ws.on(\"message\", (raw: Buffer) => {\n const messages = raw.toString(\"utf-8\").split(NUL).filter(Boolean);\n for (const msg of messages) {\n if (msg.startsWith(\"%xt%\")) {\n this.processXtBatch(msg, sfs);\n }\n }\n });\n\n // Replay buffered load_player/join_room messages after the Client attaches its listener\n sfs.flush();\n\n // Cast to Socket — Client only uses .on(\"message\") / .on(\"disconnect\") / .off()\n return sfs as unknown as import(\"socket.io-client\").Socket;\n }\n\n send(action: string, args: Record<string, unknown>): void {\n if (!this.sfs) throw new Error(\"Not connected\");\n const xt = actionToXt(action, args);\n if (xt) this.sfs.send(xt);\n }\n\n disconnect(): void {\n this.sfs?.disconnect();\n this.sfs = null;\n this.socket = null;\n }\n\n override normalizeUser(raw: Record<string, unknown>): RoomUser {\n return {\n ...this.extractAppearance(raw),\n id: raw.id as number,\n username: raw.username as string,\n x: (raw.x as number) ?? 0,\n y: (raw.y as number) ?? 0,\n frame: (raw.frame as number) ?? 0,\n meta: {\n back: raw.back,\n body2: raw.body2,\n hand2: raw.hand2,\n beak: raw.beak,\n hair: raw.hair,\n mount: raw.mount,\n rank: raw.rank,\n },\n _raw: raw,\n };\n }\n\n override normalizePlayer(raw: Record<string, unknown>): PlayerData {\n const user = raw.user as Record<string, unknown>;\n return {\n ...this.normalizeUser(user),\n _raw: raw,\n coins: (raw.coins as number) ?? 0,\n rank: (user.rank as number) ?? 0,\n inventory: [],\n buddies: [],\n ignores: [],\n };\n }\n\n override sendMessage(message: string): void {\n if (!this.sfs) throw new Error(\"Not connected\");\n const userId = 0; // Server ignores the sent userId for own messages\n this.sfs.send(`%xt%s%m#sm%-1%${userId}%${message}%`);\n }\n\n override sendEmote(emote: number): void {\n if (!this.sfs) throw new Error(\"Not connected\");\n this.sfs.send(`%xt%s%u#se%-1%${emote}%`);\n }\n\n override sendSafe(safe: number): void {\n if (!this.sfs) throw new Error(\"Not connected\");\n this.sfs.send(`%xt%s%u#sa%-1%${safe}%`);\n }\n\n override walk(x: number, y: number): void {\n if (!this.sfs) throw new Error(\"Not connected\");\n this.sfs.send(`%xt%s%u#sp%-1%${x}%${y}%`);\n }\n\n override sendFrame(frame: number): void {\n if (!this.sfs) throw new Error(\"Not connected\");\n this.sfs.send(`%xt%s%u#sf%-1%${frame}%`);\n }\n\n override snowball(x: number, y: number): void {\n if (!this.sfs) throw new Error(\"Not connected\");\n this.sfs.send(`%xt%s%u#sb%-1%${x}%${y}%`);\n }\n\n override joinRoom(room: number, x?: number, y?: number): void {\n if (!this.sfs) throw new Error(\"Not connected\");\n this.sfs.send(`%xt%s%j#jr%-1%${room}%${x ?? 0}%${y ?? 0}%`);\n }\n\n override addItem(item: number): void {\n if (!this.sfs) throw new Error(\"Not connected\");\n this.sfs.send(`%xt%s%i#ai%-1%${item}%`);\n }\n\n override equipColor(item: number): void {\n if (!this.sfs) throw new Error(\"Not connected\");\n this.sfs.send(`%xt%s%s#upc%-1%${item}%`);\n }\n\n override equipHead(item: number): void {\n if (!this.sfs) throw new Error(\"Not connected\");\n this.sfs.send(`%xt%s%s#uph%-1%${item}%`);\n }\n\n override equipFace(item: number): void {\n if (!this.sfs) throw new Error(\"Not connected\");\n this.sfs.send(`%xt%s%s#upf%-1%${item}%`);\n }\n\n override equipNeck(item: number): void {\n if (!this.sfs) throw new Error(\"Not connected\");\n this.sfs.send(`%xt%s%s#upn%-1%${item}%`);\n }\n\n override equipBody(item: number): void {\n if (!this.sfs) throw new Error(\"Not connected\");\n this.sfs.send(`%xt%s%s#upb%-1%${item}%`);\n }\n\n override equipHand(item: number): void {\n if (!this.sfs) throw new Error(\"Not connected\");\n this.sfs.send(`%xt%s%s#upa%-1%${item}%`);\n }\n\n override equipFeet(item: number): void {\n if (!this.sfs) throw new Error(\"Not connected\");\n this.sfs.send(`%xt%s%s#upe%-1%${item}%`);\n }\n\n override equipFlag(item: number): void {\n if (!this.sfs) throw new Error(\"Not connected\");\n this.sfs.send(`%xt%s%s#upl%-1%${item}%`);\n }\n\n override equipPhoto(item: number): void {\n if (!this.sfs) throw new Error(\"Not connected\");\n this.sfs.send(`%xt%s%s#upp%-1%${item}%`);\n }\n\n override getPlayer(id: number): void {\n if (!this.sfs) throw new Error(\"Not connected\");\n this.sfs.send(`%xt%s%u#gp%-1%${id}%`);\n }\n\n override joinIgloo(igloo: number, _x?: number, _y?: number): void {\n if (!this.sfs) throw new Error(\"Not connected\");\n this.sfs.send(`%xt%s%j#jp%-1%${igloo}%igloo%`);\n }\n\n /**\n * Process a batch of `%xt%` messages that may be concatenated in a single\n * WebSocket frame (separated by \\0 already split, but multiple %xt% in one string).\n */\n private processXtBatch(raw: string, sfs: SmartFoxSocket): void {\n // Split concatenated xt messages: \" %xt%cmd1%...% %xt%cmd2%...%\"\n const xtMessages = raw\n .split(/(?=%xt%)/)\n .map((s) => s.trim())\n .filter(Boolean);\n\n for (const xt of xtMessages) {\n const parts = xt.split(\"%\").filter(Boolean);\n // parts: [\"xt\", cmd, roomId, ...args]\n if (parts[0] !== \"xt\" || parts.length < 3) continue;\n\n const cmd = parts[1];\n const xtArgs = parts.slice(3); // skip \"xt\", cmd, roomId\n\n const translated = translateXt(cmd, xtArgs);\n if (translated) {\n sfs.dispatchMessage(translated.action, translated.args);\n }\n }\n }\n}\n\n// ── XML helpers ──\n\nfunction xmlMsg(action: string, r: string, body: string): string {\n return `<msg t='sys'><body action='${action}' r='${r}'>${body}</body></msg>`;\n}\n\nfunction xmlLogin(username: string, pword: string): string {\n return xmlMsg(\n \"login\",\n \"0\",\n `<login z='${LOGIN_ZONE}'><nick><![CDATA[${username}]]></nick><pword><![CDATA[${pword}]]></pword></login>`,\n );\n}\n\nfunction xmlGameLogin(nick: string, pword: string): string {\n return xmlMsg(\n \"login\",\n \"0\",\n `<login z='${LOGIN_ZONE}'><nick><![CDATA[${nick}]]></nick><pword><![CDATA[${pword}]]></pword></login>`,\n );\n}\n\n/**\n * Convert a normalized Client action to the raw `%xt%` send format.\n * Only used when called via the generic `send()` method.\n */\nfunction actionToXt(\n action: string,\n args: Record<string, unknown>,\n): string | null {\n switch (action) {\n case \"send_position\":\n return `%xt%s%u#sp%-1%${args.x}%${args.y}%`;\n case \"send_frame\":\n return `%xt%s%u#sf%-1%${args.frame}%`;\n case \"send_message\":\n return `%xt%s%m#sm%-1%0%${args.message}%`;\n case \"send_emote\":\n return `%xt%s%u#se%-1%${args.emote}%`;\n case \"send_safe\":\n return `%xt%s%u#sa%-1%${args.safe}%`;\n case \"snowball\":\n return `%xt%s%u#sb%-1%${args.x}%${args.y}%`;\n case \"join_room\":\n return `%xt%s%j#jr%-1%${args.room}%${args.x ?? 0}%${args.y ?? 0}%`;\n case \"add_item\":\n return `%xt%s%i#ai%-1%${args.item}%`;\n case \"get_player\":\n return `%xt%s%u#gp%-1%${args.id}%`;\n default:\n return null;\n }\n}\n","import { createCipheriv, createDecipheriv, randomBytes } from \"node:crypto\";\nimport { io, type Socket } from \"socket.io-client\";\nimport nacl from \"tweetnacl\";\nimport type {\n LoginOptions,\n LoginResult,\n QueueUpdate,\n ServerInfo,\n TokenLoginOptions,\n} from \"../types/adapter-types.js\";\nimport type { Buddy, PlayerData, RoomUser } from \"../types/player-types.js\";\nimport { BaseAdapter, type ConnectOptions } from \"./base-adapter.js\";\n\nconst CRUMBS_URL =\n \"https://media8.newcp.net/assets/media/crumbs/en/crumbs.json\";\n\ntype WorldConfig = {\n id?: number;\n host: string;\n path: string;\n login?: boolean;\n};\n\ntype CrumbsWorlds = Record<string, WorldConfig>;\n\ntype LoginResponse = {\n success: boolean;\n username: string;\n key: string;\n populations: Record<string, number>;\n moderator: boolean;\n buddyWorlds: string[];\n};\n\ntype GameAuthResponse = {\n success: boolean;\n token?: string;\n};\n\nclass Encryptor {\n private aesKey: Buffer | null = null;\n private keypair = nacl.box.keyPair();\n\n get publicKey(): string {\n return Buffer.from(this.keypair.publicKey).toString(\"base64\");\n }\n\n get encrypted(): boolean {\n return this.aesKey !== null;\n }\n\n acquireKey(encryptedB64: string, serverPubKeyB64: string): string | null {\n const data = Buffer.from(encryptedB64, \"base64\");\n const serverPubKey = Buffer.from(serverPubKeyB64, \"base64\");\n const nonce = data.subarray(0, nacl.box.nonceLength);\n const ciphertext = data.subarray(nacl.box.nonceLength);\n const plaintext = nacl.box.open(\n new Uint8Array(ciphertext),\n new Uint8Array(nonce),\n new Uint8Array(serverPubKey),\n this.keypair.secretKey,\n );\n return plaintext ? new TextDecoder().decode(plaintext) : null;\n }\n\n setKey(keyString: string): void {\n this.aesKey = Buffer.from(keyString, \"utf-8\");\n }\n\n encrypt(plaintext: string): string {\n if (!this.aesKey) throw new Error(\"Encryption key not set\");\n const iv = randomBytes(16);\n const cipher = createCipheriv(\"aes-256-cbc\", this.aesKey, iv);\n const encrypted = Buffer.concat([\n cipher.update(plaintext, \"utf-8\"),\n cipher.final(),\n ]);\n const result = Buffer.concat([iv, encrypted]);\n return result.toString(\"base64\");\n }\n\n decrypt(data: string): string {\n if (!this.aesKey) throw new Error(\"Encryption key not set\");\n const buf = Buffer.from(data, \"base64\");\n const iv = buf.subarray(0, 16);\n const ciphertext = buf.subarray(16);\n const decipher = createDecipheriv(\"aes-256-cbc\", this.aesKey, iv);\n return Buffer.concat([\n decipher.update(ciphertext),\n decipher.final(),\n ]).toString(\"utf-8\");\n }\n\n encode(data: Record<string, unknown>): string {\n return this.encrypted\n ? this.encrypt(JSON.stringify(data))\n : JSON.stringify(data);\n }\n\n decode(data: unknown): Record<string, unknown> {\n if (this.encrypted && typeof data === \"string\") {\n return JSON.parse(this.decrypt(data)) as Record<string, unknown>;\n }\n return typeof data === \"string\"\n ? (JSON.parse(data) as Record<string, unknown>)\n : (data as Record<string, unknown>);\n }\n}\n\nfunction performHandshake(socket: Socket, encryptor: Encryptor): Promise<void> {\n return new Promise((resolve, reject) => {\n const timeout = setTimeout(() => {\n reject(new Error(\"Handshake timed out\"));\n }, 10_000);\n\n socket.once(\n \"handshake\",\n (encryptedKey: string, serverPubKeyB64: string) => {\n clearTimeout(timeout);\n const raw = encryptor.acquireKey(encryptedKey, serverPubKeyB64);\n if (!raw) {\n reject(new Error(\"Failed to decrypt handshake key\"));\n return;\n }\n\n const parsed = JSON.parse(raw) as { key: string; time?: number };\n if (\n parsed.time &&\n typeof parsed.time === \"number\" &&\n Math.abs(Date.now() - parsed.time) > 300_000\n ) {\n reject(new Error(\"Server time desync\"));\n return;\n }\n\n encryptor.setKey(parsed.key);\n resolve();\n },\n );\n\n socket.emit(\"handshake\", encryptor.publicKey);\n });\n}\n\n/**\n * Wraps a NewCP socket to decrypt incoming messages into the\n * `{ action, args }` envelope that the Client class expects.\n */\nfunction wrapSocket(raw: Socket, encryptor: Encryptor): Socket {\n const original = raw.on.bind(raw);\n\n raw.on = ((event: string, listener: (...args: unknown[]) => void) => {\n if (event === \"message\") {\n return original(event, (msg: unknown) => {\n try {\n const decoded = encryptor.decode(msg);\n listener({ action: decoded.action, args: decoded.args ?? {} });\n } catch {\n // Skip malformed messages\n }\n });\n }\n return original(event, listener);\n }) as typeof raw.on;\n\n return raw;\n}\n\nexport class NewcpAdapter extends BaseAdapter {\n readonly id = \"NewCP\";\n private encryptor = new Encryptor();\n private worlds: CrumbsWorlds | null = null;\n\n async login(options: LoginOptions | TokenLoginOptions): Promise<LoginResult> {\n if (!this.worlds) {\n await this.loadWorlds();\n }\n\n const loginWorld = Object.values(this.worlds ?? {}).find((w) => w.login);\n if (!loginWorld) throw new Error(\"Login world not found in crumbs\");\n\n const loginSocket = this.createSocket(loginWorld.host, loginWorld.path);\n this.encryptor = new Encryptor();\n\n const result = await new Promise<LoginResult>((resolve, reject) => {\n const timeout = setTimeout(() => {\n loginSocket.disconnect();\n reject(new Error(\"Login timed out\"));\n }, 15_000);\n\n loginSocket.on(\"connect\", async () => {\n try {\n await performHandshake(loginSocket, this.encryptor);\n\n const args =\n \"token\" in options\n ? { username: options.username, token: options.token }\n : { username: options.username, password: options.password };\n\n const encrypted = this.encryptor.encode({ action: \"login\", args });\n loginSocket.emit(\"message\", encrypted);\n } catch (err) {\n clearTimeout(timeout);\n loginSocket.disconnect();\n reject(err);\n }\n });\n\n loginSocket.on(\"message\", (msg: unknown) => {\n try {\n const decoded = this.encryptor.decode(msg);\n if (decoded.action !== \"login\") return;\n\n clearTimeout(timeout);\n loginSocket.disconnect();\n\n const response = decoded.args as unknown as LoginResponse;\n\n if (!response.success) {\n reject(new Error(\"Login failed\"));\n return;\n }\n\n const servers: ServerInfo[] = Object.entries(\n response.populations ?? {},\n ).map(([name, population]) => ({ name, population }));\n\n resolve({\n servers,\n key: response.key,\n username: response.username,\n moderator: response.moderator ?? false,\n buddyWorlds: response.buddyWorlds ?? [],\n });\n } catch (err) {\n clearTimeout(timeout);\n loginSocket.disconnect();\n reject(err);\n }\n });\n\n loginSocket.on(\"connect_error\", (err: Error) => {\n clearTimeout(timeout);\n loginSocket.disconnect();\n reject(new Error(`Login connection failed: ${err.message}`));\n });\n });\n\n return result;\n }\n\n async connect(\n serverName: string,\n loginResult: LoginResult,\n options?: ConnectOptions,\n ): Promise<Socket> {\n if (!this.worlds) {\n await this.loadWorlds();\n }\n\n const worldConfig = this.worlds?.[serverName];\n if (!worldConfig)\n throw new Error(`World config not found for: ${serverName}`);\n\n this.encryptor = new Encryptor();\n const gameSocket = this.createSocket(worldConfig.host, worldConfig.path);\n this.socket = gameSocket;\n\n await new Promise<void>((resolve, reject) => {\n const timeout = setTimeout(() => {\n gameSocket.disconnect();\n reject(new Error(\"Game connection timed out\"));\n }, 15_000);\n\n gameSocket.on(\"connect\", async () => {\n try {\n await performHandshake(gameSocket, this.encryptor);\n\n const encrypted = this.encryptor.encode({\n action: \"game_auth\",\n args: {\n username: loginResult.username,\n key: loginResult.key,\n createToken: false,\n },\n });\n gameSocket.emit(\"message\", encrypted);\n } catch (err) {\n clearTimeout(timeout);\n gameSocket.disconnect();\n reject(err);\n }\n });\n\n gameSocket.on(\"message\", (msg: unknown) => {\n try {\n const decoded = this.encryptor.decode(msg);\n\n switch (decoded.action) {\n case \"wait_queue_update\": {\n options?.onQueueUpdate?.(decoded.args as unknown as QueueUpdate);\n break;\n }\n case \"game_auth\": {\n const response = decoded.args as unknown as GameAuthResponse;\n if (!response.success) {\n clearTimeout(timeout);\n gameSocket.disconnect();\n reject(new Error(\"Game auth failed\"));\n return;\n }\n\n const joinEncrypted = this.encryptor.encode({\n action: \"join_server\",\n args: {},\n });\n gameSocket.emit(\"message\", joinEncrypted);\n clearTimeout(timeout);\n resolve();\n break;\n }\n }\n } catch {\n // Ignore decode errors during auth phase\n }\n });\n\n gameSocket.on(\"connect_error\", (err: Error) => {\n clearTimeout(timeout);\n gameSocket.disconnect();\n reject(new Error(`Game connection failed: ${err.message}`));\n });\n });\n\n return wrapSocket(gameSocket, this.encryptor);\n }\n\n send(action: string, args: Record<string, unknown>): void {\n if (!this.socket) throw new Error(\"Not connected\");\n const encrypted = this.encryptor.encode({ action, args });\n this.socket.emit(\"message\", encrypted);\n }\n\n disconnect(): void {\n this.socket?.disconnect();\n this.socket = null;\n }\n\n override normalizeUser(raw: Record<string, unknown>): RoomUser {\n return {\n ...this.extractAppearance(raw),\n id: raw.id as number,\n username: raw.username as string,\n displayName: raw.nickname as string | undefined,\n x: (raw.x as number) ?? 0,\n y: (raw.y as number) ?? 0,\n frame: (raw.frame as number) ?? 0,\n meta: {\n nickname: raw.nickname,\n registrationDate: raw.registrationDate,\n customNameColor: raw.customNameColor,\n customBubbleColor: raw.customBubbleColor,\n customBubbleTextColor: raw.customBubbleTextColor,\n wallHacks: raw.wallHacks,\n moderator: raw.moderator,\n character: raw.character,\n approved: raw.approved,\n walking: raw.walking,\n },\n _raw: raw,\n };\n }\n\n override normalizePlayer(raw: Record<string, unknown>): PlayerData {\n const user = raw.user as Record<string, unknown>;\n return {\n ...this.normalizeUser(user),\n _raw: raw,\n coins: (raw.coins as number) ?? 0,\n rank: (raw.rank as number) ?? 0,\n inventory: (raw.inventory as number[]) ?? [],\n buddies: (raw.buddies as Buddy[]) ?? [],\n ignores: (raw.ignores as number[]) ?? [],\n furniture: raw.furniture as Record<string, unknown> | undefined,\n flooring: (raw.floorings as unknown[]) ?? [],\n igloos: (raw.igloos as unknown[]) ?? [],\n };\n }\n\n override sendMessage(message: string): void {\n this.send(\"send_message\", { message });\n }\n\n override sendEmote(emote: number): void {\n this.send(\"send_emote\", { emote });\n }\n\n override sendSafe(safe: number): void {\n this.send(\"send_safe\", { safe });\n }\n\n override walk(x: number, y: number): void {\n this.send(\"send_position\", { x, y });\n }\n\n override sendFrame(frame: number, set?: boolean): void {\n this.send(\"send_frame\", { frame, set });\n }\n\n override snowball(x: number, y: number): void {\n this.send(\"snowball\", { x, y });\n }\n\n override joinRoom(room: number, x?: number, y?: number): void {\n this.send(\"join_room\", { room, x: x ?? 0, y: y ?? 0 });\n }\n\n override addItem(item: number): void {\n this.send(\"add_item\", { item });\n }\n\n override equipColor(item: number): void {\n this.send(\"update_color\", { item });\n }\n\n override equipHead(item: number): void {\n this.send(\"update_head\", { item });\n }\n\n override equipFace(item: number): void {\n this.send(\"update_face\", { item });\n }\n\n override equipNeck(item: number): void {\n this.send(\"update_neck\", { item });\n }\n\n override equipBody(item: number): void {\n this.send(\"update_body\", { item });\n }\n\n override equipHand(item: number): void {\n this.send(\"update_hand\", { item });\n }\n\n override equipFeet(item: number): void {\n this.send(\"update_feet\", { item });\n }\n\n override equipFlag(item: number): void {\n this.send(\"update_flag\", { item });\n }\n\n override equipPhoto(item: number): void {\n this.send(\"update_photo\", { item });\n }\n\n override buddyRequest(id: number): void {\n this.send(\"buddy_request\", { id });\n }\n\n override buddyAccept(id: number): void {\n this.send(\"buddy_accept\", { id });\n }\n\n override buddyReject(id: number): void {\n this.send(\"buddy_reject\", { id });\n }\n\n override removeBuddy(id: number): void {\n this.send(\"remove_buddy\", { id });\n }\n\n override addIgnore(id: number): void {\n this.send(\"ignore_add\", { id });\n }\n\n override removeIgnore(id: number): void {\n this.send(\"ignore_remove\", { id });\n }\n\n override getPlayer(id: number): void {\n this.send(\"get_player\", { id });\n }\n\n override joinIgloo(igloo: number, x?: number, y?: number): void {\n this.send(\"join_igloo\", { igloo, x: x ?? 0, y: y ?? 0 });\n }\n\n private createSocket(host: string, path: string): Socket {\n return io(host, {\n path,\n transports: [\"polling\", \"websocket\"],\n reconnection: false,\n });\n }\n\n private async loadWorlds(): Promise<void> {\n const resp = await fetch(CRUMBS_URL);\n if (!resp.ok) throw new Error(`Failed to fetch crumbs: ${resp.status}`);\n const crumbs = (await resp.json()) as { worlds: CrumbsWorlds };\n this.worlds = crumbs.worlds;\n }\n}\n","import { io, type Socket } from \"socket.io-client\";\nimport type {\n LoginOptions,\n LoginResult,\n QueueUpdate,\n TokenLoginOptions,\n} from \"../types/adapter-types.js\";\nimport type { PlayerData, RoomUser } from \"../types/player-types.js\";\nimport { BaseAdapter, type ConnectOptions } from \"./base-adapter.js\";\n\nconst BASE_URL = \"https://play.penguinorigins.online\";\n\ntype LoginResponse = {\n success: boolean;\n username: string;\n key: string;\n populations: Record<string, number>;\n};\n\ntype GameAuthResponse = {\n success: boolean;\n token?: string;\n};\n\ntype ServerMessage = {\n action: string;\n args: Record<string, unknown>;\n};\n\nexport class PenguinoriginsAdapter extends BaseAdapter {\n readonly id = \"PenguinOrigins\";\n\n async login(options: LoginOptions | TokenLoginOptions): Promise<LoginResult> {\n const loginSocket = this.createSocket(\"/world/login/\");\n\n const result = await new Promise<LoginResult>((resolve, reject) => {\n const timeout = setTimeout(() => {\n loginSocket.disconnect();\n reject(new Error(\"Login timed out\"));\n }, 10_000);\n\n loginSocket.on(\"connect\", () => {\n const action = \"token\" in options ? \"token_login\" : \"login\";\n const args =\n \"token\" in options\n ? { username: options.username, token: options.token }\n : { username: options.username, password: options.password };\n\n loginSocket.emit(\"message\", { action, args });\n });\n\n loginSocket.on(\"message\", (msg: ServerMessage) => {\n if (msg.action !== \"login\") return;\n\n clearTimeout(timeout);\n loginSocket.disconnect();\n\n const response = msg.args as LoginResponse;\n\n if (!response.success) {\n reject(new Error(\"Login failed\"));\n return;\n }\n\n const servers = Object.entries(response.populations).map(\n ([name, population]) => ({ name, population }),\n );\n\n resolve({\n servers,\n key: response.key,\n username: response.username,\n moderator: false,\n buddyWorlds: [],\n });\n });\n\n loginSocket.on(\"connect_error\", (err: Error) => {\n clearTimeout(timeout);\n loginSocket.disconnect();\n reject(new Error(`Login connection failed: ${err.message}`));\n });\n });\n\n return result;\n }\n\n async connect(\n serverName: string,\n loginResult: LoginResult,\n options?: ConnectOptions,\n ): Promise<Socket> {\n const gameSocket = this.createSocket(`/world/${serverName.toLowerCase()}/`);\n this.socket = gameSocket;\n\n await new Promise<void>((resolve, reject) => {\n let authSent = false;\n\n gameSocket.on(\"connect\", () => {\n gameSocket.emit(\"message\", {\n action: \"game_auth\",\n args: {\n username: loginResult.username,\n key: loginResult.key,\n createToken: true,\n token: \"\",\n },\n });\n });\n\n gameSocket.on(\"message\", (msg: ServerMessage) => {\n switch (msg.action) {\n case \"wait_queue_update\": {\n options?.onQueueUpdate?.(msg.args as QueueUpdate);\n break;\n }\n case \"game_auth\": {\n if (authSent) break;\n authSent = true;\n\n const response = msg.args as GameAuthResponse;\n if (!response.success) {\n gameSocket.disconnect();\n reject(new Error(\"Game auth failed\"));\n return;\n }\n\n gameSocket.emit(\"message\", {\n action: \"join_server\",\n args: {},\n });\n resolve();\n break;\n }\n }\n });\n\n gameSocket.on(\"connect_error\", (err: Error) => {\n gameSocket.disconnect();\n reject(new Error(`Game connection failed: ${err.message}`));\n });\n });\n\n return gameSocket;\n }\n\n send(action: string, args: Record<string, unknown>): void {\n if (!this.socket) throw new Error(\"Not connected\");\n this.socket.emit(\"message\", { action, args });\n }\n\n disconnect(): void {\n this.socket?.disconnect();\n this.socket = null;\n }\n\n override normalizeUser(raw: Record<string, unknown>): RoomUser {\n return {\n ...this.extractAppearance(raw),\n id: raw.id as number,\n username: raw.username as string,\n displayName: (raw.nickname as string) ?? (raw.username as string),\n joinTime: raw.joinTime as string | undefined,\n x: (raw.x as number) ?? 0,\n y: (raw.y as number) ?? 0,\n frame: (raw.frame as number) ?? 0,\n meta: {\n toy: raw.toy,\n },\n _raw: raw,\n };\n }\n\n override normalizePlayer(raw: Record<string, unknown>): PlayerData {\n const user = raw.user as Record<string, unknown>;\n const normalized = this.normalizeUser(user);\n return {\n ...normalized,\n _raw: raw,\n coins: (raw.coins as number) ?? 0,\n rank: (raw.rank as number) ?? 0,\n inventory: (raw.inventory as number[]) ?? [],\n furniture: (raw.furniture as unknown[]) ?? [],\n flooring: (raw.flooring as unknown[]) ?? [],\n buddies: (raw.buddies as PlayerData[\"buddies\"]) ?? [],\n buddyRequests: (raw.buddyRequests as number[]) ?? [],\n ignores: (raw.ignores as number[]) ?? [],\n igloos: (raw.igloos as unknown[]) ?? [],\n meta: {\n ...normalized.meta,\n postcards: raw.postcards,\n mascots: raw.mascots,\n pets: raw.pets,\n },\n };\n }\n\n override sendMessage(message: string): void {\n this.send(\"send_message\", { message });\n }\n\n override sendEmote(emote: number): void {\n this.send(\"send_emote\", { emote });\n }\n\n override sendSafe(safe: number): void {\n this.send(\"send_safe\", { safe });\n }\n\n override walk(x: number, y: number): void {\n this.send(\"send_position\", { x, y });\n }\n\n override sendFrame(frame: number, set?: boolean): void {\n this.send(\"send_frame\", { frame, set: set ?? false });\n }\n\n override snowball(x: number, y: number): void {\n this.send(\"snowball\", { x, y });\n }\n\n override joinRoom(room: number, x?: number, y?: number): void {\n this.send(\"join_room\", { room, x: x ?? 0, y: y ?? 0 });\n }\n\n override addItem(item: number): void {\n this.send(\"add_item\", { item });\n }\n\n override equipColor(item: number): void {\n this.send(\"update_player\", { item });\n }\n\n override equipHead(item: number): void {\n this.send(\"update_player\", { item });\n }\n\n override equipFace(item: number): void {\n this.send(\"update_player\", { item });\n }\n\n override equipNeck(item: number): void {\n this.send(\"update_player\", { item });\n }\n\n override equipBody(item: number): void {\n this.send(\"update_player\", { item });\n }\n\n override equipHand(item: number): void {\n this.send(\"update_player\", { item });\n }\n\n override equipFeet(item: number): void {\n this.send(\"update_player\", { item });\n }\n\n override equipFlag(item: number): void {\n this.send(\"update_player\", { item });\n }\n\n override equipPhoto(item: number): void {\n this.send(\"update_player\", { item });\n }\n\n override buddyRequest(id: number): void {\n this.send(\"buddy_request\", { id });\n }\n\n override buddyAccept(id: number): void {\n this.send(\"buddy_accept\", { id });\n }\n\n override addIgnore(id: number): void {\n this.send(\"ignore_add\", { id });\n }\n\n override removeIgnore(id: number): void {\n this.send(\"ignore_remove\", { id });\n }\n\n override getIglooOpen(igloo: number): void {\n this.send(\"get_igloo_open\", { igloo });\n }\n\n override joinIgloo(igloo: number, x?: number, y?: number): void {\n this.send(\"join_igloo\", { igloo, x: x ?? 0, y: y ?? 0 });\n }\n\n override gameOver(coins: number): void {\n this.send(\"game_over\", { coins });\n }\n\n private createSocket(path: string): Socket {\n return io(BASE_URL, {\n path,\n transports: [\"polling\", \"websocket\"],\n reconnection: false,\n });\n }\n}\n","import type { BaseAdapter } from \"./base-adapter.js\";\nimport { CpjourneyAdapter } from \"./cpjourney-adapter.js\";\nimport { CplegacyAdapter } from \"./cplegacy-adapter.js\";\nimport { CpzeroAdapter } from \"./cpzero-adapter.js\";\nimport { NewcpAdapter } from \"./newcp-adapter.js\";\nimport { PenguinoriginsAdapter } from \"./penguinorigins-adapter.js\";\n\nconst ADAPTERS = {\n CPJourney: CpjourneyAdapter,\n CPLegacy: CplegacyAdapter,\n CPZero: CpzeroAdapter,\n NewCP: NewcpAdapter,\n PenguinOrigins: PenguinoriginsAdapter,\n} as const;\n\nexport type AdapterName = keyof typeof ADAPTERS;\n\nexport function createAdapter(name: AdapterName): BaseAdapter {\n return new ADAPTERS[name]();\n}\n","import type { BaseAdapter } from \"../adapters/base-adapter.js\";\nimport type { ServerMessages } from \"../types/message-types.js\";\n\ntype WaitForFn = <K extends keyof ServerMessages>(\n event: K,\n timeout?: number,\n) => Promise<ServerMessages[K]>;\n\nexport class CardJitsu {\n constructor(\n private adapter: BaseAdapter,\n private waitFor: WaitForFn,\n ) {}\n\n /** Fetch ninja rank, progress, and card deck. Resolves with ninja data. */\n getNinja(): Promise<ServerMessages[\"get_ninja\"]> {\n this.adapter.getNinja();\n return this.waitFor(\"get_ninja\");\n }\n\n /** Fetch state of all Dojo mats. Resolves with mat state. */\n getMats(): Promise<ServerMessages[\"get_waddles\"]> {\n this.adapter.getMats();\n return this.waitFor(\"get_waddles\");\n }\n\n /** Sit on a Dojo mat to wait for an opponent. Listen for `update_waddle` events. */\n joinMat(waddle: number): void {\n this.adapter.joinMat(waddle);\n }\n\n /** Join Sensei matchmaking queue. Resolves when server acknowledges. */\n joinMatchmaking(): Promise<ServerMessages[\"join_matchmaking\"]> {\n this.adapter.joinMatchmaking();\n return this.waitFor(\"join_matchmaking\");\n }\n\n /** Leave Sensei matchmaking queue. */\n leaveMatchmaking(): void {\n this.adapter.leaveMatchmaking();\n }\n\n /** Start a Card-Jitsu match after entering a game room. Resolves with player info. */\n startGame(): Promise<ServerMessages[\"start_game\"]> {\n this.adapter.startGame();\n return this.waitFor(\"start_game\");\n }\n\n /** Play a card from your hand by slot index. Resolves when server acknowledges. */\n selectCard(slot: number): Promise<ServerMessages[\"move_my_card\"]> {\n this.adapter.selectCard(slot);\n return this.waitFor(\"move_my_card\");\n }\n\n /** Preload a power card animation asset. */\n loadAnimation(animation: string): void {\n this.adapter.loadAnimation(animation);\n }\n}\n"],"mappings":"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","names":["BaseAdapter","_raw","raw","_message","_emote","_safe","_x","_y","_frame","_set","_room","_item","_id","_type","_userId","_cardId","_igloo","_name","_puffleSprite","_coins","_stamp","_slot","_animation","_waddle","EventEmitter","io","msgpackParser","BASE_URL","DEFAULT_SECRET","CpjourneyAdapter","BaseAdapter","options","loginSocket","resolve","reject","timeout","secret","args","msg","response","servers","name","population","err","serverName","loginResult","gameSocket","authSent","queueSocket","action","raw","id","username","displayName","joinTime","x","y","frame","walking","color","head","face","neck","body","hand","feet","flag","photo","rest","user","normalized","_user","coins","rank","inventory","furniture","flooring","buddies","buddyRequests","ignores","igloos","message","emote","safe","set","room","item","type","userId","cardId","igloo","puffleSprite","stamp","slot","animation","waddle","path","io","msgpackParser","io","msgpackParser","LOGIN_URL","TOKEN_LOGIN_URL","wrapSocket","raw","original","event","listener","action","args","CplegacyAdapter","BaseAdapter","options","url","body","data","name","population","serverName","loginResult","wsUrl","rawSocket","io","msgpackParser","resolve","reject","timeout","err","user","b","message","emote","safe","x","y","frame","set","room","item","id","userId","igloo","coins","stamp","createHash","EventEmitter","WebSocket","LOGIN_WS_URL","GAME_WS_URL","API_VERSION","LOGIN_ZONE","NUL","U","md5","input","createHash","swapMD5","hash","int","v","n","parseUserString","str","f","SmartFoxSocket","EventEmitter","ws","err","action","args","buffered","msg","data","WebSocket","translateXt","cmd","parts","user","coins","rank","room","users","CpzeroAdapter","BaseAdapter","options","loginHash","resolve","reject","timeout","_rndK","xmlMsg","raw","messages","kMatch","loginXml","xmlLogin","xtParts","nickString","confirmationKey","nickFields","userId","username","errParts","_serverName","loginResult","_options","keyParts","loginKey","sfs","rndK","gamePword","xmlGameLogin","xt","actionToXt","message","emote","safe","x","y","frame","item","id","igloo","_x","_y","xtMessages","xtArgs","translated","r","body","pword","nick","createCipheriv","createDecipheriv","randomBytes","io","nacl","CRUMBS_URL","Encryptor","nacl","encryptedB64","serverPubKeyB64","data","serverPubKey","nonce","ciphertext","plaintext","keyString","iv","randomBytes","cipher","createCipheriv","encrypted","buf","decipher","createDecipheriv","performHandshake","socket","encryptor","resolve","reject","timeout","encryptedKey","raw","parsed","wrapSocket","original","event","listener","msg","decoded","NewcpAdapter","BaseAdapter","options","loginWorld","w","loginSocket","args","err","response","servers","name","population","serverName","loginResult","worldConfig","gameSocket","joinEncrypted","action","user","message","emote","safe","x","y","frame","set","room","item","id","igloo","host","path","io","resp","crumbs","io","BASE_URL","PenguinoriginsAdapter","BaseAdapter","options","loginSocket","resolve","reject","timeout","action","args","msg","response","servers","name","population","err","serverName","loginResult","gameSocket","authSent","raw","user","normalized","message","emote","safe","x","y","frame","set","room","item","id","igloo","coins","path","io","ADAPTERS","CpjourneyAdapter","CplegacyAdapter","CpzeroAdapter","NewcpAdapter","PenguinoriginsAdapter","createAdapter","name","CardJitsu","adapter","waitFor","waddle","slot","animation","KNOWN_ACTIONS","isMessagePayload","msg","Client","EventEmitter","CardJitsu","server","options","createAdapter","serverName","connectOptions","update","socket","resolve","reject","timeout","playerLoaded","roomJoined","checkReady","onMessage","onDisconnect","event","listener","args","timer","cleanup","handler","message","emote","safe","x","y","frame","set","room","item","id","type","userId","cardId","igloo","name","puffleSprite","coins","stamp","ms","action","emitArgs","player","rawUsers","users","rawUser","user","iglooUsers","slot","reason","error","eventName"]}
|