tui-arcade 2.4.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/README.md +39 -0
- package/arcade.js +21 -0
- package/package.json +28 -0
package/README.md
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
# tui-arcade
|
|
2
|
+
|
|
3
|
+
Minesweeper, Book of Ra-style slots, Texas Hold'em and Blackjack in your terminal.
|
|
4
|
+
Play solo, or host a table and let friends join over the network.
|
|
5
|
+
|
|
6
|
+
```
|
|
7
|
+
npx tui-arcade@latest
|
|
8
|
+
```
|
|
9
|
+
|
|
10
|
+
Needs Node.js 18 or newer. Works on Windows, macOS and Linux.
|
|
11
|
+
|
|
12
|
+
## Games
|
|
13
|
+
|
|
14
|
+
| Command | |
|
|
15
|
+
| --- | --- |
|
|
16
|
+
| `npx tui-arcade@latest` | launcher with every game |
|
|
17
|
+
| `npx tui-arcade@latest minesweeper` | no-guess boards, hints, rewind, best times |
|
|
18
|
+
| `npx tui-arcade@latest slots` | Book of Ra-style 5×3 slots with free games and gamble |
|
|
19
|
+
| `npx tui-arcade@latest holdem` | no-limit Hold'em against bots that learn how you play |
|
|
20
|
+
| `npx tui-arcade@latest blackjack` | blackjack against the house |
|
|
21
|
+
|
|
22
|
+
Or install it once: `npm install -g tui-arcade`, then just run `tui-arcade`.
|
|
23
|
+
|
|
24
|
+
## Play with friends
|
|
25
|
+
|
|
26
|
+
Hold'em and Blackjack can be hosted by one player and joined by others:
|
|
27
|
+
|
|
28
|
+
```
|
|
29
|
+
npx tui-arcade@latest holdem host # you host (port 6769)
|
|
30
|
+
npx tui-arcade@latest holdem join <host address> --name Sam
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
The host screen shows the address to share. Everyone needs the same version
|
|
34
|
+
(`@latest` takes care of that). Same network: use the host's LAN address.
|
|
35
|
+
Over the internet: a free VPN like Tailscale is the easiest way. The host may need to
|
|
36
|
+
allow Node.js through the firewall.
|
|
37
|
+
|
|
38
|
+
Mouse and keyboard both work; every screen lists its keys. Your chips and records are
|
|
39
|
+
saved in your home folder (`.tui-arcade.sav`).
|
package/arcade.js
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
"use strict";var pe=(e,t)=>()=>{try{return t||e((t={exports:{}}).exports,t),t.exports}catch(s){throw t=0,s}};var tt=pe((Pl,Po)=>{"use strict";var Jt="\x1B[0m",Io="\x1B[1m",hi="\x1B[2m",Ae=(e,t,s)=>`\x1B[38;2;${e};${t};${s}m`,we=(e,t,s)=>`\x1B[48;2;${e};${t};${s}m`,pt={hid:[we(78,90,116),we(70,82,107)],rev:[we(30,32,40),we(35,37,46)],cursor:we(240,196,64),hintSafe:we(46,170,96),pressed:we(44,48,60),startCursor:we(140,235,150),btn:we(52,58,74),btnHot:we(240,196,64),hintBad:we(190,60,170),boom:we(210,40,40),flag:Ae(255,92,92),mine:Ae(235,235,235),dark:Ae(20,20,20),title:Ae(240,196,64),muted:Ae(140,146,160),text:Ae(220,224,232),good:Ae(110,220,130),bad:Ae(255,110,110),accent:Ae(110,180,255),border:Ae(90,98,120)},Oo=e=>e>=65281&&e<=65376||e>=127744||e===11088||e===10060?2:1,Ht=e=>{let t=0;for(let s of e.replace(/\x1b\[[0-9;]*m/g,""))t+=Oo(s.codePointAt(0));return t},Js=[],Ut=class{constructor(t=""){this.text=t,this.regions=[]}add(t,s,n){let o=Ht(this.text);return this.text+=t,(s||n)&&this.regions.push({start:o,end:Ht(this.text),onClick:s,onWheel:n}),this}whole(t,s){return this.regions.push({start:0,end:Ht(this.text),onClick:t,onWheel:s}),this}};function di(e,t,s,{enabled:n=!0,hot:o=!1}={}){let a=n?o?pt.btnHot+pt.dark+Io:pt.btn+pt.text:pt.btn+pt.muted;e.add(`${a} ${t} ${Jt}`,n?s:null),e.add(" ")}function fi(e){let t=process.stdout.columns||100,s=e.map(r=>r instanceof Ut?r.text:r),n=Math.max(...s.map(Ht)),o=Math.max(1,Math.floor((t-n)/2));Js=[],e.forEach((r,c)=>{if(r instanceof Ut)for(let u of r.regions)Js.push({...u,row:c+1,start:o+u.start,end:o+u.end})});let a=" ".repeat(o);return process.stdout.write("\x1B[H"+s.map(r=>a+r+Jt+"\x1B[K").join(`\r
|
|
3
|
+
`)+Jt+"\x1B[J"),o}function Bo(e){return Js.find(t=>t.row===e.y&&e.x-1>=t.start&&e.x-1<t.end)}function Lo(e){if(!e.press||e.b&32)return!1;let t=Bo(e);if(!t)return!1;let s=e.b&64?e.b&1?1:-1:0;if(s){if(!t.onWheel)return!1;t.onWheel(s)}else if(t.onClick)t.onClick(e.b&3);else return!1;return!0}var Eo={A:"up",B:"down",C:"right",D:"left",H:"home",F:"end"};function No(e){let t=[],s=0;for(;s<e.length;){let n=e[s];if(n==="\x1B"){let a=e.slice(s),r=/^\x1b\[<(\d+);(\d+);(\d+)([Mm])/.exec(a);if(r){t.push({type:"mouse",b:+r[1],x:+r[2],y:+r[3],press:r[4]==="M"}),s+=r[0].length;continue}if(r=/^\x1b\[([0-9;]*)([A-Za-z~])/.exec(a),r){let c=Eo[r[2]]||"csi";r[2]==="~"&&(c=r[1]==="5"?"pageup":r[1]==="6"?"pagedown":"csi"),t.push({type:"key",name:c}),s+=r[0].length;continue}if(r=/^\x1bO([A-Z])/.exec(a),r){t.push({type:"key",name:Eo[r[1]]||"ss3"}),s+=3;continue}t.push({type:"key",name:"escape"}),s++;continue}let o;n==="\r"||n===`
|
|
4
|
+
`?o="enter":n===" "?o="space":n===""?o="ctrl-c":o=n.toLowerCase(),t.push({type:"key",name:o,ch:n}),s++}return t}var be=null,Qt=null;function xs(){be&&be.render()}function Ys(e){be=e,process.stdout.write("\x1B[2J"),e.onShow&&e.onShow(),xs()}var xi=()=>!!Qt;function pi(){Qt&&be!==Qt?Ys(Qt):Xs()}function mi(e){for(let t of No(e.toString("utf8"))){if(t.type==="key"&&t.name==="ctrl-c")return Xs();if(t.type==="mouse"?be.onMouse?be.onMouse(t):Lo(t):be.onKey&&be.onKey(t.name,t),Us)return;xs()}}var _o=Jt+"\x1B[?1000l\x1B[?1002l\x1B[?1006l\x1B[?25h\x1B[?1049l",Us=!1;function Xs(){if(!Us){Us=!0,be&&be.onQuit&&be.onQuit(),process.stdout.write(_o);try{process.stdin.setRawMode(!1)}catch{}process.exit(0)}}function bi(e,t=null){(!process.stdin.isTTY||!process.stdout.isTTY)&&(console.error("Please run this in an interactive terminal."),process.exit(1)),Qt=t,process.on("uncaughtException",s=>{process.stdout.write(_o),console.error(s),process.exit(1)}),process.stdout.write("\x1B[?1049h\x1B[?25l\x1B[?1000h\x1B[?1002h\x1B[?1006h\x1B[2J"),process.stdin.setRawMode(!0),process.stdin.resume(),process.stdin.on("data",mi),process.stdout.on("resize",()=>{process.stdout.write("\x1B[2J"),xs()}),setInterval(()=>{be&&be.onTick&&be.onTick()},100),Ys(e)}Po.exports={CSI:"\x1B[",RESET:Jt,BOLD:Io,DIM:hi,fg:Ae,bg:we,C:pt,charWidth:Oo,visLen:Ht,Line:Ut,button:di,draw:fi,hitAt:Bo,clickHitbox:Lo,parseInput:No,render:xs,show:Ys,leave:pi,quit:Xs,run:bi,hasLauncher:xi}});var Et=pe((ql,Uo)=>{"use strict";function ue(e,t){e=e-367;let s=ms(),n=s[e];if(ue.wHYBsq===void 0){var o=function(u){let h="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/=",l="",f="";for(let d=0,x,m,g=0;m=u.charAt(g++);~m&&(x=d%4?x*64+m:m,d++%4)?l+=String.fromCharCode(255&x>>(-2*d&6)):0)m=h.indexOf(m);for(let d=0,x=l.length;d<x;d++)f+="%"+("00"+l.charCodeAt(d).toString(16)).slice(-2);return decodeURIComponent(f)};let c=function(u,h){let l=[],f=0,d,x="";u=o(u);let m;for(m=0;m<256;m++)l[m]=m;for(m=0;m<256;m++)f=(f+l[m]+h.charCodeAt(m%h.length))%256,d=l[m],l[m]=l[f],l[f]=d;m=0,f=0;for(let g=0;g<u.length;g++)m=(m+1)%256,f=(f+l[m])%256,d=l[m],l[m]=l[f],l[f]=d,x+=String.fromCharCode(u.charCodeAt(g)^l[(l[m]+l[f])%256]);return x};ue.llWPMz=c,ue.AGDQUj={},ue.wHYBsq=!0}let a=s[-7897+269*15+3862];ue.tLFDVG!==a&&(ue.AGDQUj={},ue.tLFDVG=a);let r=ue.AGDQUj[e];return r===void 0?(ue.YQgdnZ===void 0&&(ue.YQgdnZ=!0),n=ue.llWPMz(n,t),ue.AGDQUj[e]=n):n=r,n}(function(e,t){function s(r,c){return ue(r-537,c)}function n(r,c){return ue(c- -659,r)}let o=e();function a(r,c){return ue(r-294,c)}for(;;)try{if(-parseInt(a(903,"Yq@k"))/1*(-parseInt(a(806,"JX4M"))/2)+-parseInt(n("9IjO",-132))/3+parseInt(a(739,"W1]y"))/4+-parseInt(n("W1]y",-100))/5+-parseInt(a(964,"5X#b"))/6*(-parseInt(a(920,"m!RN"))/7)+parseInt(a(876,"rQVX"))/8*(-parseInt(a(883,"]A]w"))/9)+parseInt(s(973,"RIy6"))/10===t)break;o.push(o.shift())}catch{o.push(o.shift())}})(ms,-1244699+5*330277);var Yt=require("fs"),$i=require("os"),qo=require(N("B3@H",949)),ps=require(ae("R6lU",-188)+"to"),Ct=process.env.ARCADE_SAVE||process.env.MINESWEEPER_SAVE||qo[J(-53,"h0De")]($i[N("9IjO",934)+ae("RSkb",-329)](),ae("Nh()",-88)+J(-256,"V8If")+ae("B3@H",-231)+J(-303,"rQVX")),Do=Buffer[ae("D&[j",-61)](ae("XZF@",-170));function ae(e,t){return ue(t- -723,e)}var jo=1,gi=[[[12200+10*-1204,-3*3231+2*-1343+-5*-2517,3953*-1+801+-673*-5,240,187,-469*-13+4307+-33*308,4*-658+308*14+1*-1545,-9245*1+341+1*9008],[-3793+2*2020,127,-7122+-5*-1447,-2*1682+-6293+-3*-3260,883*5+-619+-3568,3363+297*22+9649*-1,1*-6761+2759+4056,1545+811*1+-2221*1]],[[143,2936+-1*2935,1809*4+-7232+170,79,166,1*-4166+1*8541+-4341,4111+-3106*-1+-7198,604+-1*8578+8106],[1*5090+-4634+-212,-7648+-2*-2049+3701,216,-1148*5+1087*-5+-7*-1606,83,3901+-3763*1,6763+1*-6566,4440+-7*622]],[[94,-15847+-60*-268,3*2271+-117+826*-8,201,4940+-942*-5+9648*-1,-2*3463+1*8031+-1073,54,5995*1+-280+-5518],[1*-2993+1545*-4+9277,397*23+-6*-1181+-16177,-3698*1+-7772+11687*1,208,-3*1996+-5173+11353,6511+1*3037+-7*1330,5962*1+-6555+-1*-711,2833*-2+-4*-256+-1*-4722]],[[-9682+802*6+5119,7764+-366*-6+-1*9789,-471*-11+-8060+3072,-11994+-12061*-1,7308+-3584*-2+-14268,-909+-1*-915,8781+2539*1+3*-3721,-395+-1*-677+-189],[-1*-3865+-6766+3056,267*-22+-765+-6658*-1,194,-1*-2005+-389*-4+3*-1141,-2*-3347+-377+-14*440,157,204,-7*-743+320*10+-8384]]],yi=Buffer[N("V8If",1056)]([9508*1+396*9+-13056,-2*-362+4867+-5*1093,15455+-1709*9,-949*-1+-1*-3143+3862*-1,2274+-383*-25+-2*5867,-2287*2+9314+4706*-1,199,10*-357+6889*1+-3126,183,6285+-1031*-7+-13274,-2242+-3897*-2+-5469,197,-3479*2+-3*606+9026,186,9162+4481*-2,9971+1*-9846]),Vs=null;function Ko(){function e(o,a){return ae(a,o- -90)}function t(o,a){return ae(a,o-1402)}function s(o,a){return ae(a,o-1241)}let n={YbrJY:function(o){return o()},jfhID:function(o,a){return o===a},cMPJw:t(1200,"xnO7")+"x",LKLrX:t(1132,"qzQa")+"x"};if(!Vs){if(n[s(1174,"xuR^")+"D"](n[t(1352,"Nh()")+"w"],n[s(967,"xnO7")+"X"]))return(_0x2b8582[e(-270,"!MRJ")+"et"]||n[s(1162,"&hyC")+"Y"](_0x4e3ebd))[s(1019,"h0De")+e(-246,"XZF@")];{let o=Buffer[e(-235,"B3@H")](gi[s(919,"JX4M")+s(1038,"qvFZ")](([a,r])=>a[s(908,"m!RN")]((c,u)=>c^r[u])));Vs=ps[s(1069,"4Kyu")+e(-241,"]A]w")+"nc"](o,yi,1*4525+5301+-9794)}}return Vs}function Fo(e){function t(h,l){return ae(h,l-1555)}function s(h,l){return ae(l,h-280)}let n={lurYM:t("ty^D",1294)+t("Kp1r",1491)+a(-405,"qUQA"),cSdVE:function(h){return h()},GIAXz:t("Pi2A",1270)},o=ps[s(41,"Fo#r")+t("*Xsh",1428)+t("kSh^",1503)](3574+-2*1781);function a(h,l){return ae(l,h- -53)}let r=Buffer[t("Fo#r",1376)+"at"]([Do,Buffer[a(-220,"6Cn6")]([jo])]),c=ps[s(98,"]A]w")+a(-325,"RIy6")+t("rL%O",1326)+"iv"](n[s(72,"RIy6")+"M"],n[s(128,"kSh^")+"E"](Ko),o);c[a(-372,"m!RN")+"AD"](r);let u=Buffer[s(35,"4LWv")+"at"]([c[t("]A]w",1242)+"te"](JSON[t("Nh()",1327)+t("qzQa",1266)+"y"](e),n[t("P]@l",1247)+"z"]),c[t("Kp1r",1470)+"l"]()]);return Buffer[s(137,"XZF@")+"at"]([r,o,c[t("2k3k",1439)+a(-352,"#H#4")+"ag"](),u])}function Go(e){let t={utHCs:function(u,h){return u<h},zUeIu:function(u,h){return u!==h},lAsqH:a("P]@l",-386)+s(-28,"YVf6")+a("ty^D",-285)+a("Kp1r",-155),iBFMX:n(1099,"FwQA")+s(22,"&hyC")+n(1339,"93Bh"),KkTPU:function(u){return u()},dLCXe:n(1335,"qUQA"),TjEXY:a("D&[j",-336)+"ct",GhkDA:a("*Xsh",-188)+n(1129,"XZF@")};function s(u,h){return N(h,u- -991)}function n(u,h){return N(h,u-227)}if(t[s(8,"4LWv")+"s"](e[s(-98,"FjTs")+"th"],-3*467+-6350+7784)||!e[n(1128,"FOE6")+a("KeYk",-258)](2092*2+9309+-13493,-854+-1*-9098+-8240)[a("XZF@",-224)+"ls"](Do)||t[n(1237,"XZF@")+"u"](e[-1*-2587+508*-4+-551*1],jo))throw new Error(t[s(119,"P]@l")+"H"]);let o=ps[s(73,"L3sW")+a("qBNS",-207)+n(1246,"6Cn6")+s(-32,"LLT1")](t[s(-34,"L3sW")+"X"],t[s(64,"$A1D")+"U"](Ko),e[a("Yq@k",-410)+s(7,"RIy6")](5,5494+2798*1+-8275));function a(u,h){return N(u,h- -1272)}o[a("5X#b",-231)+"AD"](e[s(-12,"B3@H")+a("L3sW",-299)](0,5)),o[a("XZF@",-120)+s(-20,"xnO7")+"ag"](e[n(1252,"9IjO")+n(1298,"P]@l")](1106+-3*363,3810+1*5774+-9551));let r=Buffer[n(1187,"HTzk")+"at"]([o[s(82,"*7uI")+"te"](e[s(-80,"Kp1r")+n(1079,"YVf6")](11*-281+1037+2087)),o[s(99,"W1]y")+"l"]()])[n(1193,"LLT1")+n(1155,"V8If")](t[n(1106,"Kp1r")+"e"]),c=JSON[a("*7uI",-286)+"e"](r);if(!c||t[a("FjTs",-423)+"u"](typeof c,t[n(1305,"Nh()")+"Y"]))throw new Error(t[n(1346,"*Xsh")+"A"]);return c}var Zs=null;function Ho(e){function t(a,r){return J(r-933,a)}function s(a,r){return J(a-151,r)}function n(a,r){return J(r-1033,a)}let o={gYxSx:function(a,r){return a(r)},wDNBX:function(a,r){return a===r},SKANz:n("RSkb",750)+"J",hgKGg:s(60,"&hyC")+"L",zxius:s(85,"qUQA")+"A",SPwHb:function(a){return a()},XHwaI:function(a,r){return a>=r},WWCdF:t("Kp1r",864)+"Y",euHXj:t("FwQA",860)+"M",uHIeo:t("&hyC",648)+"ES"};for(let a=-8719+-8719*-1;;a++){if(o[n("&hyC",963)+"X"](o[s(86,"Nh()")+"z"],o[t("W1]y",695)+"g"]))return o[s(-66,"!MRJ")+"x"](_0x51149e,_0x19a1d6);try{if(o[s(-99,"*7uI")+"X"](o[s(71,"FwQA")+"s"],o[s(-67,"2k3k")+"s"]))return o[s(-164,"*7uI")+"b"](e);{let r=_0x147ecf+(t("Fo#r",878)+"-")+new _0x398843()[n("9IjO",873)+t("qBNS",620)+n("4LWv",760)]()[n("Kp1r",934)+s(-153,"xnO7")](/[:.]/g,"-");try{_0x1a455f[n("!MRJ",844)+s(-136,"Fo#r")+"nc"](_0x1d74de,r)}catch{}return _0x55e315=n("*7uI",753)+t("B3@H",829)+t("V8If",827)+t("qzQa",643)+n("L3sW",976)+n("qvFZ",727)+t("!MRJ",879)+s(4,"ty^D")+n("R6lU",936)+t("HTzk",889)+t("h0De",604)+n("L3sW",850)+t("XZF@",862)+s(-41,"rL%O")+s(-151,"HTzk")+s(31,"qzQa")+n("xuR^",738)+s(50,"FOE6")+n("JX4M",910)+t("4Kyu",761)+n("9IjO",931)+t("L3sW",665)+t("xuR^",588)+t("qBNS",865)+n("Yq@k",937)+_0x15eed1[s(-88,"rL%O")+s(-196,"XZF@")](r)+".",{}}}catch(r){if(o[t("$A1D",616)+"I"](a,4759+-3*1011+-1706)||![o[n("kSh^",691)+"F"],o[n("RSkb",940)+"j"],o[n("qvFZ",809)+"o"]][n("Fo#r",773)+t("*Xsh",655)](r[n("R6lU",708)]))throw r;Atomics[n("Pi2A",870)](new Int32Array(new SharedArrayBuffer(8707*-1+1*-6012+-1*-14723)),-851*-4+2244+-5648,-12732+2*6366,1766+1*-1741)}}}function Xt(){let e={bbAqp:function(a,r){return a(r)}};function t(a,r){return ae(r,a-109)}let s;function n(a,r){return ae(r,a- -108)}function o(a,r){return ae(a,r-1072)}try{s=e[o("R6lU",860)+"p"](Ho,()=>Yt[t(-6,"Yq@k")+t(-62,"5X#b")+t(-109,"Nh()")](Ct))}catch{return{}}try{return e[n(-443,"*Xsh")+"p"](Go,s)}catch{let a=Ct+(t(-194,"LLT1")+"-")+new Date()[n(-211,"]A]w")+o("B3@H",853)+o("*Xsh",1002)]()[o("Fo#r",822)+t(-191,"&hyC")](/[:.]/g,"-");try{Yt[n(-446,"FjTs")+t(-139,"*7uI")+"nc"](Ct,a)}catch{}return Zs=o("4LWv",716)+n(-442,"m!RN")+o("Pi2A",823)+o("#H#4",948)+n(-317,"FwQA")+o("Kp1r",952)+n(-333,"HTzk")+o("4LWv",862)+o("5X#b",751)+t(8,"qzQa")+n(-237,"5X#b")+t(-146,"m!RN")+t(-114,"Yq@k")+n(-376,"HTzk")+o("!MRJ",873)+n(-267,"FOE6")+t(-76,"4Kyu")+n(-273,"93Bh")+t(-164,"!MRJ")+n(-359,"2k3k")+o("qBNS",896)+o("YVf6",729)+o("R6lU",768)+n(-302,"FjTs")+t(-218,"qvFZ")+qo[n(-452,"#H#4")+t(-48,"KeYk")](a)+".",{}}}function en(e){function t(r,c){return J(r-1651,c)}let s={ggGlF:function(r,c){return r(c)},zhbFM:function(r){return r()},yRXaY:function(r){return r()},kLExM:function(r,c){return r(c)},jovig:function(r,c){return r===c},phjpT:t(1416,"rL%O")+"X",CzmVS:o(1199,"&hyC")+"V",eGlrm:function(r,c){return r(c)},CBKAu:function(r,c){return r!==c},xHnwG:t(1363,"FjTs")+"n",XxdUR:a(-46,"rL%O")+"E"},n=Ct+"."+process[t(1532,"FOE6")]+t(1448,"xuR^");function o(r,c){return J(r-1277,c)}function a(r,c){return J(r-5,c)}try{s[a(-248,"m!RN")+"g"](s[a(-190,"qvFZ")+"T"],s[t(1480,"gIn3")+"S"])?(_0x428fee[o(954,"ty^D")+t(1572,"ty^D")+t(1546,"L3sW")+"c"](_0x26cf13,s[t(1441,"FwQA")+"F"](_0x58dc77,_0x317ff6)),s[a(-258,"*Xsh")+"F"](_0x293875,()=>_0x572a25[a(-184,"!MRJ")+a(-69,"LLT1")+"nc"](_0x1c8fbb,_0x1b26a3))):(Yt[a(-254,"qzQa")+a(-226,"6Cn6")+o(966,"JX4M")+"c"](n,s[o(938,"5X#b")+"m"](Fo,e)),s[t(1608,"qvFZ")+"m"](Ho,()=>Yt[a(-183,"D&[j")+o(1215,"]A]w")+"nc"](n,Ct)))}catch{if(s[o(957,"2k3k")+"u"](s[a(-304,"RIy6")+"G"],s[t(1496,"Nh()")+"G"]))_0x4a092d[o(1107,"L3sW")+t(1544,"xnO7")+"nc"](_0x21b5ee);else try{if(s[a(-55,"P]@l")+"u"](s[a(-81,"gIn3")+"R"],s[t(1301,"93Bh")+"R"])){let r=s[a(-287,"xuR^")+"M"](_0x4254e0),c=r[o(1231,"FjTs")+"et"]||_0x57aea3[a(-199,"L3sW")+"et"]||s[o(1045,"h0De")+"Y"](_0x3fb100);c[a(-252,"XZF@")+"s"]+=_0x56e71f,r[t(1543,"RIy6")+"et"]=_0x3a9011[t(1485,"RSkb")+"et"]=c,s[t(1579,"!MRJ")+"M"](_0x1f1e02,r)}else Yt[t(1599,"B3@H")+a(-347,"ty^D")+"nc"](n)}catch{}}}function J(e,t){return ue(e- -720,t)}var ke=Xt();for(let e of[J(-165,"$A1D")+N("Yq@k",989),J(-333,"P]@l"),J(-84,"#H#4")+"s",J(-249,"HTzk")+"s",ae("B3@H",-140)+"em",ae("4LWv",-121)+J(-223,"qUQA")+"k"])ke[e]=ke[e]||{};function wi(...e){let t={AGguF:function(a){return a()},sXkdp:function(a,r){return a(r)}},s=t[n(1109,"V8If")+"F"](Xt);function n(a,r){return J(a-1421,r)}function o(a,r){return J(r-1267,a)}for(let a of e)s[a]=ke[a];t[n(1160,"6Cn6")+"p"](en,s)}var nn=1e3,Qo=18197+-18097*1,tn=()=>({chips:nn,refills:0});function zs(){function e(o,a){return N(o,a- -92)}function t(o,a){return N(o,a- -998)}let s={RJxSs:function(o){return o()}};function n(o,a){return N(o,a- -87)}return ke[e("93Bh",829)+"et"]=s[n("L3sW",988)+"s"](Xt)[n("!MRJ",936)+"et"]||ke[t("qBNS",143)+"et"]||s[t("P]@l",-92)+"s"](tn),ke[t("kSh^",-91)+"et"]}var Jo={get chips(){function e(o,a){return N(o,a- -1108)}let t={qHmSO:function(o){return o()}};function s(o,a){return N(o,a-309)}function n(o,a){return N(a,o- -887)}return(ke[n(183,"6Cn6")+"et"]||t[n(129,"4LWv")+"O"](zs))[n(32,"FOE6")+"s"]},get refills(){function e(o,a){return J(a-53,o)}function t(o,a){return J(o-675,a)}let s={yuabw:function(o){return o()}};function n(o,a){return J(a-881,o)}return(ke[t(541,"#H#4")+"et"]||s[t(463,"JX4M")+"w"](zs))[t(580,"FOE6")+t(529,"!MRJ")]},sync:zs,adjust(e){let t={WrAbd:function(c){return c()},yKBRA:function(c){return c()},KgYtc:function(c,u){return c(u)}};function s(c,u){return N(u,c- -1074)}let n=t[s(-17,"$A1D")+"d"](Xt),o=n[s(37,"qUQA")+"et"]||ke[a(1444,"RIy6")+"et"]||t[a(1507,"rQVX")+"A"](tn);function a(c,u){return N(u,c-352)}o[r(1126,"gIn3")+"s"]+=e;function r(c,u){return N(u,c-84)}n[r(1118,"RSkb")+"et"]=ke[r(1030,"Nh()")+"et"]=o,t[r(1228,"Yq@k")+"c"](en,n)},canRefill(){let e={};function t(a,r){return N(r,a- -970)}function s(a,r){return N(r,a- -12)}function n(a,r){return N(a,r-4)}return e[t(-114,"*7uI")+"O"]=function(a,r){return a<r},e[s(1037,"ty^D")+"O"](Jo[t(-116,"!MRJ")+"s"],Qo)},refill(){function e(r,c){return N(c,r-191)}let t={ACWmk:function(r){return r()},qQLXd:function(r,c){return r(c)}};function s(r,c){return N(r,c- -1184)}let n=t[a("RIy6",-18)+"k"](Xt),o=n[a("4LWv",169)+"et"]||ke[s("R6lU",-275)+"et"]||t[a("]A]w",46)+"k"](tn);o[s("P]@l",-306)+"s"]=nn,o[s("YVf6",-141)+e(1258,"HTzk")]++;function a(r,c){return N(r,c- -956)}n[s("*7uI",-61)+"et"]=ke[a("RSkb",78)+"et"]=o,t[s("qzQa",-123)+"d"](en,n)}};function ki(){let e=Zs;return Zs=null,e}function N(e,t){return ue(t-480,e)}var sn={};sn[ae("Pi2A",-236)+"de"]=Fo,sn[N("L3sW",1158)+"de"]=Go;var He={};He[ae("qUQA",-90)+J(-343,"xuR^")+"E"]=Ct,He[J(-174,"RSkb")]=ke,He[J(-132,"h0De")+N("R6lU",923)]=wi,He[N("&hyC",1022)+"et"]=Jo,He[N("m!RN",956)+N("ty^D",1059)+"ce"]=ki,He[N("R6lU",924)+N("5X#b",1072)+J(-103,"#H#4")]=nn,He[N("m!RN",1091)+N("Fo#r",892)+J(-114,"Yq@k")]=Qo,He[J(-255,"FOE6")+"ec"]=sn,Uo[N("FOE6",863)+ae("h0De",-118)]=He;function ms(){let e=["v8oRf24","ySk+WRZdJq","W7KdWOWP","WRCICSoO","WRLKkmkH","W6apWRXU","W7OvtSkq","EZKeyW","WOrPW7na","W67dPmk2WQe","WORdU1BdLq","W6a0u8kR","WQKSB8oK","WQvqhMW","WRtcI8ofBq","i2NdMbm","AZOfDa","WP90W5vN","WRSvpSof","qSkPWPXl","W67dOmkOWQK","WO9HW7zU","mNtdOHe","WORcTvBdLq","WRtcKwhcKW","oCkXiWq","W5z9WQOynCk6WQVcRCoRW5GdWOK","WOjPW5iR","W7ekWQ0O","WR5GovG","WO19W4nW","W70wWPiS","W40Rmxy","W7hcNSkDW7W","AtflpW","W6mBWQPN","eYWtjG","WR/cPL/cMW","WPSXW7vz","aSo5DGy","W589WRX0","W50BWO4M","W70WCSkH","W7BcLSkTWR0","WPZcJSkVWQ0","cs1ula","W5Gzc8oL","xZeCwq","W5ldJ8o4W7VdLSoMwef8p1xcOG","WRlcGmocEG","WPGkBmoR","W5W+fHi","WRTZne0","iqpcTwq","W4i5bti","WQlcKmoJtq","W7ucca","WPrOW446","CIRcJSkX","WRKxzmo/j8oZW7e","amkaFse","W4GleMm","W5hdG8o+W7JdMSoIs0fvcK3cGa","imo/veVcGxPAW4NcTc5/wG","WPjGWOfW","WPtcMdG+","WPlcIwJdGa","f8ofydq","W5hdGmkrrG","aSo8F8kv","W4/cHHD9","xIeKwa","WQBcRmogxq","WQG7Dae","WPdcQh/dQq","p8kEoGa","W4xdMxKSxmojxCkSWOlcO8k/W6tdHG","ubVcVmk9","r8kOjCou","eSobyJK","W7/dRSkOWQ4","yCk9dHS","W7TZW5Lu","cmofW6Ka","WPVdRZddOW","odTZFW","WRL8neG","WO3cRc3dTG","WPpcSaRcPq","WRZcIutdIa","W79ZW4nD","W7WwxCoe","oSkfjqu","WPJcULZdJG","W5HmqWC","W6jlqmkYo8kaqSooWQFcUL7cOa4","zSkNjsK","WQBcVblcGq","gcL3wq","uCoSWOLd","xmkVWQFdGa","W7yQWO4Y","W5pcLrTH","WOtcSh4","WO3cRxJdQa","W7xcLSo7WRW","pG7cJ20BW7iS","WOmQAt4","qX3cISkL","W6xcL8oKWQ8","cComFq","W4qyFCoG","hmo4cMa","W5GbAmos","W7yCWQDR","W47cNmo5WRi","WOVcS2pdQG","WRC2W4FdGG","suzZg8o8Fu3dPq","W7GbWQrI","WQ9Gpua","gmkaW4Sm","tmkSW7tcLW","zdKy","WR3cPKVcGq","afRdRmoRmH9wD8oPW6pcGefi","k8kwjGq","WO3dM8k1bG","WOhcHIxcIa","W7GHzmkZ","WRJcUahcPq","WP5yihi","tmkeWPVcNa","W4VdM8kAWQC","W5OiWQuD","tSkHW7ZcLq","WQCvW7/dSW","tCk0WRC","WRxcImokBq","WOilW4RdPW","qCkiWR3dHq","WR/cT0O","jq98ca","WOySW6HT","eIzsoW","utPKjLFcSCoD","WRuBg8oJ","WO8iqSoi","W4CQccC","WPL2W6Kg","h8kQbMi","WQLbiu8","WRaDWQLW","CSkDW4S","DSoOcHm","t8k4WQddGq","rWBcKmkp","WPvoW4JdRG","WRrhW6/dUW","wdD9rW","atat","t8k4WRxdGa","W6H9pmk5imoRW6BdHCkcW6iKmvG","W61NW6DP","W6/cGmkAWQC","ECkcc8oT","WPpdQmkNdG","W63cLCkqW7m","W41kxq","W4NcTCkQW5O","iZL6Fa","WQawWPuS","smk5W7NcJW","WO5hW50","WOfcW5BdOW","zmkbWRlcOq","W4ugjCo8","W6xcTCoKWRC","yCkymCoB","W7OWBmk+","ACkRo8oY","WQdcHCohyG","k37dOHW","W7OUcCoB","dSoSsY0","WPVcSY3dSa","r8knb8o6","WQjPW63dKq","cCkvW7Tj","sSkhWR4","W7lcHSk7W5e","W50PWQel","zrhcSf0","W6bbqmk1p8kjqCopWQlcML7cVWu","xGZcISkL","W5uEWO7cRW","WRZdQ8kFpG","g8keW6mf","W4xdL8kqsG","W6TMEem","kYrQkW","WRldO8kNWQK","bmoelN0","WQFcRfdcNa","W6uaWQrV","WRfyW6TJ","W6pcVsVcJ8orv1K","WPqCFG","WPVcUxNdIa","W60VWRap","WOBcIsbY","atTPca","ENupDG","W50Kfge","WQH3o04","WO7cI8oEFa","W67cMmoEWQi","WOVcVsLx","W7jrvdO","W73cL8kr","uCo7WO5t","WOBcVwddRa","bSoizYu","BGtdUh8","W7G0DSk1","udhcKvG","WRCUtGW","wCkSW6VcNG","t8oSW49D","WRdcNGRcSG","eZzrpG","wmkLWQpdHG","W5FdJmo2W77dLCoKuhn0h07cTa","WOpcJsj/","WQfxW702vuhcMxNcLuJdTfSJ","WP3dJmkNcW","qCklWPJcLa","W70+zCo3","WRaSDa","WQdcOL7cLW","W54Bp8kK","fSk5W5CsW4NcQWdcIdldRueXWRu","W6X7W50","xJW5tq","W5Kqwa","W7FcGCoKWQ8","WPZdGCk9dW","WOnNW7VdMG","WQilW5DT","WOpcL8kVWRS","WRdcVuBcRW","W5C7xSor","WQ4OCmoa","W54bD8kA","WPhdHSkGxW","i8k2W7SB","o8onaNG","WOdcQmk3WQe","rHNcVCk9","W4GdcJW","W5ddJCkzWO8","WP3cJsj5","W51dcNy","WRJdOmkvjW","WPz+W58","cXfD","BxuyyW","xcb9qW","AhNdKae","tSkOWRhdIa","WPVcVxVdRa","uCkQla","tSk5W7dcRW","yrddUhi","WQ3dO8kSla","WPCyyqq","Dr/cULi","sJiXra","WRmlW6/dTa","WPrEW5RdOW","WQpcPtzs","W7hdPmkvWRq","WQGaW6ldVa","DCkicSo7","WOr6uxKyWOGIsCkvcCowg8k4","W6PGW615","WPRcR1pcGG","xSk1WRRdMq","W5q+DCkG","W51ixam","vSknWRZcLG","vcaP","BGCCEG","W6DkrCk1nmkej8oRWQpcN37cOG","W6BdKSoZt2TXA2y","WR7cISom","cmoJc2O","WRTwW7yn","s8kawJ0","W4qUjYi","WQb3Efy","WQKLW6JdNW","ESkNar8","zYbmzq","W4ZdH8kvqG","rmkoWP7cIq","W7eimYy","l8kViqW","W7xdR8kLWQe","WRevW6ldRG","W6hcLSo+W7y","WOVcTgtdUq"];return ms=function(){return e},ms()}});var ha=pe((Dl,ua)=>{"use strict";var Me=tt(),{RESET:B,BOLD:j,fg:st,C:$,visLen:Wi,Line:Vt,button:nt,draw:gs,hitAt:Si}=Me,{SAVE_FILE:Mi,save:le,persist:ys}=Et(),Te=[{key:"beginner",name:"Beginner",w:9,h:9,m:10},{key:"intermediate",name:"Intermediate",w:16,h:16,m:40},{key:"expert",name:"Expert",w:30,h:16,m:99},{key:"evil",name:"Evil",w:30,h:20,m:130},{key:"custom",name:"Custom",w:20,h:12,m:40}],vi=12e3,Ai=7,bt=[{key:"centered",name:"Centered",desc:"fullwidth digits + emoji, exactly centred",nums:["","\uFF11","\uFF12","\uFF13","\uFF14","\uFF15","\uFF16","\uFF17","\uFF18"],flag:"\u{1F6A9}",mine:"\u{1F4A3}",wrong:"\u274C",start:"\u2B50",safe:"\uFF1F",bad:"\uFF01"},{key:"classic",name:"Classic",desc:"plain ASCII, if your font renders the others badly",nums:["","1","2","3","4","5","6","7","8"],flag:"\u2691",mine:"\u2731",wrong:"\u2717",start:"\u25CF",safe:"?",bad:"!"}],on=new Map;function ot(e,t){let s=e+"x"+t;if(on.has(s))return on.get(s);let n=new Array(e*t);for(let o=0;o<t;o++)for(let a=0;a<e;a++){let r=[];for(let c=-1;c<=1;c++)for(let u=-1;u<=1;u++){if(!u&&!c)continue;let h=a+u,l=o+c;h>=0&&l>=0&&h<e&&l<t&&r.push(l*e+h)}n[o*e+a]=r}return on.set(s,n),n}function Ti(e,t,s,n){let o=e*t,a=new Uint8Array(o),r=n.slice();for(let h=0;h<s;h++){let l=h+Math.floor(Math.random()*(r.length-h)),f=r[h];r[h]=r[l],r[l]=f,a[r[h]]=1}let c=ot(e,t),u=new Uint8Array(o);for(let h=0;h<o;h++){let l=0;for(let f of c[h])l+=a[f];u[h]=l}return{mine:a,num:u}}function Ri(e,t,s,n){let o=e*t,a=ot(e,t),r=new Uint8Array(o),c=0;for(let u=0;u<o;u++){if(s[u]||n[u]!==0||r[u])continue;c++;let h=[u];for(;h.length;){let l=h.pop();if(!r[l]&&(r[l]=1,n[l]===0))for(let f of a[l])r[f]||h.push(f)}}for(let u=0;u<o;u++)!s[u]&&!r[u]&&c++;return c}function Xo(e,t,s,n,o,a,r=25e4){let c=e*t,u=ot(e,t),h=new Uint8Array(c),l=new Uint8Array(c),f=[],d=[],x=R=>{h[R]||(h[R]=1,f.push(R))},m=R=>{l[R]||(l[R]=1,d.push(R))},g=[];for(let R=0;R<c;R++){if(!n[R]||a[R]===0)continue;let K=0,_=[];for(let P of u[R])n[P]||(o[P]?K++:_.push(P));if(!_.length)continue;let ce=a[R]-K;ce===0?_.forEach(x):ce===_.length&&_.forEach(m),g.push({need:ce,cells:_})}if(f.length||d.length)return{safe:f,mines:d};let k=0;for(let R=0;R<c;R++)!n[R]&&o[R]&&k++;let S=s-k,A=new Int32Array(c).fill(-1),C=[],W=[];g.forEach((R,K)=>{for(let _ of R.cells)A[_]<0&&(A[_]=C.length,C.push(_),W.push([])),W[A[_]].push(K)});let v=[];for(let R=0;R<c;R++)!n[R]&&!o[R]&&A[R]<0&&v.push(R);let T=v.length,G=new Int32Array(C.length).fill(-1),H=[];for(let R=0;R<C.length;R++){if(G[R]>=0)continue;let K=H.length,_=[R];G[R]=K;let ce=new Set;for(let P=0;P<_.length;P++)for(let oe of W[_[P]])if(!ce.has(oe)){ce.add(oe);for(let ge of g[oe].cells){let Ke=A[ge];G[Ke]<0&&(G[Ke]=K,_.push(Ke))}}H.push({cells:_,cons:[...ce]})}let ee=new Int32Array(g.length),ne=new Int32Array(g.length);for(let R of H){let K=R.cells.length;for(let ye of R.cons)ee[ye]=0,ne[ye]=g[ye].cells.length;let _=new Uint8Array(K),ce=R.cells.map(ye=>W[ye]),P=new Map,oe=0,ge=!1,Ke=(ye,Fe)=>{if(ge)return;if(++oe>r){ge=!0;return}if(ye===K){let me=P.get(Fe);me||(me={mine:new Uint8Array(K),safe:new Uint8Array(K)},P.set(Fe,me));for(let xt=0;xt<K;xt++)(_[xt]?me.mine:me.safe)[xt]=1;return}let Qs=ce[ye];for(let me=0;me<=1&&!(me&&Fe+1>S);me++){let xt=!0;for(let Ge of Qs){let Ro=ee[Ge]+me,ui=ne[Ge]-1,Co=g[Ge].need;if(Ro>Co||Ro+ui<Co){xt=!1;break}}if(xt){for(let Ge of Qs)ee[Ge]+=me,ne[Ge]--;_[ye]=me,Ke(ye+1,Fe+me);for(let Ge of Qs)ee[Ge]-=me,ne[Ge]++}}};Ke(0,0),R.aborted=ge,R.byK=P,R.ks=ge?Array.from({length:K+1},(ye,Fe)=>Fe):[...P.keys()]}let te=Math.max(0,S),ie=R=>S-R>=0&&S-R<=T,Gt=R=>{let K=new Uint8Array(te+1);return K[0]=1,H.forEach((_,ce)=>{if(ce===R)return;let P=new Uint8Array(te+1);for(let oe=0;oe<=te;oe++)if(K[oe])for(let ge of _.ks)oe+ge<=te&&(P[oe+ge]=1);K=P}),K};if(H.forEach((R,K)=>{if(R.aborted)return;let _=Gt(K),ce=R.ks.filter(P=>{for(let oe=0;oe+P<=te;oe++)if(_[oe]&&ie(P+oe))return!0;return!1});if(ce.length)for(let P=0;P<R.cells.length;P++){let oe=!1,ge=!1;for(let ye of ce){let Fe=R.byK.get(ye);Fe.mine[P]&&(oe=!0),Fe.safe[P]&&(ge=!0)}let Ke=C[R.cells[P]];!oe&&ge?x(Ke):oe&&!ge&&m(Ke)}}),T>0){let R=Gt(-1),K=!1,_=!0,ce=!0;for(let P=0;P<=te;P++)!R[P]||!ie(P)||(K=!0,S-P!==0&&(_=!1),S-P!==T&&(ce=!1));K&&_?v.forEach(x):K&&ce&&v.forEach(m)}return{safe:f,mines:d}}function an(e,t,s,n,o,a,r=!1){let c=e*t,u=ot(e,t),h=new Uint8Array(c),l=new Uint8Array(c),f=0,d=c-s,x=m=>{let g=[m];for(;g.length;){let k=g.pop();if(!h[k]&&(h[k]=1,f++,o[k]===0))for(let S of u[k])h[S]||g.push(S)}};for(x(a);f<d;){let m=Xo(e,t,s,h,l,o);if(!m.safe.length&&!m.mines.length)return!1;for(let g of m.safe){if(r&&n[g])throw new Error("solver unsound: deduced a mine as safe");x(g)}for(let g of m.mines){if(r&&!n[g])throw new Error("solver unsound: deduced a safe cell as mine");l[g]=1}}return!0}async function $s(e,t,s,n,o,a,r){let c=e*t,u=ot(e,t),h=new Uint8Array(c);h[n]=1;for(let x of u[n])h[x]=1;let l=[];for(let x=0;x<c;x++)h[x]||l.push(x);l.length<s&&(l=Array.from({length:c},(x,m)=>m).filter(x=>x!==n));let f=Date.now()+vi,d=0;for(;;){let x=Date.now()+40;for(;Date.now()<x;){d++;let m=Ti(e,t,s,l);if(!o)return{...m,ng:!1,attempts:d};if(an(e,t,s,m.mine,m.num,n))return{...m,ng:!0,attempts:d};if(Date.now()>f)return{...m,ng:!1,failed:!0,attempts:d}}if(a&&a(d),await new Promise(m=>setImmediate(m)),r&&r())return null}}var bs=[null,st(90,165,255),st(100,205,100),st(255,95,95),st(175,125,255),st(255,165,70),st(70,215,215),st(235,235,235),st(160,160,160)],M={screen:"menu",menu:{sel:0,diffIdx:Math.min(le.settings.diffIdx??0,Te.length-1),ng:le.settings.ng??!0,custom:le.settings.custom||{w:20,h:12,m:40},glyphIdx:Math.max(0,bt.findIndex(e=>e.key===le.settings.glyphs))},game:null,prevScreen:"menu",press:null,showCursor:!1};function Vo(){let e=Te[M.menu.diffIdx];return e.key==="custom"?{...e,...M.menu.custom}:e}function zo(e,t){return`${e.key==="custom"?`custom-${e.w}x${e.h}-${e.m}`:e.key}:${t?"ng":"classic"}`}function zt(){let e=Vo(),t=e.w*e.h;M.game&&(M.game.cancelled=!0),M.press=null,M.game={cfg:e,w:e.w,h:e.h,m:e.m,ng:M.menu.ng,ngActual:M.menu.ng,mine:null,num:null,bbbv:0,state:new Uint8Array(t),cx:Math.floor(e.w/2),cy:Math.floor(e.h/2),phase:"ready",start:0,end:0,exploded:[],undo:null,hints:0,rewinds:0,clicks:0,hintCell:-1,hintKind:"",startCell:-1,message:"Classic mode: your first click is always safe.",genAttempts:0,cancelled:!1},M.screen="game",le.settings={diffIdx:M.menu.diffIdx,ng:M.menu.ng,custom:M.menu.custom,glyphs:bt[M.menu.glyphIdx].key},ys("settings","best","stats"),M.game.ng&&Ci(M.game),Me.render()}async function Ci(e){let t=(r,c)=>r>4?1+Math.floor(Math.random()*(r-2)):c,s=t(e.w,Math.floor(Math.random()*e.w)),n=t(e.h,Math.floor(Math.random()*e.h)),o=n*e.w+s;e.phase="generating",e.message="Generating a no-guess board\u2026",Me.render();let a=await $s(e.w,e.h,e.m,o,!0,r=>{e.genAttempts=r,e.message=`Generating a no-guess board\u2026 (${r} candidates tried)`,Me.render()},()=>e.cancelled);!a||M.game!==e||(Zo(e,a),e.startCell=o,e.cx=s,e.cy=n,e.phase="ready",e.message=a.failed?`${$.bad}Couldn't find a no-guess board in time${B}${$.text} \u2014 this one may need guessing. Click the ${$.good}green cell${B}${$.text} to start.`:`Click the ${$.good}${j}green cell${B}${$.text} to start \u2014 from there, everything can be solved by logic.`,Me.render())}function Zo(e,t){e.mine=t.mine,e.num=t.num,e.bbbv=Ri(e.w,e.h,e.mine,e.num),e.ngActual=t.ng}function ea(e,t){e.phase="playing",e.start=Date.now(),e.startCell=-1;let s=zo(e.cfg,e.ng);le.stats[s]=le.stats[s]||{played:0,won:0},le.stats[s].played++,ys("settings","best","stats"),rn(e,t)}function ta(e){return e.start?((e.end||Date.now())-e.start)/1e3:0}function sa(e){e.undo={state:e.state.slice(),clicks:e.clicks}}function ws(e){e.hintCell=-1,e.hintKind=""}async function Ei(e,t){e.phase="generating";let s=await $s(e.w,e.h,e.m,t,!1,null,()=>e.cancelled);!s||M.game!==e||(Zo(e,s),e.message="",ea(e,t),Me.render())}function na(e,t){let s=ot(e.w,e.h),n=t.slice();for(;n.length;){let o=n.pop();if(e.state[o]===0){if(e.state[o]=1,e.mine[o]){e.exploded.push(o);continue}if(e.num[o]===0)for(let a of s[o])e.state[a]===0&&n.push(a)}}if(e.exploded.length)return Ii(e);Oi(e)}function rn(e,t){if(e.phase==="ready"){if(e.startCell>=0){if(t!==e.startCell){e.cx=e.startCell%e.w,e.cy=Math.floor(e.startCell/e.w),e.message=`No Guessing: you must start on the ${$.good}${j}green cell${B}${$.text} (cursor moved there).`;return}e.message="",ea(e,t)}else Ei(e,t);return}if(e.phase!=="playing")return;let s=e.state[t];if(s===1){e.num[t]>0&&cn(e,t);return}s!==2&&(sa(e),ws(e),e.clicks++,na(e,[t]))}function cn(e,t){if(e.phase!=="playing"||e.state[t]!==1||e.num[t]===0)return;let s=ot(e.w,e.h)[t],n=0,o=[];for(let a of s)e.state[a]===2?n++:e.state[a]===0&&o.push(a);n!==e.num[t]||!o.length||(sa(e),ws(e),e.clicks++,na(e,o))}function oa(e,t){e.phase==="playing"&&e.state[t]!==1&&(e.state[t]=e.state[t]===2?0:2,e.clicks++,e.hintCell===t&&ws(e))}function Ii(e){e.phase="lost",e.end=Date.now(),e.message=`${$.bad}${j}BOOM!${B}${$.text} Press ${j}R${B}${$.text} to rewind the last move, or ${j}N${B}${$.text} for a new game.`}function Oi(e){let t=e.w*e.h,s=0;for(let l=0;l<t;l++)e.state[l]===1&&!e.mine[l]&&s++;if(s!==t-e.m)return;for(let l=0;l<t;l++)e.mine[l]&&(e.state[l]=2);e.phase="won",e.end=Date.now(),ws(e);let n=ta(e),o=zo(e.cfg,e.ng);le.stats[o]=le.stats[o]||{played:1,won:0},le.stats[o].won++;let a=e.hints===0&&e.rewinds===0,r=-1;if(a){let l=le.best[o]||[];l.push({time:Math.round(n*1e3)/1e3,bbbv:e.bbbv,date:new Date().toISOString().slice(0,10)}),l.sort((f,d)=>f.time-d.time),le.best[o]=l.slice(0,10),r=le.best[o].findIndex(f=>f.time===Math.round(n*1e3)/1e3)}ys("settings","best","stats");let c=(e.bbbv/Math.max(n,.001)).toFixed(2),u=Math.round(e.bbbv/Math.max(e.clicks,1)*100),h=`${$.good}${j}Cleared in ${n.toFixed(2)}s!${B}${$.text} 3BV ${e.bbbv} \xB7 ${c} 3BV/s \xB7 ${u}% efficiency.`;a?r===0?h+=`${$.title}${j} New best time!`:r>0&&r<10&&(h+=`${$.accent} #${r+1} best time.`):h+=`${$.muted} (hints/rewinds used \u2014 not recorded)`,e.message=h}function aa(e){e.phase!=="lost"||!e.undo||(e.state=e.undo.state,e.clicks=e.undo.clicks,e.undo=null,e.exploded=[],e.phase="playing",e.end=0,e.rewinds++,e.message="Rewound. The timer kept running \u2014 think it through this time.")}function ra(e){if(e.phase==="ready"){e.startCell>=0?(e.cx=e.startCell%e.w,e.cy=Math.floor(e.startCell/e.w),e.message=`Start on the ${$.good}${j}green cell${B}${$.text} \u2014 the cursor is on it.`):e.message="The first click is always safe \u2014 click anywhere to start.";return}if(e.phase!=="playing")return;let t=e.w*e.h,s=c=>{let u=-1,h=1/0;for(let l of c){let f=Math.abs(l%e.w-e.cx)+Math.abs(Math.floor(l/e.w)-e.cy);f<h&&(h=f,u=l)}return u},n=[];for(let c=0;c<t;c++)e.state[c]===2&&!e.mine[c]&&n.push(c);let o,a,r;if(n.length)o=s(n),a="bad",r="This flag is wrong \u2014 there is no mine here.";else{let c=new Uint8Array(t),u=new Uint8Array(t);for(let d=0;d<t;d++)c[d]=e.state[d]===1?1:0,u[d]=e.state[d]===2?1:0;let h=Xo(e.w,e.h,e.m,c,u,e.num),l=h.safe.filter(d=>e.state[d]===0),f=h.mines.filter(d=>e.state[d]===0);if(l.length)o=s(l),a="safe",r="This cell can be proven safe from the numbers around it.";else if(f.length)o=s(f),a="bad",r="This cell can be proven to be a mine \u2014 flag it.";else{let d=[];for(let x=0;x<t;x++)e.state[x]===0&&!e.mine[x]&&d.push(x);o=s(d),a="safe",r="No logical move exists here (a guess would be needed) \u2014 but this cell is safe."}}o<0||(e.hints++,e.hintCell=o,e.hintKind=a,e.cx=o%e.w,e.cy=Math.floor(o/e.w),e.message=`${a==="safe"?$.good:$.bad}Hint:${B}${$.text} ${r}`)}var mt={boardTop:0,boardLeft:0,cellW:3};function ln(){M.screen=M.screen==="help"?M.prevScreen:"menu",M.screen==="game"&&!M.game&&(M.screen="menu")}function un(){M.prevScreen=M.screen,M.screen="help"}function ia(){let e=M.game,t=process.stdout.columns||100,s=process.stdout.rows||40,n=1;for(;n+2<=Ai&&e.w*2*(n+2)+4<=t&&e.h*(n+2)+11<=s;)n+=2;let o=2*n,a=n,r=bt[M.menu.glyphIdx],c=e.w*e.h,u=[],h=e.ng?e.ngActual?`${$.good}No Guessing`:`${$.bad}No Guessing (fallback)`:`${$.muted}Classic`;u.push(`${$.title}${j}MINESWEEPER${B} ${$.text}${e.cfg.name} ${e.w}\xD7${e.h}, ${e.m} mines ${$.muted}\xB7${B} ${h}`);let l=0;for(let C=0;C<c;C++)e.state[C]===2&&l++;let f=e.phase==="lost"?`${$.bad}x_x`:e.phase==="won"?`${$.good}B-)`:`${$.title}:-)`,d=new Vt(`${$.flag}\u2691 ${String(e.m-l).padStart(3)}${B} `).add(`${$.btn} ${f} ${B}`,()=>zt()).add(` ${$.accent}\u23F1 ${ta(e).toFixed(1).padStart(6)}${B}`).add(` ${$.muted}hints ${e.hints} \xB7 rewinds ${e.rewinds}${e.bbbv?` \xB7 3BV ${e.bbbv}`:""}`);u.push(d);let x=e.w*o;u.push(`${$.border}\u250C${"\u2500".repeat(x)}\u2510`);let m=new Set(e.exploded),g=Fi(e),k=e.phase==="lost";for(let C=0;C<e.h;C++){let W=Array(a).fill(`${$.border}\u2502${B}`);for(let v=0;v<e.w;v++){let T=C*e.w+v,G=v+C&1,H=e.state[T],ee,ne=$.text,te=" ";H===1?(ee=$.rev[G],e.mine&&e.mine[T]?(te=r.mine,ne=$.mine,ee=$.boom):e.num&&e.num[T]&&(te=r.nums[e.num[T]],ne=bs[e.num[T]]+j)):(ee=$.hid[G],H===2?(te=r.flag,ne=$.flag,k&&!e.mine[T]&&(te=r.wrong,ne=$.bad+j)):k&&e.mine[T]&&(te=r.mine,ne=$.mine)),m.has(T)&&(ee=$.boom),g.has(T)&&(ee=$.pressed),T===e.hintCell&&(ee=e.hintKind==="safe"?$.hintSafe:$.hintBad,ne=$.dark+j,te===" "&&(te=e.hintKind==="safe"?r.safe:r.bad));let ie=v===e.cx&&C===e.cy&&M.showCursor&&!M.press;T===e.startCell?(ee=g.has(T)?$.pressed:ie?$.startCursor:$.hintSafe,ne=$.dark+j,te=r.start):ie&&(ee=$.cursor,ne=$.dark+j);let Gt=Wi(te),R=Math.floor((o-Gt)/2),K=Math.floor((a-1)/2);for(let _=0;_<a;_++){let ce=_===K?" ".repeat(R)+te+" ".repeat(o-Gt-R):" ".repeat(o);W[_]+=ee+ne+ce+B}}for(let v of W)u.push(v+`${$.border}\u2502`)}u.push(`${$.border}\u2514${"\u2500".repeat(x)}\u2518`),u.push(e.message?`${$.text}${e.message}`:""),u.push("");let S=new Vt;nt(S,"Hint",()=>ra(e),{enabled:e.phase==="playing"||e.phase==="ready"}),nt(S,"Rewind",()=>aa(e),{enabled:e.phase==="lost"&&!!e.undo,hot:e.phase==="lost"}),nt(S,"New game",()=>zt(),{hot:e.phase==="won"}),nt(S,"Menu",()=>{M.screen="menu"}),nt(S,"Help",un),nt(S,Me.hasLauncher()?"Arcade":"Quit",Me.leave),u.push(S),u.push(""),u.push(`${$.muted}Mouse: ${$.text}left${$.muted} reveal/chord \xB7 ${$.text}right${$.muted} flag \xB7 ${$.text}middle${$.muted} chord \xB7 click the face for a new game`),u.push(`${$.muted}Keys: \u2190\u2191\u2193\u2192/WASD move \xB7 ${$.text}Space${$.muted} reveal \xB7 ${$.text}F${$.muted} flag \xB7 ${$.text}C${$.muted} chord \xB7 ${$.text}H${$.muted} hint \xB7 ${$.text}R${$.muted} rewind \xB7 ${$.text}N${$.muted} new \xB7 ${$.text}Esc${$.muted} menu`),mt={boardTop:4,boardLeft:gs(u)+2,cellW:o,cellH:a}}function hn(){let e=[{id:"diff"}];return Te[M.menu.diffIdx].key==="custom"&&e.push({id:"cw"},{id:"ch"},{id:"cm"}),e.push({id:"ng"},{id:"glyphs"},{id:"start"}),M.game&&e.push({id:"resume"}),e.push({id:"records"},{id:"help"},{id:"quit"}),e}var Yo=new Set(["diff","cw","ch","cm","ng","glyphs"]);function Qe(e,t){let s=M.menu;e.id==="diff"?s.diffIdx=(s.diffIdx+Math.sign(t)+Te.length)%Te.length:e.id==="cw"?s.custom.w+=t:e.id==="ch"?s.custom.h+=t:e.id==="cm"?s.custom.m+=t:e.id==="ng"?s.ng=!s.ng:e.id==="glyphs"&&(s.glyphIdx=(s.glyphIdx+Math.sign(t)+bt.length)%bt.length,le.settings.glyphs=bt[s.glyphIdx].key,ys("settings","best","stats")),s.custom.w=Math.max(5,Math.min(60,s.custom.w)),s.custom.h=Math.max(5,Math.min(40,s.custom.h)),s.custom.m=Math.max(1,Math.min(s.custom.w*s.custom.h-9,s.custom.m))}function ca(e){e.id==="ng"?M.menu.ng=!M.menu.ng:e.id==="records"?M.screen="records":e.id==="help"?un():e.id==="resume"?M.screen="game":e.id==="quit"?Me.leave():zt()}function Bi(){let e=M.menu,t=hn();e.sel=Math.min(e.sel,t.length-1);let s=Vo(),n=[];n.push(""),n.push(`${$.title}${j} \u2554\u2566\u2557\u2566\u2554\u2557\u2554\u2554\u2550\u2557\u2554\u2550\u2557\u2566 \u2566\u2554\u2550\u2557\u2554\u2550\u2557\u2554\u2550\u2557\u2554\u2550\u2557\u2566\u2550\u2557`),n.push(`${$.title}${j} \u2551\u2551\u2551\u2551\u2551\u2551\u2551\u2551\u2563 \u255A\u2550\u2557\u2551\u2551\u2551\u2551\u2563 \u2551\u2563 \u2560\u2550\u255D\u2551\u2563 \u2560\u2566\u255D`),n.push(`${$.title}${j} \u2569 \u2569\u2569\u255D\u255A\u255D\u255A\u2550\u255D\u255A\u2550\u255D\u255A\u2569\u255D\u255A\u2550\u255D\u255A\u2550\u255D\u2569 \u255A\u2550\u255D\u2569\u255A\u2550`),n.push(`${$.muted} terminal edition \xB7 no guessing`),n.push("");let o=new Vt(" ");Te.forEach((r,c)=>nt(o,r.name,()=>{e.diffIdx=c,e.sel=0},{hot:c===e.diffIdx})),n.push(o),n.push("");let a=s.m/(s.w*s.h);t.forEach((r,c)=>{let u=c===e.sel,h=()=>{e.sel=c},l=new Vt(u?`${$.title}${j} \u25B6 ${B}`:" "),f=x=>l.add((u?`${$.text}${j}`:$.text)+x.padEnd(14)+B),d=x=>{let m=u?$.title+j:$.muted;l.add(`${m} \u2039 ${B}`,()=>{h(),Qe(r,-1)}),l.add(`${u?$.title:$.text} ${x} ${B}`,()=>{h(),Qe(r,1)}),l.add(`${m} \u203A ${B}`,()=>{h(),Qe(r,1)})};switch(r.id){case"diff":f("Difficulty"),d(Te[e.diffIdx].name.padEnd(12)),l.add(` ${$.muted}${s.w}\xD7${s.h}, ${s.m} mines (${Math.round(a*100)}%)`);break;case"cw":f(" Width"),d(String(e.custom.w).padStart(3));break;case"ch":f(" Height"),d(String(e.custom.h).padStart(3));break;case"cm":f(" Mines"),d(String(e.custom.m).padStart(3));break;case"ng":f("No Guessing"),d(e.ng?"ON ":"OFF"),e.ng&&a>.24&&l.add(` ${$.bad}high density \u2014 generation may fail`);break;case"glyphs":{let x=bt[e.glyphIdx];f("Symbols"),d(x.name.padEnd(8)),l.add(` ${bs[1]}${x.nums[1]}${bs[2]}${x.nums[2]}${bs[3]}${x.nums[3]} ${B}${x.flag} ${x.mine} ${$.muted}${x.desc}`);break}case"start":f("\u25B8 Start game");break;case"resume":f("\u25B8 Resume game");break;case"records":f("Best times");break;case"help":f("How to play");break;case"quit":f(Me.hasLauncher()?"Back to arcade":"Quit");break}l.whole(x=>{h(),Yo.has(r.id)?(r.id==="diff"||r.id==="ng"||r.id==="glyphs")&&Qe(r,x===2?-1:1):ca(r)},Yo.has(r.id)?x=>{h(),Qe(r,-x)}:null),n.push(l)}),n.push(""),n.push(`${$.muted} Mouse: click to choose \xB7 click \u2039 \u203A (or scroll) to change values \xB7 right-click goes back`),n.push(`${$.muted} Keys: \u2191\u2193 select \xB7 \u2190\u2192 change \xB7 Enter confirm \xB7 PgUp/PgDn \xB110 \xB7 Q ${Me.hasLauncher()?"arcade":"quit"}`),gs(n)}function la(){let e=new Vt;return nt(e,"\u25C0 Back",ln,{hot:!0}),e}function Li(){let e=["",`${$.title}${j}BEST TIMES${B} ${$.muted}(games without hints or rewinds)`,""],t=new Set([...Object.keys(le.best),...Object.keys(le.stats)]),s=o=>{let a=Te.findIndex(r=>o.startsWith(r.key));return(a<0?99:a)*2+(o.endsWith(":ng")?0:1)},n=[...t].sort((o,a)=>s(o)-s(a)||o.localeCompare(a));n.length||e.push(`${$.muted}No games played yet.`,"");for(let o of n){let[a,r]=o.split(":"),c=Te.find(d=>d.key===a),u=c?c.name:a,h=le.stats[o]||{played:0,won:0},l=h.played?Math.round(h.won/h.played*100):0;e.push(`${$.text}${j}${u}${B} ${r==="ng"?$.good+"No Guessing":$.muted+"Classic"}${B} ${$.muted}played ${h.played} \xB7 won ${h.won} (${l}%)`),(le.best[o]||[]).slice(0,5).forEach((d,x)=>{let m=d.bbbv?(d.bbbv/d.time).toFixed(2)+" 3BV/s":"";e.push(` ${x===0?$.title:$.text}${String(x+1).padStart(2)}. ${d.time.toFixed(3).padStart(8)}s${B} ${$.muted}${d.date} ${m}`)}),e.push("")}e.push(la()),e.push("",`${$.muted}Click anywhere or press Esc to go back`),gs(e)}function Ni(){let e=["",`${$.title}${j}HOW TO PLAY${B}`,"",`${$.text}Reveal every cell that isn't a mine. A number shows how many of the 8`,`${$.text}surrounding cells hold mines. Flag cells you know are mines.`,"",`${$.good}${j}No Guessing${B}${$.text} The board is built before you start, and the ${$.good}green cell${$.text}`,`${$.text} marks where you must click first. From there, the whole`,`${$.text} board can be solved by logic \u2014 you never have to gamble.`,`${$.title}${j}Chording${B}${$.text} Click a number whose flags are all placed to open all its`,`${$.text} other neighbours at once (middle-click or C also works).`,`${$.accent}${j}Hint${B}${$.text} Highlights a cell provably safe (green) \u2014 or a wrong flag /`,`${$.text} provable mine (magenta). Hinted games aren't recorded.`,`${$.bad}${j}Rewind${B}${$.text} After hitting a mine, undo that move and keep going.`,`${$.text} The timer keeps running; rewound games aren't recorded.`,"",`${$.text}${j}Mouse${B}${$.text} Left = reveal/chord \xB7 Right = flag \xB7 Middle = chord.`,`${$.text} Click the face to start a new game.`,"",`${$.muted}Stats: 3BV = minimum clicks needed to clear the board. 3BV/s is speed,`,`${$.muted}efficiency = 3BV / your clicks. Records are saved to ${Mi}`,"",la(),"",`${$.muted}Click anywhere or press Esc to go back`];gs(e)}function _i(){M.screen==="game"?ia():M.screen==="menu"?Bi():M.screen==="records"?Li():M.screen==="help"&&Ni()}var Pi=new Set(["up","down","left","right","w","a","s","d","home","end","space","enter","f","e","c"]);function qi(e){let t=M.game,s=t.cy*t.w+t.cx;switch(Pi.has(e)&&(M.showCursor=!0),e){case"up":case"w":t.cy=(t.cy-1+t.h)%t.h;break;case"down":case"s":t.cy=(t.cy+1)%t.h;break;case"left":case"a":t.cx=(t.cx-1+t.w)%t.w;break;case"right":case"d":t.cx=(t.cx+1)%t.w;break;case"home":t.cx=0;break;case"end":t.cx=t.w-1;break;case"space":case"enter":rn(t,s);break;case"f":case"e":oa(t,s);break;case"c":cn(t,s);break;case"h":ra(t);break;case"r":aa(t);break;case"n":zt();return;case"m":case"escape":M.screen="menu";break;case"?":un();break}}function dn(e){let t=M.game;if(e.x<mt.boardLeft||e.y<mt.boardTop)return-1;let s=Math.floor((e.y-mt.boardTop)/mt.cellH),n=Math.floor((e.x-mt.boardLeft)/mt.cellW);return n<0||s<0||n>=t.w||s>=t.h?-1:s*t.w+n}function Di(e){let t=M.game,s=dn(e);if(s<0||t.phase!=="playing"&&t.phase!=="ready")return;t.cx=s%t.w,t.cy=Math.floor(s/t.w);let n=e.b&3;n===2?oa(t,s):M.press={idx:s,btn:n}}function ji(e){let t=M.game,s=dn(e);M.press.idx=s,s>=0&&(t.cx=s%t.w,t.cy=Math.floor(s/t.w))}function Ki(e){let t=M.game,s=dn(e),{btn:n}=M.press;M.press=null,!(s<0)&&(n===0?rn(t,s):n===1&&cn(t,s))}function Fi(e){let t=new Set,s=M.press;if(!s||s.idx<0||e.phase!=="playing"&&e.phase!=="ready")return t;let n=e.state[s.idx];if(n===0&&t.add(s.idx),n===1&&e.num&&e.num[s.idx]>0||s.btn===1)for(let o of ot(e.w,e.h)[s.idx])e.state[o]===0&&t.add(o);return t}function Gi(e){let t=e.b&3;if(M.screen==="game"&&(M.showCursor=!1),M.press){M.screen!=="game"?M.press=null:e.b&32?ji(e):e.press||Ki(e);return}if(!e.press||e.b&32)return;let s=e.b&64?e.b&1?1:-1:0,n=Si(e);if(s){if(n&&n.onWheel)n.onWheel(s);else if(M.screen==="menu"){let o=hn().length;M.menu.sel=(M.menu.sel+s+o)%o}}else n&&n.onClick?n.onClick(t):M.screen==="game"?Di(e):M.screen==="records"||M.screen==="help"?ln():M.screen==="menu"&&t===2&&M.game&&(M.screen="game")}function Hi(e){let t=M.menu,s=hn(),n=s[t.sel];switch(e){case"up":case"w":t.sel=(t.sel-1+s.length)%s.length;break;case"down":case"s":t.sel=(t.sel+1)%s.length;break;case"left":case"a":Qe(n,-1);break;case"right":case"d":Qe(n,1);break;case"pageup":Qe(n,10);break;case"pagedown":Qe(n,-10);break;case"space":case"enter":ca(n);break;case"n":zt();return;case"escape":M.game&&(M.screen="game");break}}function Qi(e){if(e==="q")return Me.leave();if(M.screen==="game"){if(M.game.phase==="generating"&&!["escape","m","n","?"].includes(e))return;qi(e)}else M.screen==="menu"?Hi(e):["escape","enter","space","m"].includes(e)&&ln()}var Ji={render:_i,onKey:Qi,onMouse:Gi,onTick(){M.screen==="game"&&M.game&&M.game.phase==="playing"&&ia()}};async function Ui(){for(let e of Te.slice(0,4)){let t=e.key==="evil"?5:10,s=0,n=0,o=0;for(let a=0;a<t;a++){let r=Math.floor(Math.random()*e.w*e.h),c=Date.now(),u=await $s(e.w,e.h,e.m,r,!0);if(s+=Date.now()-c,n+=u.attempts,u.failed)o++;else if(!an(e.w,e.h,e.m,u.mine,u.num,r,!0))throw new Error("regenerated board not solvable")}console.log(`${e.name.padEnd(13)} avg ${(s/t).toFixed(0).padStart(5)} ms, avg ${(n/t).toFixed(1)} candidates, ${o} timeouts`)}for(let e=0;e<300;e++){let t=Te[e%3],s=Math.floor(Math.random()*t.w*t.h),n=await $s(t.w,t.h,t.m,s,!1);an(t.w,t.h,t.m,n.mine,n.num,s,!0)}console.log("Soundness check on 300 random boards: OK")}ua.exports={name:"Minesweeper",screen:Ji,bench:Ui}});var gt=pe((jl,$a)=>{"use strict";var xn=["","","2","3","4","5","6","7","8","9","10","J","Q","K","A"],ks=["","","Two","Three","Four","Five","Six","Seven","Eight","Nine","Ten","Jack","Queen","King","Ace"],$t=["","","Twos","Threes","Fours","Fives","Sixes","Sevens","Eights","Nines","Tens","Jacks","Queens","Kings","Aces"],da=["\u2660","\u2665","\u2666","\u2663"],Zt=e=>(e>>2)+2,It=e=>e&3,fa=(e,t)=>e-2<<2|t,Yi=e=>xn[Zt(e)]+da[It(e)];function Xi(e){return e.trim().split(/\s+/).map(t=>{let s=xn.indexOf(t.slice(0,-1).toUpperCase().replace("T","10")),n="shdc".indexOf(t.slice(-1).toLowerCase());if(s<2||n<0)throw new Error("bad card "+t);return fa(s,n)})}function Vi(e=Math.random){let t=Array.from({length:52},(s,n)=>n);for(let s=t.length-1;s>0;s--){let n=Math.floor(e()*(s+1)),o=t[s];t[s]=t[n],t[n]=o}return t}var zi=["High card","Pair","Two pair","Three of a kind","Straight","Flush","Full house","Four of a kind","Straight flush"];function xa(e){let t=e.map(Zt).sort((l,f)=>f-l),s=It(e[0]),n=e.every(l=>It(l)===s),o=new Map;for(let l of t)o.set(l,(o.get(l)||0)+1);let a=[...o].sort((l,f)=>f[1]-l[1]||f[0]-l[0]),r=0;o.size===5&&(t[0]-t[4]===4?r=t[0]:t[0]===14&&t[1]===5&&(r=5));let c,u;r&&n?(c=8,u=[r]):a[0][1]===4?(c=7,u=a.map(l=>l[0])):a[0][1]===3&&a[1][1]===2?(c=6,u=a.map(l=>l[0])):n?(c=5,u=t):r?(c=4,u=[r]):a[0][1]===3?(c=3,u=a.map(l=>l[0])):a[0][1]===2&&a[1][1]===2?(c=2,u=a.map(l=>l[0])):a[0][1]===2?(c=1,u=a.map(l=>l[0])):(c=0,u=t);let h=c;for(let l=0;l<5;l++)h=h*15+(u[l]||0);return h}var fn={};function Zi(e){if(fn[e])return fn[e];let t=[];for(let s=0;s<e;s++)for(let n=s+1;n<e;n++)for(let o=n+1;o<e;o++)for(let a=o+1;a<e;a++)for(let r=a+1;r<e;r++)t.push([s,n,o,a,r]);return fn[e]=t}function es(e){let t=-1,s=null;for(let n of Zi(e.length)){let o=xa(n.map(a=>e[a]));o>t&&(t=o,s=n)}return{score:t,cards:s.map(n=>e[n])}}function pa(e){let t=[];for(let s=0;s<5;s++)t.unshift(e%15),e=Math.floor(e/15);return{cat:e,kick:t}}function ec(e){let{cat:t,kick:s}=pa(e);switch(t){case 8:return s[0]===14?"Royal flush":`Straight flush, ${ks[s[0]]} high`;case 7:return`Four of a kind, ${$t[s[0]]}`;case 6:return`Full house, ${$t[s[0]]} over ${$t[s[1]]}`;case 5:return`Flush, ${ks[s[0]]} high`;case 4:return`Straight, ${ks[s[0]]} high`;case 3:return`Three of a kind, ${$t[s[0]]}`;case 2:return`Two pair, ${$t[s[0]]} and ${$t[s[1]]}`;case 1:return`Pair of ${$t[s[0]]}`;default:return`${ks[s[0]]} high`}}function tc(e,t,s=600,n=Math.random){let o=new Set([...e,...t]),a=[];for(let u=0;u<52;u++)o.has(u)||a.push(u);let r=2+(5-t.length),c=0;for(let u=0;u<s;u++){for(let d=0;d<r;d++){let x=d+Math.floor(n()*(a.length-d)),m=a[d];a[d]=a[x],a[x]=m}let h=t.concat(a.slice(2,r)),l=es(e.concat(h)).score,f=es([a[0],a[1]].concat(h)).score;c+=l>f?1:l===f?.5:0}return c/s}var sc=`
|
|
5
|
+
AA:849 KK:820 QQ:796 JJ:780 TT:755 99:729 88:693 77:670 AKs:665 AQs:659 AKo:655 ATs:645 AJs:643
|
|
6
|
+
AQo:640 66:638 KQs:638 A9s:637 AJo:634 A8s:630 KJs:626 ATo:625 KQo:618 A9o:617 KTs:615 A7s:612
|
|
7
|
+
KTo:607 QJs:607 A7o:603 KJo:602 A6s:601 A8o:599 A5s:598 55:598 K9s:596 QTs:590 K8s:587 K7s:586
|
|
8
|
+
A5o:583 A4s:583 A3s:582 JTs:578 QTo:577 Q9s:574 K6s:573 QJo:573 44:573 K9o:572 A6o:570 A2s:569
|
|
9
|
+
K5s:569 A3o:566 Q8s:566 A4o:565 K8o:561 Q9o:557 J9s:556 A2o:554 K7o:552 JTo:550 K4s:545 K6o:545
|
|
10
|
+
Q8o:542 T9s:541 Q6s:539 K2s:539 J8s:538 33:534 Q7s:532 J9o:531 K5o:528 Q5s:527 T8s:526 T9o:526
|
|
11
|
+
K3s:525 K4o:524 Q7o:522 K3o:518 J7s:516 J8o:516 Q4s:512 K2o:512 Q6o:511 J6s:510 T8o:507 Q3s:505
|
|
12
|
+
J5s:505 98s:504 22:504 Q4o:502 T7s:502 J7o:497 Q2s:495 T6s:494 J4s:492 97s:492 Q5o:490 Q3o:489
|
|
13
|
+
J3s:486 T7o:485 96s:482 98o:479 J6o:478 87s:475 J5o:473 T5s:469 Q2o:469 T4s:468 J2s:466 76s:460
|
|
14
|
+
97o:460 T6o:460 J4o:458 95s:455 86s:455 T3s:454 87o:454 T2s:453 J3o:448 75s:447 T4o:446 85s:443
|
|
15
|
+
J2o:443 94s:442 T5o:439 86o:438 96o:434 95o:432 65s:429 76o:427 74s:425 84s:424 T3o:422 T2o:421
|
|
16
|
+
93s:420 92s:420 75o:418 64s:418 65o:413 73s:412 54s:412 85o:410 93o:406 63s:404 94o:403 82s:400
|
|
17
|
+
83s:399 74o:398 84o:393 43s:390 92o:389 72s:387 53s:385 62s:384 54o:378 52s:375 82o:373 83o:372
|
|
18
|
+
73o:369 64o:369 53o:365 42s:362 32s:358 63o:355 72o:349 52o:345 62o:342 43o:339 42o:336 32o:323
|
|
19
|
+
`,pn=new Map;{let e=0;sc.trim().split(/\s+/).forEach((t,s)=>{let[n,o]=t.split(":"),a=n.length===2?6:n[2]==="s"?4:12;e+=a,pn.set(n,{rank:s,eq:+o/1e3,pct:e/1326})})}var Ws=e=>"xx23456789TJQKA"[e];function ma(e){let[t,s]=e,n=Zt(t),o=Zt(s),a=Math.max(n,o),r=Math.min(n,o);return a===r?Ws(a)+Ws(r):Ws(a)+Ws(r)+(It(t)===It(s)?"s":"o")}var ba=e=>pn.get(ma(e)).pct;function nc(e,t,s,n=400,o=Math.random){let a=new Uint8Array(52);for(let l of e)a[l]=1;for(let l of t)a[l]=1;let r=[];for(let l=0;l<52;l++)a[l]||r.push(l);let c=s.map((l,f)=>f).sort((l,f)=>s[l]-s[f]),u=new Int32Array(52),h=0;for(let l=1;l<=n;l++){let f=()=>{for(;;){let S=r[Math.floor(o()*r.length)];if(u[S]!==l)return u[S]=l,S}},d=[];for(let S of c){let A=null;for(let C=0;C<60;C++){let W=r[Math.floor(o()*r.length)],v=r[Math.floor(o()*r.length)];if(!(W===v||u[W]===l||u[v]===l)&&(A=[W,v],s[S]>=1||ba(A)<=s[S]))break}A?(u[A[0]]=l,u[A[1]]=l):A=[f(),f()],d.push(A)}let x=t.slice();for(;x.length<5;)x.push(f());let m=es(e.concat(x)).score,g=-1,k=0;for(let S of d){let A=es(S.concat(x)).score;A>g&&(g=A,k=0),A===g&&k++}m>g?h+=1:m===g&&(h+=1/(k+1))}return h/n}$a.exports={PREFLOP:pn,handClass:ma,handPct:ba,equityVs:nc,RANK_CH:xn,SUIT_CH:da,CATEGORY:zi,rankOf:Zt,suitOf:It,card:fa,cardText:Yi,parseCards:Xi,shuffledDeck:Vi,eval5:xa,bestHand:es,scoreParts:pa,handName:ec,equity:tc}});var bn=pe((Kl,ya)=>{"use strict";var{RESET:oc,fg:ga}=tt(),mn={A:["\u2554\u2550\u2557","\u2560\u2550\u2563","\u2569 \u2569"],B:["\u2554\u2557 ","\u2560\u2569\u2557","\u255A\u2550\u255D"],C:["\u2554\u2550\u2557","\u2551 ","\u255A\u2550\u255D"],E:["\u2554\u2550\u2557","\u2551\u2563 ","\u255A\u2550\u255D"],F:["\u2554\u2550\u2557","\u2560\u2563 ","\u255A "],G:["\u2554\u2550\u2557","\u2551 \u2566","\u255A\u2550\u255D"],H:["\u2566 \u2566","\u2560\u2550\u2563","\u2569 \u2569"],I:["\u2566","\u2551","\u2569"],J:[" \u2566"," \u2551","\u255A\u2550\u255D"],K:["\u2566\u2554\u2550","\u2560\u2569\u2557","\u2569 \u2569"],L:["\u2566 ","\u2551 ","\u2569\u2550\u255D"],M:["\u2554\u2566\u2557","\u2551\u2551\u2551","\u2569 \u2569"],N:["\u2554\u2557\u2554","\u2551\u2551\u2551","\u255D\u255A\u255D"],O:["\u2554\u2550\u2557","\u2551 \u2551","\u255A\u2550\u255D"],P:["\u2554\u2550\u2557","\u2560\u2550\u255D","\u2569 "],Q:["\u2554\u2550\u2557 ","\u2551\u2550\u256C\u2557","\u255A\u2550\u255D\u255A"],R:["\u2566\u2550\u2557","\u2560\u2566\u255D","\u2569\u255A\u2550"],S:["\u2554\u2550\u2557","\u255A\u2550\u2557","\u255A\u2550\u255D"],T:["\u2554\u2566\u2557"," \u2551 "," \u2569 "],U:["\u2566 \u2566","\u2551 \u2551","\u255A\u2550\u255D"],W:["\u2566 \u2566","\u2551\u2551\u2551","\u255A\u2569\u255D"],X:["\u2550\u2557 \u2566","\u2554\u2569\u2566\u255D","\u2569 \u255A\u2550"],0:["\u2554\u2550\u2557","\u2551 \u2551","\u255A\u2550\u255D"],1:[" \u2557"," \u2551"," \u2569"],2:["\u2554\u2550\u2557","\u2554\u2550\u255D","\u255A\u2550\u255D"],3:["\u2554\u2550\u2557"," \u2550\u2563","\u255A\u2550\u255D"],4:["\u2566 \u2566","\u255A\u2550\u2563"," \u2569"],5:["\u2554\u2550\u2557","\u255A\u2550\u2557","\u255A\u2550\u255D"],6:["\u2554\u2550\u2557","\u2560\u2550\u2557","\u255A\u2550\u255D"],7:["\u2554\u2550\u2557"," \u2551"," \u2569"],8:["\u2554\u2550\u2557","\u2560\u2550\u2563","\u255A\u2550\u255D"],9:["\u2554\u2550\u2557","\u255A\u2550\u2563","\u255A\u2550\u255D"]," ":[" "," "," "],",":[" "," ","\u2553 "]};function ac(e){let t=["","",""];for(let s of e.toUpperCase()){let n=mn[s]||mn[" "];for(let o=0;o<3;o++)t[o]+=n[o]}return t}function rc(e,t,s=1,n=!1){let o="",a=0;for(let r of e){let c=Math.sin(a*.35-t/160*s)*.5+.5;o+=n?ga(255,Math.round(120+135*c),Math.round(60*c)):ga(Math.round(200+55*c),Math.round(150+75*c),Math.round(40+90*c)),o+=r,a++}return o+oc}ya.exports={FONT:mn,bigText:ac,shimmer:rc}});var qa=pe((Fl,Pa)=>{"use strict";var ts=tt(),{RESET:I,BOLD:O,DIM:Wt,fg:F,bg:V,C:E,visLen:Ot,Line:wa,button:Oe,draw:ic}=ts,{save:Ce,persist:vt,wallet:Re,START_CHIPS:kn}=Et(),ve=gt(),de=9,fe=[{key:"10",name:"Ten",pay:[0,0,0,5,25,100]},{key:"J",name:"Jack",pay:[0,0,0,5,25,100]},{key:"Q",name:"Queen",pay:[0,0,0,5,25,100]},{key:"K",name:"King",pay:[0,0,0,5,40,150]},{key:"A",name:"Ace",pay:[0,0,0,5,40,150]},{key:"scarab",name:"Scarab",pay:[0,0,5,30,100,750]},{key:"statue",name:"Statue",pay:[0,0,5,30,100,750]},{key:"pharaoh",name:"Pharaoh",pay:[0,0,5,40,400,2e3]},{key:"explorer",name:"Explorer",pay:[0,0,10,100,1e3,5e3]},{key:"book",name:"Book",pay:[0,0,0,2,20,200]}],he=5,Wn=3,St=10,ka=5,at=[[1,1,1,1,1],[0,0,0,0,0],[2,2,2,2,2],[0,1,2,1,0],[2,1,0,1,2],[1,2,2,2,1],[1,0,0,0,1],[2,2,1,0,0],[0,0,1,2,2],[2,1,1,1,0]],ns=[1,2,3,4,5,10,20,50,100],kt=[{key:"big",label:"big win",desc:"wins of 10\xD7 bet or more, and after free games"},{key:"win",label:"any win",desc:"every win"},{key:"feature",label:"free games",desc:"only after free games end"},{key:"never",label:"never",desc:"collect everything, like the real game"}],cc=10,lc=[7,6,5,5,4,3,2,2,1,1];function uc(e,t){let s=e.reduce((a,r)=>a+r,0),n=new Array(s).fill(-1),o=e.map((a,r)=>r).sort((a,r)=>e[a]-e[r]);for(let a of o)for(let r=0;r<e[a];r++){let c=Math.floor(t*7+a*5+r*s/e[a])%s;for(;n[c]!==-1;)c=(c+1)%s;n[c]=a}return n}var rt=Array.from({length:he},(e,t)=>uc(lc,t)),Sn=e=>e.map((t,s)=>[0,1,2].map(n=>rt[s][(t+n)%rt[s].length]));function Mn(e){let t=e.find(o=>o!==de);if(t===void 0)return null;let s=0;for(;s<e.length&&(e[s]===t||e[s]===de);)s++;let n=fe[t].pay[s];return n?{sym:t,count:s,mult:n}:null}function Wa(e,t,s,n=-1){let o=[];for(let u=0;u<t;u++){let h=at[u],l=Mn(h.map((f,d)=>e[d][f]));l&&o.push({kind:"line",line:u,sym:l.sym,count:l.count,amount:l.mult*s,cells:h.slice(0,l.count).map((f,d)=>[d,f])})}let a=[];e.forEach((u,h)=>u.forEach((l,f)=>{l===de&&a.push([h,f])}));let r=fe[de].pay[Math.min(5,a.length)];r&&o.push({kind:"scatter",sym:de,count:a.length,amount:r*s*t,cells:a});let c=null;if(n>=0){let u=[];e.forEach((l,f)=>{l.includes(n)&&u.push(f)});let h=fe[n].pay[u.length];h&&(c={kind:"expand",sym:n,count:u.length,reels:u,amount:h*s*t,cells:u.flatMap(l=>[[l,0],[l,1],[l,2]])})}return{wins:o,books:a.length,expand:c}}function hc(){let e=rt.map(d=>{let x=new Array(fe.length).fill(0);return d.forEach(m=>x[m]++),x.map(m=>m/d.length)}),t=0,s=0,n=[];(function d(x,m){if(x===he){let g=Mn(n);g&&(t+=m*g.mult,s+=m);return}for(let g=0;g<fe.length;g++)e[x][g]&&(n[x]=g,d(x+1,m*e[x][g]))})(0,1);let o=(d,x)=>d.filter((m,g)=>[0,1,2].some(k=>d[(g+k)%d.length]===x)).length/d.length,a=d=>d.reduce((x,m)=>{let g=new Array(x.length+1).fill(0);return x.forEach((k,S)=>{g[S]+=k*(1-m),g[S+1]+=k*m}),g},[1]),r=a(rt.map(d=>o(d,de))),c=r.reduce((d,x,m)=>d+x*fe[de].pay[m],0),u=r.slice(3).reduce((d,x)=>d+x,0),h=St/(1-St*u),l=0;for(let d=0;d<de;d++)l+=a(rt.map(x=>o(x,d))).reduce((x,m,g)=>x+m*fe[d].pay[g],0)/de;let f=h*(t+c+l);return{line:t,scatter:c,trigger:u,games:h,feature:f,rtp:t+c+u*f,lineHit:s}}var D=F(255,206,84),ss=V(255,200,60),Q=F(220,190,130),$n=F(25,18,10),Je=F(196,150,60),gn=[{fg:F(255,176,70),bg:V(26,28,56)},{fg:F(90,170,255),bg:V(26,28,56)},{fg:F(235,110,230),bg:V(26,28,56)},{fg:F(110,225,120),bg:V(26,28,56)},{fg:F(255,92,84),bg:V(26,28,56)},{fg:F(120,230,170),bg:V(18,62,52)},{fg:F(210,210,200),bg:V(58,54,44)},{fg:F(255,215,90),bg:V(84,62,14)},{fg:F(255,170,110),bg:V(92,34,26)},{fg:F(255,220,120),bg:V(110,24,30)}],yn={scarab:"\u{1FAB2}",statue:"\u{1F5FF}",pharaoh:"\u{1F451}",explorer:"\u{1F920}",book:"\u{1F4D6}"},Sa={scarab:"SCARAB",statue:"STATUE",pharaoh:"PHARAO",explorer:"EXPLR",book:"BOOK"},Ma=[[255,90,90],[255,200,60],[110,220,120],[90,170,255],[235,110,230],[255,150,60],[80,220,220],[190,140,255],[255,255,255],[170,230,90]],vn=e=>F(...Ma[e]),Ss=e=>V(...Ma[e].map(t=>Math.round(t*.55))),{bigText:An,shimmer:wn}=bn(),z=e=>e.toLocaleString("en-US");function va(e,t,s,{bgc:n,fgc:o,dim:a=!1}={}){let r=gn[e],c=n||r.bg,u=(o||r.fg)+(a?Wt:O),h=c+" ".repeat(t)+I,l=g=>{let k=Ot(g),S=Math.max(0,Math.floor((t-k)/2));return c+" ".repeat(S)+u+g+I+c+" ".repeat(Math.max(0,t-k-S))+I},f=fe[e].key,d=Ce.settings.glyphs==="classic",x=new Array(s).fill(h),m=Math.floor(s/2);return e<5?s>=5?An(f==="10"?"10":f).forEach((g,k)=>{x[m-1+k]=l(g)}):x[m]=l(f):(x[m]=l(d?Sa[f]:yn[f]),s>=5&&(x[s-1]=l((a?"":Wt)+fe[e].name.toUpperCase()),d||(x[m-1]=l("\xB7 \xB7"),x[m+1]=l("\xB7 \xB7")))),x}var Aa=50,i={lines:Math.min(10,Math.max(1,Ce.slots.lines??10)),betIdx:Math.max(0,ns.indexOf(Ce.slots.lineBet??1)),stops:[0,9,18,27,4],target:[],stopAt:[],stopped:[!0,!0,!0,!0,!0],landedAt:[0,0,0,0,0],anticipation:-1,mode:"base",phase:"idle",wins:[],expand:null,expandShown:0,expandNext:0,winTotal:0,winT0:0,until:0,pending:0,triggered:!1,free:null,intro:null,outro:null,gamble:null,preview:0,panel:"lines",auto:!1,autoStop:Math.max(0,kt.findIndex(e=>e.key===Ce.slots.autoStop)),autoStopped:!1,message:"",lag:0},Rs=()=>i.free?i.free.bet:ns[i.betIdx],Mt=()=>i.free?i.free.lines:i.lines,Be=()=>Rs()*Mt(),Bt=()=>Ce.slots.stats={spins:0,wagered:0,won:0,biggest:0,features:0,...Ce.slots.stats},os=()=>i.phase==="spinning"||i.phase==="expand"||i.phase==="intro"||i.phase==="outro"||i.mode==="free"||i.phase==="gamble";function yt(e,t=Date.now()){os()||(i.lines=Math.max(1,Math.min(10,i.lines+e)),i.preview=t+2400,i.previewT0=t,Ta())}function wt(e){os()||(i.betIdx=Math.max(0,Math.min(ns.length-1,i.betIdx+e)),Ta())}function Ta(){Ce.slots.lines=i.lines,Ce.slots.lineBet=ns[i.betIdx],vt("slots")}function it(e=Date.now()){if(!(i.phase==="spinning"||i.phase==="expand"||i.phase==="intro"||i.phase==="outro"||i.phase==="gamble")&&!i.triggered){if(i.mode==="base"){if(Re.sync(),Re.chips<Be()){i.auto=!1,i.message=Re.canRefill()?`${E.bad}Out of chips.${I}${Q} Press ${O}F${I}${Q} for a free refill to ${kn}.`:`${E.bad}Not enough credit for this bet${I}${Q} \u2014 lower the bet or lines.`;return}Re.adjust(-Be());let t=Bt();t.spins++,t.wagered+=Be(),vt("slots")}else i.free.left--,i.free.played++;i.pending=0,i.message="",i.autoStopped=!1,i.wins=[],i.expand=null,i.winTotal=0,i.lag=0,i.preview=0,i.phase="spinning",i.anticipation=-1,i.target=rt.map(t=>Math.floor(Math.random()*t.length)),i.stopAt=i.target.map((t,s)=>e+650+s*260),i.stopped=[!1,!1,!1,!1,!1]}}function Ms(e){switch(i.phase){case"spinning":{for(let t=0;t<he;t++){if(i.stopped[t])continue;let s=rt[t].length;if(e>=i.stopAt[t]){dc(t,e);continue}let n=Math.ceil((i.stopAt[t]-e)/Aa);i.stops[t]=(i.target[t]+n)%s}i.stopped.every(Boolean)&&fc(e);break}case"expand":e>=i.expandNext&&(i.expandShown++,i.expandNext=e+380,i.expandShown>i.expand.reels.length&&(i.wins.push(i.expand),Ra(e,i.winTotal+i.expand.amount)));break;case"idle":i.mode==="base"&&i.auto&&e>=i.until&&it(e);break;case"wins":i.triggered&&e>=i.until?xc(e):i.mode==="free"&&e>=i.until?i.free.left>0?it(e):mc(e):i.mode==="base"&&i.auto&&e>=i.until&&it(e);break;case"intro":e>=i.intro.until&&pc(e);break;case"outro":e>=i.outro.until&&(i.mode="base",i.free=null,i.phase="wins",i.wins=[],i.expand=null,i.winT0=e-1e7,i.until=e+1500,i.auto&&kt[i.autoStop].key!=="never"&&Ca());break;case"gamble":{let t=i.gamble;if(t.pick&&e>=t.revealUntil){if(t.history.unshift(t.card),t.history.length=Math.min(t.history.length,7),t.pick=null,!t.ok){i.pending=0,i.phase="idle",i.gamble=null,i.lag=0,i.message=`${E.bad}${O}Gamble lost.`;break}t.stake*=2,t.rounds++,i.pending=t.stake,i.lag=0,t.rounds>=ka&&Cs(`${D}${O}Gamble limit reached \u2014 collected ${z(t.stake)}.`)}break}}(i.phase==="wins"||i.phase==="expand")&&(i.lag=Math.max(0,i.winTotal-vs(e))+(i.phase==="expand"?i.expand.amount:0))}function dc(e,t){if(i.stopped[e]=!0,i.stops[e]=i.target[e],i.landedAt[e]=t,i.anticipation<0&&e<he-1&&Sn(i.stops).slice(0,e+1).flat().filter(n=>n===de).length>=2){i.anticipation=e+1;for(let n=e+1;n<he;n++)i.stopAt[n]=Math.max(i.stopAt[n],t)+1100*(n-e)}}function fc(e){let t=Sn(i.stops),s=i.mode==="free"?i.free.sym:-1,n=Wa(t,Mt(),Rs(),s);i.wins=n.wins;let o=n.wins.reduce((c,u)=>c+u.amount,0)+(n.expand?n.expand.amount:0);o&&Re.adjust(o);let a=Bt();a.won+=o,vt("slots"),i.mode==="free"&&(i.free.won+=o),n.books>=3&&(i.mode==="base"?i.triggered=!0:(i.free.left+=St,i.message=`${D}${O}+${St} FREE GAMES!`));let r=o-(n.expand?n.expand.amount:0);n.expand?(i.expand=n.expand,i.expandShown=0,i.expandNext=e+500,i.winTotal=r,i.winT0=e,i.phase="expand"):Ra(e,r)}function Ra(e,t){i.phase="wins",i.winTotal=t,i.winT0=e;let s=Oa(t);if(i.mode==="free")i.until=e+(t?Math.max(1600,s+900):700);else{i.until=e+(t?Math.max(1200,s+600):400),i.triggered&&(i.until=e+Math.max(2600,s+800)),i.pending=t;let n=Bt();t>n.biggest&&(n.biggest=t,vt("slots")),!t&&!i.triggered&&(i.phase="idle");let o=kt[i.autoStop].key;i.auto&&t&&!i.triggered&&(o==="win"||o==="big"&&t>=cc*Be())&&Ca()}}function Ca(){i.auto=!1,i.autoStopped=!0}function Ea(e=1){i.autoStop=(i.autoStop+e+kt.length)%kt.length,Ce.slots.autoStop=kt[i.autoStop].key,vt("slots")}function Ia(){i.auto=!i.auto,i.autoStopped=!1,i.auto&&i.mode==="base"&&it()}function Oa(e){return e?Math.min(5e3,500+e/Math.max(1,Be())*90):0}function vs(e){let t=Oa(i.winTotal);return t?Math.min(i.winTotal,Math.floor(i.winTotal*(e-i.winT0)/t)):i.winTotal}function xc(e){i.triggered=!1,i.phase="intro";let t=Math.floor(Math.random()*de),s=[],n=900,o=60;for(;n<3600;)s.push({t:n,s:Math.floor(Math.random()*de)}),n+=o,o*=1.12;s.push({t:n,s:t}),i.intro={t0:e,sym:t,flips:s,settle:e+n,until:e+n+2600};let a=Bt();a.features++,vt("slots")}function pc(e){i.free={left:St,played:0,sym:i.intro.sym,won:0,lines:i.lines,bet:ns[i.betIdx]},i.intro=null,i.mode="free",i.phase="idle",i.message="",it(e)}function mc(e){i.phase="outro",i.outro={t0:e,won:i.free.won,until:e+4200,games:i.free.played},i.pending=i.free.won,i.winTotal=i.free.won,i.winT0=e,i.lag=0,i.message=`${D}${O}Feature win ${z(i.free.won)}${I}${Q} in ${i.free.played} free games.`}function Ba(){i.mode!=="base"||i.phase!=="wins"||!i.pending||i.triggered||(i.auto=!1,i.lag=0,i.phase="gamble",i.gamble={stake:i.pending,rounds:0,history:i.gambleHistory||[],pick:null})}function As(e,t=Date.now()){let s=i.gamble;if(!s||s.pick)return;let n=Math.floor(Math.random()*52),o=ve.suitOf(n)===1||ve.suitOf(n)===2;s.pick=e,s.card=n,s.ok=e==="red"===o,s.revealUntil=t+1100,Re.adjust(s.ok?s.stake:-s.stake),i.lag=s.ok?s.stake:-s.stake;let a=Bt();a.won+=s.ok?s.stake:-s.stake,vt("slots")}function Cs(e){!i.gamble||i.gamble.pick||(i.gambleHistory=i.gamble.history,i.message=e||`${E.good}${O}Collected ${z(i.gamble.stake)}.`,i.gamble=null,i.pending=0,i.phase="idle",i.lag=0)}function La(){!Re.canRefill()||os()||(Re.refill(),i.message=`${E.good}Wallet refilled to ${kn}.`)}function Tn(){i.auto=!1,i.gamble&&i.gamble.pick&&Ms(i.gamble.revealUntil),i.gamble&&Cs();let e=Date.now();for(let t=0;t<1e5&&(i.mode==="free"||["spinning","expand","intro","outro"].includes(i.phase)||i.triggered);t++)e+=6e4,Ms(e);i.phase="idle",i.lag=0}function bc(){let e=process.stdout.rows||40,t=process.stdout.columns||100,s=e>=47&&t>=82;return s?{w:12,h:5,big:s}:{w:8,h:3,big:s}}function $c(e){let t=new Map,s=-1,n=!1;if(i.preview>e&&i.phase!=="spinning"){let o=Math.floor((e-i.previewT0)/240)%Mt();return at[o].forEach((a,r)=>t.set(r+":"+a,Ss(o))),{hi:t,focusLine:o,dimOthers:!0,previewAll:!0}}if(i.phase==="wins"&&i.wins.length){let o=e-i.winT0,a=Math.floor(o/260)%2===0;if(o<1300)for(let r of i.wins)for(let[c,u]of r.cells)t.set(c+":"+u,a?ss:null);else{let r=i.wins[Math.floor((o-1300)/1100)%i.wins.length];for(let[c,u]of r.cells)t.set(c+":"+u,a?r.kind==="line"?Ss(r.line):ss:null);r.kind==="line"&&(s=r.line)}n=!0}return{hi:t,focusLine:s,dimOthers:n}}function gc(e){if(i.phase!=="wins"||!i.wins.length)return"";let t=e-i.winT0;if(t<1300)return"";let s=i.wins[Math.floor((t-1300)/1100)%i.wins.length],n=fe[s.sym].name.toUpperCase();return s.kind==="line"?`${vn(s.line)}${O}LINE ${s.line+1}${I}${Q} ${s.count} \xD7 ${n} ${D}${O}${z(s.amount)}`:s.kind==="scatter"?`${D}${O}${s.count} \xD7 BOOK SCATTER${I}${Q} pays ${D}${O}${z(s.amount)}`:`${D}${O}EXPANDING ${n}${I}${Q} ${s.count} reels on every line ${D}${O}${z(s.amount)}`}function yc(e,t){let{w:s,h:n}=t,{hi:o,focusLine:a,dimOthers:r}=$c(e),c=[],u=[[],[],[]],h=[[],[],[]];for(let g=0;g<at.length;g++)u[at[g][0]].push(g),h[at[g][4]].push(g);let l=(g,k)=>{let S=Math.ceil(g.length/n);return g.slice(k*S,k*S+S).map(C=>{let W=C<Mt(),v=C===a,T=String(C+1).padStart(3);return v?Ss(C)+F(255,255,255)+O+T+I:W?vn(C)+O+T+I:F(70,70,80)+T+I}).join("")},f=6,d=i.expand&&(i.phase==="expand"||i.phase==="wins")?i.expand.reels.slice(0,i.phase==="expand"?i.expandShown:99):[],x=Sn(i.stops),m=`${Je}\u2554${"\u2550".repeat(he*s+(he-1))}\u2557`;c.push(" ".repeat(f)+m);for(let g=0;g<Wn;g++){let k=[];for(let A=0;A<he;A++){let C=d.includes(A)?i.expand.sym:x[A][g],W=A+":"+g,v=i.phase==="spinning"&&!i.stopped[A],T={};if(v?T={dim:!0,bgc:V(16,16,30)}:d.includes(A)&&(T={bgc:Math.floor(e/200)%2?V(150,105,20):V(120,84,16)}),o.has(W)){let G=o.get(W);G&&(T={bgc:G,fgc:G===ss?$n:F(255,255,255)})}else r&&!v&&(T={...T,dim:!0,bgc:V(14,14,26)});C===de&&!v&&e-i.landedAt[A]<420&&i.phase==="spinning"&&(T={bgc:ss,fgc:$n}),k.push(va(C,s,n,T))}let S=i.phase==="spinning"&&i.anticipation>=0;for(let A=0;A<n;A++){let C="";for(let v=0;v<he;v++){let T=v===0?"":S&&v>=i.anticipation&&!i.stopped[v]&&Math.floor(e/120)%2?D+"\u2503":Je+"\u2502";C+=T+I+k[v][A]}let W=l(u[g],A);c.push(`${" ".repeat(Math.max(0,f-Ot(W)))}${W}${Je}\u2551${I}${C}${Je}\u2551${I}${l(h[g],A)}`)}}return c.push(" ".repeat(f)+`${Je}\u255A${"\u2550".repeat(he*s+(he-1))}\u255D`),c}function wc(e,t){let s=t.h*Wn+2,n=he*t.w+(he-1)+2,o=i.intro,a=e-o.t0,r=[...o.flips].reverse().find(S=>a>=S.t),c=r?r.s:-1,u=e>=o.settle,h=Math.floor((n-8)/2),l=s-2,f=Math.min(t.big?5:3,l-2),d=V(214,190,140),x=F(110,80,40),m=[];for(let S=0;S<l;S++)m.push(d+x+(S%2?" \u2625 \u2248\u2248\u2248\u2248\u2248\u2248\u2248\u2248\u2248\u2248\u2248\u2248\u2248\u2248\u2248\u2248\u2248\u2248\u2248\u2248\u2248\u2248\u2248\u2248\u2248\u2248\u2248\u2248":" \u2248\u2248\u2248\u2248\u2248 \u2625 \u2248\u2248\u2248\u2248\u2248\u2248\u2248\u2248\u2248\u2248\u2248\u2248\u2248\u2248\u2248\u2248\u2248\u2248\u2248\u2248\u2248\u2248").slice(0,h-2).padEnd(h)+I);let g=new Array(l).fill(d+" ".repeat(h)+I);if(c>=0){let S=Math.min(h-2,14),A=u&&Math.floor(e/220)%2?ss:null,C=va(c,S,f,A?{bgc:A,fgc:$n}:{}),W=Math.floor((l-f)/2),v=Math.floor((h-S)/2);C.forEach((T,G)=>{g[W+G]=d+" ".repeat(v)+I+T+d+" ".repeat(h-S-v)+I})}let k=[`${Je}\u2554${"\u2550".repeat(n-2)}\u2557`];for(let S=0;S<l;S++)k.push(`${Je}\u2551 ${V(120,24,30)} ${I}${m[S]}${V(80,50,20)} ${I}${g[S]}${V(120,24,30)} ${I}${Je} \u2551`);return k.push(`${Je}\u255A${"\u2550".repeat(n-2)}\u255D`),k.map(S=>" "+S)}function kc(e,t){let s=t.h*Wn+2,n=i.gamble,o=t.big?13:9,a=t.big?9:5,r=[],c;if(n.pick){let d=n.card,x=ve.suitOf(d)===1||ve.suitOf(d)===2,m=V(246,244,238),g=(x?F(205,30,45):F(20,20,30))+O,k=ve.RANK_CH[ve.rankOf(d)],S=ve.SUIT_CH[ve.suitOf(d)];c=[];for(let A=0;A<a;A++){let C=" ".repeat(o);A===0?C=(" "+k+S).padEnd(o):A===a-1?C=(k+S+" ").padStart(o):A===Math.floor(a/2)&&(C=" ".repeat(Math.floor((o-1)/2))+S+" ".repeat(o-1-Math.floor((o-1)/2))),c.push(m+g+C+I)}}else{let d=Math.floor(e/170)%2===0,x=d?V(170,20,30):V(20,20,26),m=d?F(230,90,90):F(120,120,140);c=Array.from({length:a},(g,k)=>x+m+(k%2?"\u259A\u259E".repeat(o):"\u259E\u259A".repeat(o)).slice(0,o)+I)}let u=he*t.w+(he-1)+2,h=[];h.push(`${D}${O}GAMBLE${I}${Q} stake ${D}${O}${z(n.stake)}${I}${Q} \u2192 win ${D}${O}${z(n.stake*2)}${I}${Q} (${ka-n.rounds} left)`),h.push(""),c.forEach(d=>h.push(d)),h.push(""),n.pick?h.push(n.ok?`${E.good}${O} ${n.pick.toUpperCase()} \u2014 YOU WIN!`:`${E.bad}${O} ${n.pick.toUpperCase()}? No \u2014 lost.`):h.push(`${Q}Red or black?`);let l=n.history.slice(0,7).map(d=>(ve.suitOf(d)===1||ve.suitOf(d)===2?F(230,60,70):F(200,200,210))+O+ve.SUIT_CH[ve.suitOf(d)]+I).join(" ");h.push(`${E.muted}previous cards ${l||"\u2014"}`);let f=Math.max(0,Math.floor((s-h.length)/2));for(let d=0;d<f;d++)r.push("");for(h.forEach(d=>r.push(" ".repeat(Math.max(0,Math.floor((u-Ot(d))/2))+6)+d));r.length<s;)r.push("");return r.slice(0,s)}function Wc(e,t){let s=a=>" ".repeat(Math.max(0,Math.floor((t-Ot(a))/2)))+a,n=["","","",""],o=(a,r,c)=>{An(a).forEach((u,h)=>{n[h]=s(wn(u,e,1.5,c))}),n[3]=s(r||"")};if(i.phase==="intro"){let a=e>=i.intro.settle;o("FREE GAMES",a?`${Q}${St} free games \xB7 special expanding symbol: ${D}${O}${fe[i.intro.sym].name.toUpperCase()}`:`${Q}the book opens\u2026`,!0)}else if(i.phase==="outro"){let a=Math.min(i.outro.won,Math.floor(i.outro.won*(e-i.outro.t0)/2500));o(z(a),`${D}${O}FEATURE WIN${I}${Q} \xB7 ${i.outro.games} free games`,!0)}else if(i.phase==="gamble")o(z(i.gamble.stake),`${Q}double or nothing`);else if(i.phase==="expand"&&vs(e)===0)o(fe[i.expand.sym].name,`${D}${O}EXPANDING${I}${Q} \xB7 ${i.expand.count} reels \xB7 pays on every line`,!0);else if((i.phase==="wins"||i.phase==="expand")&&i.winTotal){let a=vs(e),r=i.winTotal/Be(),c=r>=150?"EPIC WIN":r>=50?"MEGA WIN":r>=15?"BIG WIN":"";c&&i.mode==="base"&&Math.floor((e-i.winT0)/1400)%2===0?o(c,`${D}${O}\u2726 ${z(a)} \u2726`,!0):o(z(a),gc(e)||(i.phase==="expand"?`${D}${O}EXPANDING ${fe[i.expand.sym].name.toUpperCase()}\u2026`:`${D}WIN`),r>=15)}else i.mode==="free"?n[1]=s(`${Q}free game ${D}${O}${i.free.played}${I}${Q} of ${i.free.played+i.free.left}`):n[1]=s(i.message||`${Q}${Wt}good luck, explorer`);return n}function Sc(e){let t=["","","",""];for(let s=0;s<at.length;s++){let n=s<Mt(),o=n?vn(s):F(70,70,80),a=i.preview>e&&s===Math.floor((e-i.previewT0)/240)%Mt();t[0]+=(a?Ss(s)+F(255,255,255):o)+O+`${String(s+1).padStart(2)} `.slice(0,6)+I+" ";for(let r=0;r<3;r++){let c="";for(let u=0;u<he;u++)c+=at[s][u]===r?"\u25A0":"\xB7";t[r+1]+=o+(n?O:Wt)+c+I+" "}}return t}function Mc(){let e=Rs(),t=[`${E.muted}${"symbol".padEnd(14)}${"5\xD7".padStart(8)}${"4\xD7".padStart(8)}${"3\xD7".padStart(8)}${"2\xD7".padStart(8)} ${Wt}(credits at ${e}/line)`];for(let n=de-1;n>=0;n--){let o=fe[n],a=n<5?o.key:Ce.settings.glyphs==="classic"?Sa[o.key]:yn[o.key],r=`${gn[n].fg}${O}${a}${I} ${Q}${o.name}`,c=[5,4,3,2].map(u=>o.pay[u]?`${D}${String(z(o.pay[u]*e)).padStart(8)}`:`${E.muted}${"\u2014".padStart(8)}`).join("");t.push(r+" ".repeat(Math.max(1,14-Ot(r)))+c)}let s=fe[de];return t.push(`${gn[de].fg}${O}${Ce.settings.glyphs==="classic"?"BOOK":yn.book}${I} ${Q}Book: wild + scatter. 3/4/5 anywhere pay ${D}${z(s.pay[3]*Be())}/${z(s.pay[4]*Be())}/${z(s.pay[5]*Be())}${Q} and give ${St} free games.`),t.push(`${E.muted}Free games: a special symbol expands over whole reels and pays on all played lines, adjacent or not.`),t}function vc(){let e=Date.now(),t=bc(),s=he*t.w+(he-1)+2+12,n=[];t.big?(An("BOOK OF RA").forEach(g=>n.push(" "+" ".repeat(Math.floor((s-8-Ot(g))/2))+wn(g,e,.6))),n.push(` ${" ".repeat(Math.floor((s-8-34)/2))}${Q}${Wt}deluxe \xB7 10 lines \xB7 expanding symbol`)):n.push(` ${wn("\u2726 BOOK OF RA \u2726",e,.6)} ${Q}${Wt}deluxe \xB7 10 lines`);let o;i.phase==="intro"?o=wc(e,t):i.phase==="gamble"?o=kc(e,t):o=yc(e,t),o.forEach(g=>n.push(g)),Wc(e,s).forEach(g=>n.push(g));let a=Re.chips-i.lag,r=i.phase==="gamble"?i.gamble.stake:i.phase==="outro"?i.outro.won:i.phase==="wins"||i.phase==="expand"?vs(e):i.pending,c=(g,k,S=E.text)=>`${E.muted}${g} ${S}${O}${k}${I}`,u=i.mode==="free"?` ${c("FREE",`${i.free.left} left`,D)} ${c("FEATURE",z(i.free.won),D)}`:"",h=i.autoStopped&&i.pending>0&&i.phase==="wins"?` ${Math.floor(e/400)%2?D:Q}${O}AUTO PAUSED${I}${Q} \u2014 G gamble \xB7 A resume \xB7 Space spin`:"";n.push(` ${c("CREDIT",z(a))} ${c("WIN",z(r),D)}${u}${h}`);let l=new wa(" "),f=os();l.add(`${E.muted}LINES`),l.add(`${D}${O} \u2039 ${I}`,()=>yt(-1),g=>yt(-g)),l.add(`${E.text}${O}${String(Mt()).padStart(2)}${I}`,()=>{i.preview=Date.now()+2400,i.previewT0=Date.now()},g=>yt(-g)),l.add(`${D}${O} \u203A ${I}`,()=>yt(1),g=>yt(-g)),l.add(` ${E.muted}BET/LINE`),l.add(`${D}${O} \u2039 ${I}`,()=>wt(-1),g=>wt(-g)),l.add(`${E.text}${O}${String(Rs()).padStart(3)}${I}`,null,g=>wt(-g)),l.add(`${D}${O} \u203A ${I}`,()=>wt(1),g=>wt(-g)),l.add(` ${E.muted}TOTAL ${E.text}${O}${Be()}${I}`),n.push(l),n.push("");let d=new wa(" ");if(i.phase==="gamble"){let g=i.gamble;Oe(d,"\u25C0 RED",()=>As("red"),{enabled:!g.pick,hot:!g.pick}),Oe(d,"BLACK \u25B6",()=>As("black"),{enabled:!g.pick,hot:!g.pick}),Oe(d,`COLLECT ${z(g.stake)}`,()=>Cs(),{enabled:!g.pick})}else{let g=!["spinning","expand","intro","outro"].includes(i.phase)&&i.mode==="base";Oe(d,"START",()=>it(),{enabled:g,hot:g}),Oe(d,i.auto?"AUTO \u25CF":"AUTO",Ia,{hot:i.auto}),Oe(d,`AUTO STOP: ${kt[i.autoStop].label}`,()=>Ea());let k=i.mode==="base"&&i.phase==="wins"&&i.pending>0&&!i.triggered;Oe(d,"GAMBLE",Ba,{enabled:k,hot:k&&i.autoStopped}),Oe(d,i.panel==="lines"?"PAYTABLE":"LINES",()=>{i.panel=i.panel==="lines"?"paytable":"lines"}),Re.canRefill()&&!f&&Oe(d,`REFILL ${kn}`,La),Oe(d,ts.hasLauncher()?"ARCADE":"QUIT",_a)}n.push(d),n.push(""),(i.panel==="paytable"?Mc():Sc(e)).forEach(g=>n.push(" "+g)),n.push("");let x=Bt(),m=x.wagered?`${Math.round(x.won/x.wagered*100)}%`:"\u2014";n.push(` ${E.muted}spins ${x.spins} \xB7 features ${x.features} \xB7 wagered ${z(x.wagered)} \xB7 won ${z(x.won)} (${m}) \xB7 best ${z(x.biggest)}`),n.push(i.phase==="gamble"?` ${E.muted}Keys: ${E.text}R/\u2190${E.muted} red \xB7 ${E.text}B/\u2192${E.muted} black \xB7 ${E.text}C/Space${E.muted} collect`:` ${E.muted}Keys: ${E.text}Space${E.muted} start \xB7 ${E.text}\u2191\u2193${E.muted} lines \xB7 ${E.text}\u2190\u2192${E.muted} bet \xB7 ${E.text}G${E.muted} gamble \xB7 ${E.text}A${E.muted} auto \xB7 ${E.text}S${E.muted} auto stop \xB7 ${E.text}P${E.muted} paytable \xB7 ${E.text}F${E.muted} refill \xB7 ${E.text}Esc${E.muted} ${ts.hasLauncher()?"arcade":"quit"}`),ic(n)}var Ts=null;function Ac(){Ts||(Ts=setInterval(()=>{let e=Date.now(),t=i.phase;Ms(e),(t!=="idle"||i.phase!=="idle"||i.preview>e-100)&&ts.render()},Aa))}function Na(){clearInterval(Ts),Ts=null}function _a(){Tn(),Na(),ts.leave()}var Tc={render:vc,onShow(){Re.sync(),Ac()},onQuit(){Tn()},onKey(e){if(e==="escape"||e==="q")return _a();if(i.phase==="gamble"){e==="r"||e==="left"?As("red"):e==="b"||e==="right"?As("black"):(e==="c"||e==="space"||e==="enter")&&Cs();return}switch(e){case"space":case"enter":i.mode==="base"&&it();break;case"up":case"+":case"=":yt(1);break;case"down":case"-":yt(-1);break;case"right":wt(1);break;case"left":wt(-1);break;case"g":Ba();break;case"a":Ia();break;case"s":Ea();break;case"p":i.panel=i.panel==="lines"?"paytable":"lines";break;case"l":os()||(i.preview=Date.now()+2400,i.previewT0=Date.now());break;case"f":La();break}}};Pa.exports={name:"Book of Ra",screen:Tc,SYMBOLS:fe,STRIPS:rt,LINES:at,BOOK:de,evaluate:Wa,lineResult:Mn,theory:hc,_st:i,_update:Ms,_spin:it,_settle:Tn,_stopLoop:Na}});var In=pe((Gl,Ga)=>{"use strict";var{RESET:as,BOLD:Rn,fg:Es,bg:Is}=tt(),Le=gt(),Da=Is(246,244,238),ja=Is(255,230,140),Ka=Is(60,70,150),Rc=Is(32,110,72),Fa=Es(205,30,45),Cn=Es(20,20,30),En=e=>Le.suitOf(e)===1||Le.suitOf(e)===2;function Cc(e,{hidden:t=!1,hi:s=!1,empty:n=!1}={}){if(n)return[0,1,2].map(()=>Rc+" "+as);if(t)return[0,1,2].map(()=>Ka+Es(120,130,210)+"\u2591\u2591\u2591\u2591\u2591"+as);let o=s?ja:Da,a=En(e)?Fa:Cn,r=Le.RANK_CH[Le.rankOf(e)],c=Le.SUIT_CH[Le.suitOf(e)];return[o+a+Rn+r.padEnd(5),o+a+" "+c+" ",o+a+Rn+r.padStart(5)].map(u=>u+as)}var Ec=e=>[0,1,2].map(t=>e.map(s=>s[t]).join(" "));function Ic(e,{hidden:t=!1,hi:s=!1}={}){return t?Ka+Es(120,130,210)+"\u2591\u2591\u2591"+as:(s?ja:Da)+(En(e)?Fa:Cn)+Rn+(Le.RANK_CH[Le.rankOf(e)]+Le.SUIT_CH[Le.suitOf(e)]).padEnd(3)+as}Ga.exports={cardRows:Cc,cardsRows:Ec,mini:Ic,isRed:En,BLACK:Cn}});var Bn=pe((Hl,Ua)=>{"use strict";var Os=gt(),Ha=5,Qa=10,Ja=["Preflop","Flop","Turn","River"],On=class{constructor(t,s,n=Os.shuffledDeck(),o={sb:Ha,bb:Qa}){if(this.n=t.length,this.n<2)throw new Error("need two players");this.sbAmt=o.sb,this.bbAmt=o.bb,this.names=t.map(r=>r.name),this.start=t.map(r=>r.stack),this.stacks=this.start.slice(),this.button=s,this.deck=n.slice(),this.hole=t.map(()=>[]);for(let r=0;r<2;r++)for(let c=1;c<=this.n;c++)this.hole[(s+c)%this.n].push(this.deck.pop());this.board=[],this.pot=0,this.bets=new Array(this.n).fill(0),this.committed=new Array(this.n).fill(0),this.folded=new Array(this.n).fill(!1),this.acted=new Array(this.n).fill(!1),this.street=0,this.lastRaise=this.bbAmt,this.over=!1,this.result=null,this.log=[],this.actions=[];let a=this.n===2;this.sb=a?s:this.next(s),this.bb=this.next(this.sb),this.put(this.sb,this.sbAmt),this.put(this.bb,this.bbAmt),this.actions.push({seat:this.sb,street:0,type:"blind",to:this.bets[this.sb]}),this.actions.push({seat:this.bb,street:0,type:"blind",to:this.bets[this.bb]}),this.log.push(`${this.names[this.sb]} ${this.verb(this.sb,"post")} ${this.bets[this.sb]}, ${this.names[this.bb]} ${this.verb(this.bb,"post")} ${this.bets[this.bb]}`),this.advance(a?s:this.next(this.bb))}next(t){return(t+1)%this.n}verb(t,s){return this.names[t]==="You"?s:s+"s"}put(t,s){let n=Math.min(s,this.stacks[t]);return this.stacks[t]-=n,this.bets[t]+=n,this.committed[t]+=n,n}get maxBet(){return Math.max(...this.bets)}get totalPot(){return this.pot+this.bets.reduce((t,s)=>t+s,0)}allIn(t){return this.stacks[t]===0&&!this.folded[t]}live(){let t=[];for(let s=0;s<this.n;s++)this.folded[s]||t.push(s);return t}othersWithChips(t){return this.live().some(s=>s!==t&&this.stacks[s]>0)}legal(t){let s=Math.min(this.maxBet-this.bets[t],this.stacks[t]),n=this.bets[t]+this.stacks[t],o=this.stacks[t]>s&&this.othersWithChips(t)&&!this.acted[t],a=Math.min(this.maxBet+this.lastRaise,n);return{toCall:s,canCheck:s===0,canRaise:o,minTo:a,maxTo:n,isBet:this.maxBet===0}}needsAction(t){return this.folded[t]||this.stacks[t]===0?!1:this.bets[t]<this.maxBet?!0:!this.acted[t]&&this.othersWithChips(t)}act(t,s){if(this.over||t!==this.toAct)throw new Error("not your turn");let n=this.legal(t),o=this.names[t],a={seat:t,street:this.street,type:s.type};switch(s.type){case"fold":this.folded[t]=!0,this.log.push(`${o} ${this.verb(t,"fold")}`);break;case"check":if(!n.canCheck)throw new Error("cannot check");this.log.push(`${o} ${this.verb(t,"check")}`);break;case"call":{if(n.canCheck)throw new Error("nothing to call");let c=this.put(t,n.toCall);a.amount=c,this.log.push(`${o} ${this.verb(t,"call")} ${c}${this.allIn(t)?" (all-in)":""}`);break}case"raise":{if(!n.canRaise)throw new Error("cannot raise");let c=Math.max(n.minTo,Math.min(n.maxTo,Math.round(s.to))),u=c-this.maxBet;if(a.reraise=this.actions.some(h=>h.street===this.street&&h.type==="raise"),u>=this.lastRaise){this.lastRaise=u;for(let h=0;h<this.n;h++)h!==t&&(this.acted[h]=!1)}this.put(t,c-this.bets[t]),a.to=c,this.log.push(`${o} ${n.isBet?this.verb(t,"bet"):this.verb(t,"raise")+" to"} ${c}${this.allIn(t)?" (all-in)":""}`);break}default:throw new Error("unknown action "+s.type)}a.allIn=this.allIn(t),this.actions.push(a),this.acted[t]=!0;let r=this.live();if(r.length===1)return this.finishFold(r[0]);this.advance(this.next(t))}advance(t){for(let s=0;s<this.n;s++){let n=(t+s)%this.n;if(this.needsAction(n)){this.toAct=n;return}}this.endStreet()}collectBets(){let t=this.bets.map((a,r)=>r).sort((a,r)=>this.bets[r]-this.bets[a]),[s,n]=t,o=this.bets[s]-this.bets[n];o>0&&(this.stacks[s]+=o,this.committed[s]-=o,this.bets[s]-=o),this.pot+=this.bets.reduce((a,r)=>a+r,0),this.bets.fill(0)}dealStreet(){let t=this.deck.splice(this.board.length?-1:-3);this.board.push(...t),this.log.push(`\u2014 ${Ja[this.board.length===3?1:this.board.length-2]}: ${t.map(Os.cardText).join(" ")} \u2014`)}endStreet(){this.collectBets();let t=this.live().filter(s=>this.stacks[s]>0).length;if(this.street===3||t<=1){for(this.runoutFrom={log:this.log.length,board:this.board.length},this.runout=this.board.length<5;this.board.length<5;)this.dealStreet();return this.street=4,this.showdown()}this.street++,this.dealStreet(),this.acted.fill(!1),this.lastRaise=this.bbAmt,this.advance(this.next(this.button))}finishFold(t){this.collectBets();let s=new Array(this.n).fill(0);s[t]=this.pot,this.stacks[t]+=this.pot,this.result={winners:[t],showdown:!1,won:s,pots:[{amount:this.pot,eligible:[t],winners:[t]}]},this.log.push(`${this.names[t]} ${this.verb(t,"win")} ${this.pot}`),this.over=!0}buildPots(){let t=this.live(),s=this.committed.slice(),n=[];for(;t.some(a=>s[a]>0);){let a=Math.min(...t.filter(u=>s[u]>0).map(u=>s[u])),r=t.filter(u=>s[u]>=a),c=0;for(let u=0;u<this.n;u++){let h=Math.min(s[u],a);c+=h,s[u]-=h}n.push({amount:c,eligible:r})}let o=s.reduce((a,r)=>a+r,0);return o&&n.length&&(n[n.length-1].amount+=o),n}showdown(){let t={};for(let a of this.live())t[a]=Os.bestHand(this.hole[a].concat(this.board));let s=this.buildPots(),n=new Array(this.n).fill(0),o=new Set;s.forEach((a,r)=>{let c=Math.max(...a.eligible.map(x=>t[x].score)),u=a.eligible.filter(x=>t[x].score===c).sort((x,m)=>(x-this.button-1+this.n)%this.n-(m-this.button-1+this.n)%this.n),h=Math.floor(a.amount/u.length),l=a.amount-h*u.length;for(let x of u)n[x]+=h+(l-- >0?1:0),o.add(x);a.winners=u;let f=s.length===1?"Pot":r===0?"Main pot":`Side pot ${r}`,d=u.map(x=>this.names[x]).join(" & ");this.log.push(`${f} ${a.amount} \u2192 ${d}${u.length>1?" (split)":""}, ${Os.handName(t[u[0]].score).toLowerCase()}`)});for(let a=0;a<this.n;a++)this.stacks[a]+=n[a];this.result={winners:[...o],showdown:!0,best:t,won:n,pots:s},this.over=!0}};Ua.exports={Hand:On,SB:Ha,BB:Qa,STREETS:Ja}});var Nn=pe((Ql,tr)=>{"use strict";var Ya=gt(),Va=[{key:"solid",label:"solid",open:1,aggr:1,bluff:.1,margin:.02},{key:"tight",label:"tight",open:.65,aggr:.75,bluff:.03,margin:.06},{key:"loose",label:"loose-aggressive",open:1.5,aggr:1.4,bluff:.2,margin:0},{key:"station",label:"calling station",open:1.45,aggr:.45,bluff:.03,margin:-.06},{key:"maniac",label:"maniac",open:2.2,aggr:2,bluff:.32,margin:-.03}],Xa=[1,.72,.42,.3,.22,.17,.14,.12,.11,.1],Ln=25,za=(e,t,s)=>Math.max(t,Math.min(s,e)),Za=()=>({hands:0,vpip:0,pfr:0,shoves:0});function Oc(e,t){for(let s=0;s<t.n;s++){let n=e[t.names[s]]=e[t.names[s]]||Za(),o=t.actions.filter(a=>a.seat===s&&a.street===0&&a.type!=="blind");n.hands++,o.some(a=>a.type==="call"||a.type==="raise")&&n.vpip++,o.some(a=>a.type==="raise")&&n.pfr++,o.some(a=>a.type==="raise"&&a.allIn&&a.to>=Ln*t.bbAmt)&&n.shoves++}}function rs(e,t,s,n){let o=e[t],a=8;return o?(o[s]+n*a)/(o.hands+a):n}function er(e,t,s={}){let n=e.names[t],o=e.actions.filter(u=>u.seat===t&&u.street===0&&u.type!=="blind"),a=o.filter(u=>u.type==="raise"),r=1;if(a.length){let u=a[a.length-1];u.allIn&&u.to>=Ln*e.bbAmt?r=rs(s,n,"shoves",.06)*1.3:u.reraise?r=rs(s,n,"pfr",.18)*.45:r=rs(s,n,"pfr",.18)*1.15}else o.some(u=>u.type==="call")&&(r=Math.max(.15,rs(s,n,"vpip",.3)*1.1));let c=e.actions.filter(u=>u.seat===t&&u.street>0&&u.type==="raise").length;return r*=Math.pow(.75,c),za(r,.025,1)}function Bc(e,t,s={}){let n=s.style||Va[0],o=s.models||{},a=s.iters||300,r=s.rng||Math.random,c=e.legal(t),u=e.bbAmt,h=e.hole[t],l=e.live().filter(W=>W!==t),f=e.totalPot,d=c.toCall/(f+c.toCall),x=W=>(W=Math.round(W/u)*u,W>=c.maxTo*.45&&(W=c.maxTo),{type:"raise",to:za(W,c.minTo,c.maxTo)}),m=W=>x(e.maxBet+W*(f+c.toCall)),g=()=>c.canCheck?{type:"check"}:{type:"fold"},k=()=>Ya.equityVs(h,e.board,l.map(W=>er(e,W,o)),a,r);if(e.street===0){let W=Ya.handPct(h);if(!(e.maxBet>u)){let H=l.filter(ie=>!e.acted[ie]&&e.stacks[ie]>0).length,ee=Math.min(1,Xa[Math.min(H,Xa.length-1)]*n.open),ne=e.actions.filter(ie=>ie.street===0&&ie.type==="call").length,te=e.stacks[t]+e.bets[t]<=12*u;return c.canRaise&&W<=ee*(ne?.7:1)?te?{type:"raise",to:c.maxTo}:x(u*(2.5+ne+(r()<.3?.5:0))):c.canCheck?{type:"check"}:c.toCall<=u&&W<=ee*(ne?1.4:1.6)?{type:"call"}:{type:"fold"}}let T=k(),G=d+n.margin;return c.canRaise&&(W<=.02||T>Math.max(.6,G+.2))&&r()<.6+.25*n.aggr?x(e.maxBet*(e.maxBet>=8*u?2.3:3)):!c.canCheck&&T>=G?{type:"call"}:g()}let S=k(),A=Math.max(1,l.length),C=Math.pow(S,1/A);return c.canCheck?c.canRaise?C>.78?r()<.8?m(.7):{type:"check"}:C>.62&&r()<.55*n.aggr?m(.5):A<=2&&C<.4&&r()<n.bluff?m(.6):{type:"check"}:{type:"check"}:c.canRaise&&C>.85&&r()<.2+.6*n.aggr?m(.8):S>=d+n.margin?{type:"call"}:c.canRaise&&A===1&&r()<n.bluff*.25?m(.7):{type:"fold"}}tr.exports={STYLES:Va,botDecide:Bc,rangeOf:er,observe:Oc,newModel:Za,freq:rs,SHOVE_BB:Ln}});var or=pe((Ul,nr)=>{"use strict";var Lc=require("events"),{Hand:Nc,SB:_c,BB:Pc}=Bn(),{STYLES:sr,botDecide:qc,observe:Dc,newModel:Jl}=Nn(),ct=6,_n=100,Pn=2e3,qn={0:[],1:[3],2:[2,4],3:[1,3,5],4:[1,2,4,5],5:[1,2,3,4,5]},Bs=[0,3,2,4,1,5],jc=["Rusty","Mabel","Gizmo","Vera","Dex","Pickles","Nova","Bolt","Juno","Ozzy","Pip","Tilda","Moss","Rook"],Kc=3,Dn=class extends Lc{constructor(t={}){super(),this.opts={bots:0,botStack:1e3,fast:!1,turnMs:0,autoNextMs:0,...t},this.models=t.models||{},this.seats=new Array(ct).fill(null),this.queue=[],this.button=-1,this.hand=null,this.map=[],this.handNo=0,this.shown=0,this.notes=[],this.chat=[],this.ready=new Set,this.deadline=0,this.timers={},this.closed=!1,this.started=!this.opts.waitForStart;for(let s of qn[Math.max(0,Math.min(5,this.opts.bots))])this.seats[s]=this.newBot()}newBot(){let t=new Set(this.seats.filter(Boolean).map(o=>o.name)),s=jc.filter(o=>!t.has(o)),n=sr[Math.floor(Math.random()*sr.length)];return{name:s[Math.floor(Math.random()*s.length)],stack:this.opts.botStack,bot:!0,style:n}}addPerson(t,s){t=String(t||"").trim().slice(0,14)||"Player";let n=this.seats.findIndex(c=>c&&c.name.toLowerCase()===t.toLowerCase());if(n>=0){let c=this.seats[n];if(c.bot||c.connected)throw new Error(`the name "${t}" is taken at this table`);return c.connected=!0,c.away=0,this.note(`${c.name} reconnected`),this.changed(),this.maybeStart(),c}s=Math.max(_n,Math.min(Pn,Math.floor(s)||0));let o={name:t,stack:s,bot:!1,connected:!0,away:0,pendingNet:0},a=Bs.find(c=>!this.seats[c]);if(a!==void 0)return this.seats[a]=o,this.note(`${t} sits down`),this.changed(),this.maybeStart(),o;let r=Bs.find(c=>this.seats[c].bot&&!this.seats[c].leaving);if(r===void 0)throw new Error("the table is full");return this.seats[r].leaving=!0,this.queue.push({person:o,seat:r}),this.handRunning()||(this.tidySeats(),this.maybeStart()),this.changed(),o}seatOf(t){return this.seats.indexOf(t)}rebuy(t,s){let n=this.seats[t];return!n||n.bot||n.stack>0||this.inHand(t)?!1:(n.stack=Math.max(_n,Math.min(Pn,Math.floor(s)||0)),this.note(`${n.name} buys in for ${n.stack}`),this.changed(),this.maybeStart(),!0)}removePerson(t){let s=this.seats[t];!s||s.bot||(this.queue=this.queue.filter(n=>n.person!==s),this.inHand(t)?(s.leaving=!0,s.connected=!1,this.autoActIfTurn(t)):this.seats[t]=null,this.note(`${s.name} leaves`),this.changed())}disconnect(t){let s=this.seats[t];!s||s.bot||(s.connected=!1,this.note(`${s.name} disconnected`),this.autoActIfTurn(t),this.changed(),this.checkReady())}handRunning(){return!!(this.hand&&!this.hand.over)}inHand(t){let s=this.map.indexOf(t);return s>=0&&this.handRunning()&&!this.hand.folded[s]}tidySeats(){for(let t=0;t<ct;t++){let s=this.seats[t];s&&(s.bot&&s.stack===0?(this.seats[t]=null,this.seats[t]=this.newBot(),this.note(`${s.name} is busted \u2014 ${this.seats[t].name} sits down`)):s.leaving?this.seats[t]=null:!s.bot&&!s.connected&&++s.away>Kc&&(this.seats[t]=null))}for(let t of this.queue.splice(0)){let s=this.seats[t.seat]?Bs.find(n=>!this.seats[n]):t.seat;s!==void 0&&(this.seats[s]=t.person,this.note(`${t.person.name} sits down`))}}begin(){this.started||(this.started=!0,this.maybeStart(),this.changed())}setBots(t){if(!this.started){for(let s=0;s<ct;s++)this.seats[s]&&this.seats[s].bot&&(this.seats[s]=null);t=Math.max(0,Math.min(5,t));for(let s of[...qn[t],...Bs]){if(this.seats.filter(n=>n&&n.bot).length>=t)break;this.seats[s]||(this.seats[s]=this.newBot())}this.opts.bots=this.seats.filter(s=>s&&s.bot).length,this.changed()}}maybeStart(){this.closed||!this.started||this.handRunning()||this.timers.next||this.hand&&this.hand.over&&this.revealing()||this.hand&&this.hand.over&&this.opts.autoNextMs===0&&!this.everyoneReady()||this.dealHand()}canDeal(){let t=this.seats.filter(s=>s&&s.stack>0&&!s.leaving);return t.length>=2&&t.some(s=>!s.bot&&s.connected)}dealHand(){if(this.tidySeats(),!this.canDeal()){this.hand=this.hand&&this.hand.over?this.hand:null,this.changed();return}for(let t=1;t<=ct;t++){let s=(this.button+t+ct)%ct;if(this.seats[s]&&this.seats[s].stack>0){this.button=s;break}}this.map=[];for(let t=0;t<ct;t++)this.seats[t]&&this.seats[t].stack>0&&this.map.push(t);this.handNo++,this.hand=new Nc(this.map.map(t=>({name:this.seats[t].name,stack:this.seats[t].stack})),this.map.indexOf(this.button)),this.shown=0,this.ready.clear(),this.notes=this.notes.slice(-2),this.afterAction()}revealing(){return!!(this.hand&&this.hand.runout&&this.shown<5)}afterAction(){let t=this.hand;if(this.clearTimers(),t.runout&&this.shown<5)return this.shown=this.shown<3?3:this.shown+1,this.timers.reveal=setTimeout(()=>this.afterAction(),this.opts.fast?700:1100),this.changed();if(this.shown=t.board.length,t.over)return this.endHand();let s=this.map[t.toAct],n=this.seats[s];if(n.bot){let o=this.map.filter((r,c)=>!this.seats[r].bot&&!t.folded[c]&&!t.allIn(c)&&this.seats[r].connected),a=this.opts.botDelayMs!==void 0?this.opts.botDelayMs:o.length?this.opts.fast?300+Math.random()*250:650+Math.random()*600:220+Math.random()*150;this.timers.bot=setTimeout(()=>{this.hand!==t||t.over||(t.act(t.toAct,qc(t,t.toAct,{style:n.style,models:this.models,iters:260})),this.afterAction())},a)}else!n.connected||n.leaving?this.timers.turn=setTimeout(()=>this.autoAct(t),400):this.opts.turnMs&&(this.deadline=Date.now()+this.opts.turnMs,this.timers.turn=setTimeout(()=>this.autoAct(t),this.opts.turnMs));this.changed()}autoAct(t){if(this.hand!==t||t.over)return;let s=t.legal(t.toAct);t.act(t.toAct,{type:s.canCheck?"check":"fold"}),this.afterAction()}autoActIfTurn(t){let s=this.hand;s&&!s.over&&this.map[s.toAct]===t&&(this.clearTimers(),this.timers.turn=setTimeout(()=>this.autoAct(s),200))}endHand(){let t=this.hand;this.map.forEach((s,n)=>{this.seats[s]&&(this.seats[s].stack=t.stacks[n])}),Dc(this.models,t),this.map.forEach((s,n)=>{let o=this.seats[s];if(!o||o.bot)return;let a=t.stacks[n]-t.start[n];o.leaving||(o.connected?this.emit("settle",s,a,t):o.pendingNet+=a,o.stack===0&&this.emit("busted",s))}),this.opts.autoNextMs&&(this.deadline=Date.now()+this.opts.autoNextMs,this.timers.next=setTimeout(()=>{delete this.timers.next,this.maybeStart()},this.opts.autoNextMs)),this.changed()}act(t,s){let n=this.hand;if(!n||n.over||this.map[n.toAct]!==t||!s)return!1;let o=["fold","check","call","raise"].includes(s.type)?s.type:null;if(!o)return!1;try{n.act(n.toAct,o==="raise"?{type:o,to:Number(s.to)||0}:{type:o})}catch{return!1}return this.afterAction(),!0}setReady(t){!this.hand||!this.hand.over||(this.ready.add(t),this.checkReady())}everyoneReady(){return this.seats.every((t,s)=>!t||t.bot||!t.connected||t.leaving||this.ready.has(s))}checkReady(){this.hand&&this.hand.over&&!this.revealing()&&this.everyoneReady()&&(clearTimeout(this.timers.next),delete this.timers.next,this.maybeStart())}say(t,s){let n=this.seats[t];s=String(s||"").replace(/[\x00-\x1f\x7f]/g,"").trim().slice(0,120),!(!n||!s)&&(this.chat.push({name:n.name,text:s}),this.chat=this.chat.slice(-6),this.changed())}takePending(t){let s=this.seats[t];if(!s||s.bot)return 0;let n=s.pendingNet;return s.pendingNet=0,n}note(t){this.notes.push(t),this.notes=this.notes.slice(-4)}start(){this.maybeStart(),this.changed()}close(){this.closed=!0,this.clearTimers(),this.removeAllListeners()}clearTimers(){for(let t of Object.keys(this.timers))clearTimeout(this.timers[t]),delete this.timers[t];this.deadline=0}changed(){this.closed||this.emit("change")}view(t){let s=this.hand,n=this.revealing(),o={you:t,handNo:this.handNo,blinds:[_c,Pc],deadline:this.deadline?Math.max(0,this.deadline-Date.now()):0,waitingNext:!!(s&&s.over&&!n&&!this.ready.has(t)),started:this.started,notes:this.notes.slice(),chat:this.chat.slice(),seats:this.seats.map(h=>h&&{name:h.name,stack:h.stack,bot:!!h.bot,style:h.style?h.style.label:"",connected:h.bot||h.connected,leaving:!!h.leaving}),hand:null};if(!s)return o;let a=this.map.indexOf(t),r=s.over&&s.result.showdown&&!n,c=h=>h===a||!s.folded[h]&&(r||s.runout),u=s.log;if(n){let h=[3,4,5].filter(l=>l>s.runoutFrom.board&&l<=this.shown).length;u=s.log.slice(0,s.runoutFrom.log+h)}return o.hand={n:s.n,map:this.map.slice(),me:a,button:s.button,sb:s.sb,bb:s.bb,toAct:s.over?-1:s.toAct,street:s.street,over:s.over,revealing:n,runout:!!s.runout,board:s.board.slice(0,this.shown),pot:s.over?s.pot:s.totalPot,maxBet:s.maxBet,bets:s.bets.slice(),committed:s.committed.slice(),start:s.start.slice(),folded:s.folded.slice(),allIn:s.folded.map((h,l)=>s.allIn(l)),stacks:s.stacks.map((h,l)=>n?s.start[l]-s.committed[l]:h),hole:s.hole.map((h,l)=>c(l)?h.slice():null),actions:s.actions.map(h=>({seat:h.seat,street:h.street,type:h.type,to:h.to,amount:h.amount,allIn:h.allIn,reraise:h.reraise})),log:u.slice(-8),legal:!s.over&&s.toAct===a?s.legal(a):null,result:s.over&&!n?{showdown:s.result.showdown,won:s.result.won.slice(),winners:s.result.winners.slice(),pots:s.result.pots.map(h=>({amount:h.amount,winners:h.winners.slice()})),best:r?Object.fromEntries(Object.entries(s.result.best).map(([h,l])=>[h,{score:l.score,cards:l.cards.slice()}])):{}}:null},o}};nr.exports={Table:Dn,SEATS:ct,MIN_BUYIN:_n,MAX_BUYIN:Pn,LAYOUT:qn}});var Kn=pe((Yl,cr)=>{"use strict";var rr=require("net"),Fc=require("os"),Ls=2,ar={holdem:"Texas Hold'em",blackjack:"Blackjack"},jn=6769,Gc=64*1024;function ir(e,t){let s="";e.setEncoding("utf8"),e.on("data",n=>{if(s+=n,s.length>Gc){e.destroy();return}let o;for(;(o=s.indexOf(`
|
|
20
|
+
`))>=0;){let a=s.slice(0,o);if(s=s.slice(o+1),!a.trim())continue;let r;try{r=JSON.parse(a)}catch{continue}r&&typeof r=="object"&&t(r)}})}var Ee=(e,t)=>{!e.destroyed&&e.writable&&e.write(JSON.stringify(t)+`
|
|
21
|
+
`)},Hc=/vethernet|wsl|hyper-v|docker|virtualbox|vmware|vbox|loopback|bluetooth/i,Qc=/vpn|tun|tap|wireguard|zerotier|sdp|anyconnect|fortinet|globalprotect/i;function Jc(){let e=[];for(let[t,s]of Object.entries(Fc.networkInterfaces()))if(!Hc.test(t))for(let n of s||[]){if(n.family!=="IPv4"||n.internal||n.address.startsWith("169.254."))continue;let o=t,a=1;n.address.startsWith("100.")?(o="Tailscale",a=0):(Qc.test(t)||n.netmask==="255.255.255.252"||n.netmask==="255.255.255.255")&&(o=`${t}, VPN`,a=2),e.push({address:n.address,label:o,rank:a})}return e.sort((t,s)=>t.rank-s.rank)}function Uc(e,{game:t="holdem",port:s=jn,onListening:n,onError:o}={}){let a=new Set,r=!1,c=()=>{r||(r=!0,setImmediate(()=>{r=!1;for(let l of a)l.person&&Ee(l.sock,{t:"view",view:e.view(e.seatOf(l.person))})}))},u=l=>[...a].find(f=>f.person&&e.seatOf(f.person)===l),h=rr.createServer(l=>{let f={sock:l,person:null,left:!1};a.add(f),l.setNoDelay(!0),l.on("error",()=>{});let d=setTimeout(()=>{f.person||l.destroy()},1e4);ir(l,x=>{if(!f.person){if(x.t!=="hello")return l.destroy();if(clearTimeout(d),x.v!==Ls)return Ee(l,{t:"error",msg:`version mismatch (host protocol ${Ls}, yours ${x.v}) \u2014 update your arcade`}),l.end();if(x.game!==t)return Ee(l,{t:"error",msg:`this is a ${ar[t]} table \u2014 open ${ar[t]} to join it`}),l.end();try{f.person=e.addPerson(x.name,x.buyin)}catch(k){return Ee(l,{t:"error",msg:k.message}),l.end()}Ee(l,{t:"welcome",name:f.person.name});let g=e.takePending(e.seatOf(f.person));g&&Ee(l,{t:"settle",net:g,pot:0}),c();return}let m=e.seatOf(f.person);switch(x.t){case"act":e.act(m,x.action);break;case"ready":e.setReady(m);break;case"chat":e.say(m,x.text);break;case"rebuy":e.rebuy(m,x.buyin);break;case"leave":f.left=!0,e.removePerson(m),l.end();break}}),l.on("close",()=>{a.delete(f),f.person&&!f.left&&e.seatOf(f.person)>=0&&e.disconnect(e.seatOf(f.person))})});return e.on("change",c),e.on("settle",(l,f,d)=>{let x=u(l);x&&Ee(x.sock,{t:"settle",net:f,pot:d.pot})}),e.on("busted",l=>{let f=u(l);f&&Ee(f.sock,{t:"busted"})}),h.on("error",l=>o&&o(l)),h.listen(s,"0.0.0.0",()=>n&&n(h.address().port)),{port:()=>h.address()?h.address().port:s,players:()=>[...a].filter(l=>l.person).length,close(l="The host closed the table."){for(let f of a)Ee(f.sock,{t:"closed",msg:l}),f.sock.end();h.close()}}}function Yc(e,{game:t="holdem",name:s,buyin:n},{onMessage:o,onClose:a}){let r=/^\s*\[?([^\]]+?)\]?(?::(\d+))?\s*$/.exec(String(e||"")),c=r?r[1]:"",u=r&&r[2]?+r[2]:jn,h=!1,l="",f=rr.connect({host:c,port:u});return f.setNoDelay(!0),f.setTimeout(8e3,()=>{h||(l=`couldn't reach ${c}:${u} (timed out)`,f.destroy())}),f.on("connect",()=>{f.setTimeout(0),Ee(f,{t:"hello",v:Ls,game:t,name:s,buyin:n})}),ir(f,d=>{(d.t==="error"||d.t==="closed")&&(l=d.msg),o(d)}),f.on("error",d=>{l=l||(d.code==="ECONNREFUSED"?`nobody is hosting on ${c}:${u}`:d.code==="ENOTFOUND"?`unknown host "${c}"`:d.message)}),f.on("close",()=>{h||(h=!0,a(l||"disconnected from the host"))}),{send:d=>Ee(f,d),close(){h=!0,f.end(),setTimeout(()=>f.destroy(),500)}}}cr.exports={PROTOCOL:Ls,PORT:jn,hostTable:Uc,joinTable:Yc,addresses:Jc}});var Tr=pe((Vl,Ar)=>{"use strict";var Xc=require("os"),Ve=tt(),{RESET:L,BOLD:q,DIM:Fn,fg:xr,bg:Ps,C:b,visLen:qs,Line:Ie,button:se,draw:Jn}=Ve,{save:We,persist:Vn,wallet:X,START_CHIPS:Vc}=Et(),cs=gt(),{cardRows:Gn,cardsRows:lr,mini:ur,BLACK:zc}=In(),{STREETS:Zc}=Bn(),{newModel:Xl}=Nn(),{Table:pr,MIN_BUYIN:Se,MAX_BUYIN:el}=or(),{PORT:mr,hostTable:tl,joinTable:sl,addresses:nl}=Kn(),ol=()=>{try{return Xc.userInfo().username.slice(0,14)}catch{return"Player"}},p={screen:"lobby",name:We.holdem.name||ol(),addr:We.holdem.addr||"",port:We.holdem.port||mr,bots:Math.max(0,Math.min(5,We.holdem.bots??5)),fast:!!We.holdem.fast,buyin:Math.min(1e3,Math.max(Se,X.chips)),message:"",input:null,ctrl:null,raiseTo:0,turnKey:"",busted:!1},At=We.holdem.models||{};We.holdem.model&&!At.You&&(At.You=We.holdem.model);var br=()=>We.holdem.stats={hands:0,won:0,net:0,biggestPot:0,...We.holdem.stats};function Ye(){Object.assign(We.holdem,{name:p.name,addr:p.addr,port:p.port,bots:p.bots,fast:p.fast}),Vn("holdem")}var $r=new Set(Object.keys(At));function al(){let e={};for(let[t,s]of Object.entries(At))s.hands&&$r.has(t)&&(e[t]=s);We.holdem.models=e,delete We.holdem.model,Vn("holdem")}function Xe(){p.buyin=Math.max(Se,Math.min(el,X.chips,p.buyin))}function zn(e,t){e&&X.adjust(e);let s=br();s.hands++,e>0&&s.won++,s.net+=e,t>s.biggestPot&&(s.biggestPot=t),Vn("holdem")}function gr(e,t,s,n=null){let o=()=>e.seatOf(t);return e.on("change",()=>{for(let a of e.seats)a&&!a.bot&&$r.add(a.name);Ve.render()}),e.on("settle",(a,r,c)=>{a===o()&&zn(r,c.pot),al()}),e.on("busted",a=>{a===o()&&(p.busted=!0)}),{mode:s,server:n,view:()=>e.view(o()),viewAge:()=>0,act:a=>e.act(o(),a),ready:()=>e.setReady(o()),say:a=>e.say(o(),a),rebuy:a=>{e.rebuy(o(),a)&&(p.busted=!1)},begin:()=>e.begin(),bots:a=>{e.setBots(e.opts.bots+a),p.bots=e.opts.bots,Ye()},close(){n&&n.close(),e.removePerson(o()),e.close()}}}function yr(){if(p.ctrl)return;if(X.sync(),Xe(),X.chips<Se){p.message=`${b.bad}You need at least ${Se} chips to sit down.`;return}let e=new pr({bots:Math.max(1,p.bots),botStack:p.buyin,fast:p.fast,models:At}),t=e.addPerson("You",p.buyin);p.ctrl=gr(e,t,"solo"),to(),e.start()}function Zn(){if(p.ctrl)return;if(X.sync(),Xe(),X.chips<Se){p.message=`${b.bad}You need at least ${Se} chips to host.`;return}let e=new pr({bots:p.bots,botStack:p.buyin,fast:p.fast,turnMs:3e4,autoNextMs:8e3,models:At,waitForStart:!0}),t=e.addPerson(p.name,p.buyin),s=tl(e,{port:p.port,onError:n=>{ut(!0),p.message=`${b.bad}Couldn't host on port ${p.port}: ${n.code==="EADDRINUSE"?"something else is using it":n.message}`,Ve.render()}});p.ctrl=gr(e,t,"host",s),to(),e.start()}function eo(e){if(p.ctrl)return;if(X.sync(),Xe(),X.chips<Se){p.message=`${b.bad}You need at least ${Se} chips to join.`;return}if(!e){p.message=`${b.bad}Enter the host's address first (J).`;return}p.addr=e,Ye();let t=null,s=0,n=!1,o=!1;p.message=`${b.accent}Connecting to ${e}\u2026`;let a=sl(e,{name:p.name,buyin:p.buyin},{onMessage(r){r.t==="welcome"?(n=!0,p.name=r.name):r.t==="view"?(t=r.view,s=Date.now(),n&&p.screen!=="table"&&to()):r.t==="settle"?zn(r.net,r.pot):r.t==="busted"&&(p.busted=!0),Ve.render()},onClose(r){o||(p.ctrl&&p.ctrl.conn===a&&(so(t),p.ctrl=null,p.screen="lobby"),p.message=`${b.bad}${r}`,Ve.render())}});p.ctrl={mode:"join",conn:a,view:()=>t,viewAge:()=>Date.now()-s,act:r=>a.send({t:"act",action:r}),ready:()=>a.send({t:"ready"}),say:r=>a.send({t:"chat",text:r}),rebuy:r=>{a.send({t:"rebuy",buyin:r}),p.busted=!1},close(){o=!0,a.send({t:"leave"}),a.close()}}}function to(){p.screen="table",p.message="",p.busted=!1,p.turnKey=""}function so(e){let t=e&&e.hand;t&&!t.over&&t.me>=0&&t.committed[t.me]>0&&zn(-t.committed[t.me],t.pot)}function ut(e=!1){let t=p.ctrl;if(!t){p.screen="lobby";return}let s=t.view();if(s&&s.hand&&s.hand.revealing){p.message="Let the board finish first.";return}so(s),p.ctrl=null,t.close(),p.screen="lobby",e||(p.message=t.mode==="host"?`${b.muted}Table closed.`:"")}var Nt=()=>p.ctrl?p.ctrl.view():null;function no(){let e=Nt();return e&&e.hand&&e.hand.legal}function Lt(e){let t=no();t&&(e==="checkcall"&&(e=t.canCheck?"check":"call"),e==="fold"&&t.canCheck&&(e="check"),!(e==="raise"&&!t.canRaise)&&p.ctrl.act(e==="raise"?{type:e,to:p.raiseTo}:{type:e}))}function Ue(e){let t=no();t&&(p.raiseTo=Math.max(t.minTo,Math.min(t.maxTo,p.raiseTo+e)))}function _e(e){let t=Nt(),s=no();if(!s)return;let n=t.hand,o=e===1/0?s.maxTo:Math.round((n.maxBet+e*(n.pot+s.toCall))/10)*10;p.raiseTo=Math.max(s.minTo,Math.min(s.maxTo,o))}function wr(){let e=Nt();e&&e.hand&&e.hand.over&&!e.hand.revealing&&p.ctrl.ready()}function kr(){if(X.sync(),Xe(),X.chips<Se){p.message=`${b.bad}Not enough chips in your wallet to rebuy.`;return}p.ctrl.rebuy(p.buyin)}function oo(e,t,s,n){p.input={label:e,value:t,max:s,onDone:n}}var hr=Ps(22,92,58),Wr=82,is=23,lt=xr(200,230,210),Ns=xr(255,230,140),dr=e=>cs.CATEGORY[cs.scoreParts(e).cat].toLowerCase();function Ne(e=""){let t=Math.max(0,Wr-2-qs(e));return hr+" "+e.split(L).join(L+hr)+" ".repeat(t)+" "+L}var _s=(e,t)=>e+" ".repeat(Math.max(0,t-qs(e))),Hn=(e,t)=>_s(" ".repeat(Math.max(0,Math.floor((t-qs(e))/2)))+e,t),Un=e=>Math.ceil(Math.max(0,e.deadline-p.ctrl.viewAge())/1e3);function fr(e,t){let s=[...e.actions].reverse().find(n=>n.seat===t);return!s||s.type==="blind"?"":s.type==="fold"?"folded":s.street!==e.street&&!e.over?"":s.allIn?"ALL-IN":s.type==="raise"?`${s.street===0||s.reraise?"raise":"bet"} ${s.to}`:s.type==="call"?`call ${s.amount}`:s.type}function Sr(e,t){let s="";return e.button===t&&(s+=` ${Ps(240,240,240)}${zc}${q} D ${L}`),e.n>2&&e.sb===t&&(s+=` ${b.muted}SB`),e.bb===t&&(s+=` ${b.muted}BB`),s}function Qn(e,t){let s=e.seats[t];if(!s)return["",` ${b.muted}${Fn}empty seat`,"",""].map(m=>_s(m,is));let n=e.hand,o=n?n.map.indexOf(t):-1,a=o>=0&&!n.over&&n.toAct===o,r=a?Ps(240,196,64)+b.dark+q:(s.bot?b.text:b.accent)+q,c=s.connected?s.leaving?` ${b.muted}leaving`:"":` ${b.bad}offline`,u=`${a?`${b.title}\u25B6`:" "}${r}${s.name}${L}${o>=0?Sr(n,o):""}${c}`,h=s.bot?s.style:"player",l=a&&e.deadline&&!s.bot?` ${b.title}\u23F1 ${Un(e)}s`:"",f=` ${lt}${o>=0?n.stacks[o]:s.stack}${L} ${b.muted}${Fn}${h}${L}${l}`,d="",x="";if(o<0)d=` ${b.muted}${e.started?s.stack?"next hand":"sitting out":"ready"}`;else if(n.folded[o])d=` ${b.muted}${Fn}\u2591\u2591\u2591 \u2591\u2591\u2591`;else{let m=n.result,g=m&&m.showdown&&m.winners.includes(o)?new Set(m.best[o].cards):null;d=" "+[0,1].map(k=>n.hole[o]?ur(n.hole[o][k],{hi:g&&g.has(n.hole[o][k])}):ur(0,{hidden:!0})).join(" ")}if(o>=0){let m=n.result;m&&m.won[o]>0?x=` ${b.good}${q}+${m.won[o]}${L}${m.showdown?` ${lt}${dr(m.best[o].score)}`:""}`:m&&m.showdown&&!n.folded[o]?x=` ${b.muted}${dr(m.best[o].score)}`:n.bets[o]?x=` ${Ns}\u25CF ${n.bets[o]}${L} ${b.muted}${fr(n,o)}`:x=` ${b.muted}${fr(n,o)}`}return[u,f,d,x].map(m=>_s(m,is))}function rl(e){let t=e.hand,s=t.result,n=r=>r===t.me?"You":e.seats[t.map[r]]?e.seats[t.map[r]].name:"?",a=s.pots.map((r,c)=>{let u=r.winners.map(n).join(" & "),h=s.pots.length===1?"":c===0?"main ":`side ${c} `,l=s.showdown?` \u2014 ${cs.handName(s.best[r.winners[0]].score)}`:"",f=r.winners.length>1?"split":r.winners[0]===t.me?"win":"wins";return`${r.winners.includes(t.me)?b.good:b.title}${q}${u}${L}${b.text} ${f} ${h}${r.amount}${l}`}).join(`${b.muted} \xB7 `);if(t.me>=0){let r=t.stacks[t.me]-t.start[t.me];r>0?a+=` ${b.good}${q}+${r}`:r<0&&(a+=` ${b.bad}${r}`)}return a}function il(){let e=p.ctrl.server?p.ctrl.server.port():p.port,[t,...s]=nl();if(!t)return`${b.bad}No network connection found \u2014 friends can't reach this table.`;let n=e===mr?"":`:${e}`,o=s.length?`${b.muted} other: ${s.map(a=>`${a.address}${n} (${a.label})`).join(", ")}`:"";return`${b.muted}Friends join with ${b.title}${q}holdem join ${t.address}${n}${L}${b.muted} (${t.label})${o}`}function cl(){let e=Nt();if(!e){Jn(["",`${b.accent}Connecting\u2026`]);return}let t=e.hand,s=Wr-2,n=[],o=p.ctrl.mode==="host"?`${b.good}hosting`:p.ctrl.mode==="join"?`${b.accent}online`:`${b.muted}solo`,a=e.seats.filter(Boolean).length;n.push(`${b.title}${q}TEXAS HOLD'EM${L} ${o}${L} ${b.muted}${a} seated \xB7 blinds ${e.blinds.join("/")} \xB7 hand #${e.handNo} wallet ${b.text}${X.chips}`),n.push(p.ctrl.mode==="host"?il():""),n.push(Ne());let r=e.you>=0?e.you:0,c=W=>(W+r)%6,u=[2,3,4].map(W=>Qn(e,c(W))),h=Math.floor((s-3*is)/2);for(let W=0;W<4;W++)n.push(Ne(u[0][W]+" ".repeat(h)+u[1][W]+" ".repeat(s-3*is-h)+u[2][W]));n.push(Ne());let l=Qn(e,c(1)),f=Qn(e,c(5)),d=s-2*is,x;if(t){let W=t.result,v=W&&W.showdown?new Set(W.winners.flatMap(H=>W.best[H].cards)):new Set,T=[];for(let H=0;H<5;H++)T.push(H<t.board.length?Gn(t.board[H],{hi:v.has(t.board[H])}):Gn(0,{empty:!0}));let G;W&&W.pots.length>1?G=W.pots.map((H,ee)=>`${Ns}${q}${ee?`side ${ee}`:"main"} ${H.amount}${L}`).join(`${lt} \xB7 `):G=`${Ns}${q}Pot ${t.pot}${L}${lt} ${t.revealing?"All-in":t.over?W&&W.showdown?"Showdown":"":Zc[t.street]||""}`,x=[...lr(T),G]}else if(e.started)x=["",`${lt}Waiting for players\u2026`,p.ctrl.mode==="host"?`${b.muted}a hand starts when someone joins`:"",""];else{let W=e.seats.filter(T=>T&&!T.bot).length,v=e.seats.filter(T=>T&&T.bot).length;x=[`${b.title}${q}WAITING ROOM`,`${lt}${W} player${W===1?"":"s"} \xB7 ${v} bot${v===1?"":"s"}`,p.ctrl.mode==="host"?`${b.muted}start when everyone's in`:`${b.muted}the host starts the game`,""]}for(let W=0;W<4;W++)n.push(Ne(l[W]+Hn(x[W],d)+f[W]));n.push(Ne());let m=t?t.me:-1,g=e.seats[e.you];if(m>=0){let W=t.result,v=W&&W.showdown&&W.winners.includes(m)?new Set(W.best[m].cards):null,T=lr(t.hole[m].map(ie=>Gn(ie,{hi:v&&v.has(ie)}))),G=!t.over&&t.toAct===m,H=t.board.length>=3?cs.handName(cs.bestHand(t.hole[m].concat(t.board)).score):"",ee=G&&e.deadline?` ${b.title}\u23F1 ${Un(e)}s`:"",ne=[`${G?`${b.title}${q}\u25B6 `:" "}${b.accent}${q}${g?g.name:"You"}${L}${Sr(t,m)} ${lt}stack ${q}${t.stacks[m]}${L}${t.bets[m]?` ${Ns}\u25CF ${t.bets[m]}`:""}${ee}`,` ${t.folded[m]?`${b.muted}folded`:`${lt}${H}`}`,` ${t.allIn[m]&&!t.over?`${b.bad}${q}ALL-IN`:""}`],te=qs(T[0])+3+40;for(let ie=0;ie<3;ie++)n.push(Ne(Hn(_s(T[ie]+" "+ne[ie],te),s)))}else{let W=g?e.started?g.stack===0?"You're out of chips: rebuy or leave.":"You're in from the next hand.":"You're seated.":"Waiting for a seat \u2014 a bot will make room after this hand.";n.push(Ne(),Ne(Hn(`${b.muted}${W}`,s)),Ne())}n.push(Ne()),n.push("");let k=t&&t.legal;if(k&&p.turnKey!==`${e.handNo}:${t.actions.length}`&&(p.turnKey=`${e.handNo}:${t.actions.length}`,p.raiseTo=k.minTo),e.started)if(p.busted||g&&g.stack===0&&!(t&&t.me>=0&&!t.over)){n.push(`${b.bad}${q}You're out of chips at this table.`,"");let W=new Ie;se(W,`Rebuy ${p.buyin}`,kr,{hot:!0,enabled:X.chips>=Se}),se(W,"Leave table",()=>ut()),n.push(W,"")}else if(t&&t.over){t.revealing?n.push(`${b.accent}All-in \u2014 running out the board\u2026`,""):n.push(`${b.text}${rl(e)}`,e.deadline?`${b.muted}next hand in ${Un(e)}s`:"");let W=new Ie,v=!t.revealing;se(W,e.waitingNext?"Next hand":"Waiting for others\u2026",wr,{enabled:v&&e.waitingNext,hot:v&&e.waitingNext}),se(W,p.ctrl.mode==="host"?"Close table":"Leave table",()=>ut(),{enabled:v}),n.push(W,"")}else if(k){n.push(`${b.text}Your move${k.toCall?` \u2014 ${b.title}${k.toCall}${b.text} to call`:""}.`,"");let W=new Ie;if(se(W,"Fold",()=>Lt("fold"),{enabled:!k.canCheck}),se(W,k.canCheck?"Check":`Call ${k.toCall}${k.toCall===t.stacks[m]?" (all-in)":""}`,()=>Lt("checkcall"),{hot:!0}),k.canRaise&&se(W,p.raiseTo===k.maxTo?`All-in ${p.raiseTo}`:`${k.isBet?"Bet":"Raise to"} ${p.raiseTo}`,()=>Lt("raise")),n.push(W),k.canRaise){let v=new Ie(`${b.muted}size `);v.add(`${b.title}${q} \u2039 ${L}`,()=>Ue(-10),T=>Ue(-T*10)),v.add(`${b.text}${q}${String(p.raiseTo).padStart(5)}${L}`,null,T=>Ue(-T*10)),v.add(`${b.title}${q} \u203A ${L} `,()=>Ue(10),T=>Ue(-T*10)),se(v,"Min",()=>_e(0)),se(v,"\xBD pot",()=>_e(.5)),se(v,"\xBE pot",()=>_e(.75)),se(v,"Pot",()=>_e(1)),se(v,"All-in",()=>_e(1/0)),n.push(v)}else n.push("")}else{let W=t&&t.toAct>=0&&e.seats[t.map[t.toAct]]?e.seats[t.map[t.toAct]].name:"";n.push(W?`${b.muted}${W} is thinking\u2026`:"","");let v=new Ie;se(v,p.ctrl.mode==="host"?"Close table":"Leave table",()=>ut()),n.push(v,"")}else if(p.ctrl.mode==="host"){n.push(`${b.text}Friends can join now. Start the game when everyone's seated.`,"");let W=new Ie,v=e.seats.filter(T=>T).length>=2;se(W,"Start game",()=>p.ctrl.begin(),{hot:v,enabled:v}),W.add(`${b.muted}bots`),W.add(`${b.title}${q} \u2039 ${L}`,()=>p.ctrl.bots(-1)),W.add(`${b.text}${q}${e.seats.filter(T=>T&&T.bot).length}${L}`),W.add(`${b.title}${q} \u203A ${L} `,()=>p.ctrl.bots(1)),se(W,"Close table",()=>ut()),n.push(W,"")}else{n.push(`${b.text}Waiting for the host to start the game\u2026`,"");let W=new Ie;se(W,"Leave table",()=>ut()),n.push(W,"")}n.push("");let S=t?t.log.slice(-5):[];for(let W of S)n.push(`${b.muted}\xB7 ${W}`);for(let W=S.length;W<5;W++)n.push("");let A=[...e.notes.slice(-2).map(W=>`${b.muted}\xBB ${W}`),...e.chat.slice(-3).map(W=>`${b.accent}${W.name}:${L} ${b.text}${W.text}`)];for(let W of A.slice(-4))n.push(W);for(let W=A.length;W<4;W++)n.push("");n.push(p.input?`${b.title}${p.input.label}: ${b.text}${p.input.value}${b.title}\u258C`:"");let C=p.ctrl.mode==="solo"?"":` \xB7 ${b.text}T${b.muted} chat`;n.push(`${b.muted}Keys: ${b.text}C/Space${b.muted} check/call \xB7 ${b.text}F${b.muted} fold \xB7 ${b.text}R${b.muted} bet/raise \xB7 ${b.text}\u2190\u2192 \u2191\u2193${b.muted} size \xB7 ${b.text}1-5${b.muted} presets \xB7 ${b.text}N${b.muted} next hand${C} \xB7 ${b.text}Esc${b.muted} leave`),Jn(n)}function ll(){X.sync(),Xe();let e=["",`${b.title}${q}TEXAS HOLD'EM${L} ${b.muted}no-limit \xB7 blinds 5/10 \xB7 up to 6 seats`,""];e.push(`${b.text}Wallet: ${q}${X.chips}${L}${b.text} chips`,"");let t=(u,h,l,f,d="")=>{let x=new Ie(`${b.text}${u.padEnd(11)}`);x.add(`${b.title}${q} \u2039 ${L}`,l,m=>m>0?l():f()),x.add(`${b.text}${q}${String(h).padStart(6)}${L}`,f,m=>m>0?l():f()),x.add(`${b.title}${q} \u203A ${L}`,f,m=>m>0?l():f()),d&&x.add(` ${b.muted}${d}`),e.push(x)},s=(u,h,l,f)=>{let d=new Ie(`${b.text}${u.padEnd(11)}`);d.add(`${Ps(40,44,58)}${b.text} ${h||`${b.muted}\u2014`} ${L}`,f),d.add(` ${b.muted}${l}`),e.push(d)};s("Name",p.name,"E to edit (used online)",Mr),t("Bots",p.bots,()=>{p.bots=Math.max(0,p.bots-1),Ye()},()=>{p.bots=Math.min(5,p.bots+1),Ye()},p.bots===0?"people only (solo plays 1)":`${p.bots} bot${p.bots>1?"s":""} at the table`),X.chips>=Se?t("Buy-in",p.buyin,()=>{p.buyin-=100,Xe()},()=>{p.buyin+=100,Xe()},`${p.buyin/10} big blinds`):e.push(`${b.bad}You need at least ${Se} chips to play.`);let n=new Ie(`${b.text}${"Bot speed".padEnd(11)}`);n.add(`${b.title}${q} \u2039 ${L}${b.text}${q}${p.fast?" fast":"normal"}${L}${b.title}${q} \u203A ${L}`,()=>{p.fast=!p.fast,Ye()}),e.push(n),s("Join",p.addr,"J to type a host address and join",Yn),e.push("");let o=new Ie,a=X.chips>=Se;se(o,"Play vs bots",yr,{enabled:a,hot:!0}),se(o,`Host on :${p.port}`,Zn,{enabled:a}),se(o,"Join",()=>p.addr?eo(p.addr):Yn(),{enabled:a}),X.canRefill()&&se(o,`Refill to ${Vc}`,()=>X.refill()),se(o,Ve.hasLauncher()?"Arcade":"Quit",vr),e.push(o,""),p.message&&e.push(`${b.text}${p.message}`,"");let r=br();e.push(`${b.muted}hands ${r.hands} \xB7 won ${r.won} \xB7 net ${r.net>=0?"+":""}${r.net} \xB7 biggest pot ${r.biggestPot}`);let c=At.You;if(c&&c.hands>=5){let u=h=>`${Math.round(c[h]/c.hands*100)}%`;e.push(`${b.muted}The bots remember you: ${c.hands} hands, play ${u("vpip")}, raise ${u("pfr")}, shove ${u("shoves")} preflop.`)}e.push(""),e.push(`${b.muted}Host: your arcade runs the table on port ${p.port}; friends with the arcade join with`),e.push(`${b.muted}${b.text}holdem join <your address>${b.muted}. Bots fill empty seats. Over the internet use a VPN like`),e.push(`${b.muted}Tailscale (free) or forward the port. Every hand settles into each player's own wallet.`,""),e.push(p.input?`${b.title}${p.input.label}: ${b.text}${p.input.value}${b.title}\u258C${b.muted} Enter to confirm \xB7 Esc to cancel`:""),e.push(`${b.muted}Keys: ${b.text}Enter${b.muted} play vs bots \xB7 ${b.text}H${b.muted} host \xB7 ${b.text}J${b.muted} join \xB7 ${b.text}E${b.muted} name \xB7 ${b.text}\u2191\u2193${b.muted} bots \xB7 ${b.text}\u2190\u2192${b.muted} buy-in \xB7 ${b.text}S${b.muted} speed \xB7 ${b.text}F${b.muted} refill \xB7 ${b.text}Esc${b.muted} ${Ve.hasLauncher()?"arcade":"quit"}`),Jn(e)}function Mr(){oo("Your name",p.name,14,e=>{e.trim()&&(p.name=e.trim(),Ye())})}function Yn(){oo("Host address (ip or ip:port)",p.addr,60,e=>{e.trim()&&eo(e.trim())})}function vr(){p.ctrl&&ut(!0),!p.ctrl&&Ve.leave()}function ul(e,t){let s=p.input;if(e==="enter"){p.input=null,s.onDone(s.value);return}if(e==="escape"){p.input=null;return}let n=t&&t.ch;if(n==="\x7F"||n==="\b"){s.value=s.value.slice(0,-1);return}if(e==="space"){s.value.length<s.max&&(s.value+=" ");return}n&&n.length===1&&n>=" "&&s.value.length<s.max&&(s.value+=n)}var Xn={render(){p.screen==="table"&&p.ctrl?cl():ll()},onShow(){X.sync()},onQuit(){p.ctrl&&(so(p.ctrl.view()),p.ctrl.close(),p.ctrl=null)},onTick(){let e=p.screen==="table"&&Nt();e&&e.deadline&&Ve.render()},onKey(e,t){if(p.input)return ul(e,t);if(p.screen!=="table"||!p.ctrl){if(e==="escape"||e==="q")return vr();e==="left"?(p.buyin-=100,Xe()):e==="right"?(p.buyin+=100,Xe()):e==="up"?(p.bots=Math.min(5,p.bots+1),Ye()):e==="down"?(p.bots=Math.max(0,p.bots-1),Ye()):e==="s"?(p.fast=!p.fast,Ye()):e==="enter"||e==="space"?yr():e==="h"?Zn():e==="j"?Yn():e==="e"?Mr():e==="f"&&X.canRefill()&&X.refill();return}if(e==="escape"||e==="q")return ut();if(e==="t"&&p.ctrl.mode!=="solo")return oo("Say","",120,n=>{n.trim()&&p.ctrl.say(n)});let s=Nt();if(s&&!s.started){p.ctrl.mode==="host"&&(e==="enter"||e==="space"||e==="s"?p.ctrl.begin():e==="up"||e==="right"?p.ctrl.bots(1):(e==="down"||e==="left")&&p.ctrl.bots(-1));return}if(p.busted||s.seats[s.you]&&s.seats[s.you].stack===0){e==="r"&&kr();return}if(s.hand&&s.hand.over){(e==="n"||e==="enter"||e==="space")&&wr();return}switch(e){case"c":case"space":Lt("checkcall");break;case"f":Lt("fold");break;case"r":case"b":Lt("raise");break;case"left":Ue(-10);break;case"right":Ue(10);break;case"down":case"pagedown":Ue(-100);break;case"up":case"pageup":Ue(100);break;case"1":_e(0);break;case"2":_e(.5);break;case"3":_e(.75);break;case"4":_e(1);break;case"5":_e(1/0);break}}};function hl(e){let t=o=>{let a=e.indexOf(o);return a>=0?e[a+1]:void 0};t("--name")&&(p.name=t("--name").slice(0,14)),t("--buyin")&&(p.buyin=+t("--buyin")||p.buyin);let[s,n]=e.filter((o,a)=>!o.startsWith("--")&&!(a>0&&e[a-1].startsWith("--")));s==="host"?(n&&+n&&(p.port=+n),Xn.onShow=()=>{X.sync(),p.ctrl||Zn()}):s==="join"&&n&&(Xn.onShow=()=>{X.sync(),p.ctrl||eo(n)})}Ar.exports={name:"Texas Hold'em",screen:Xn,configure:hl}});var Ir=pe((zl,Er)=>{"use strict";var us=gt(),Rr=6,dl=.75,Cr=4,ao=class{constructor(t=Math.random,s=Rr){this.rng=t,this.decks=s,this.shuffle()}shuffle(){this.cards=[];for(let t=0;t<this.decks;t++)this.cards.push(...us.shuffledDeck(this.rng));for(let t=this.cards.length-1;t>0;t--){let s=Math.floor(this.rng()*(t+1));[this.cards[t],this.cards[s]]=[this.cards[s],this.cards[t]]}this.size=this.cards.length}draw(){return this.cards.pop()}get used(){return 1-this.cards.length/this.size}get needsShuffle(){return this.used>=dl}},ls=e=>{let t=us.rankOf(e);return t===14?11:Math.min(10,t)};function Pe(e){let t=0,s=0;for(let n of e)t+=ls(n),us.rankOf(n)===14&&s++;for(;t>21&&s;)t-=10,s--;return{total:t,soft:s>0}}var Ds=e=>e.cards.length===2&&!e.split&&Pe(e.cards).total===21,ro=class{constructor(t,s){this.shoe=s,this.players=t.map(n=>({id:n.id,stack:n.stack,start:n.stack+n.bet,insurance:0,insured:null,hands:[{cards:[],bet:n.bet,doubled:!1,split:!1,splitAces:!1,done:!1,result:null,paid:0}]})),this.dealer={cards:[]},this.order=[];for(let n=0;n<2;n++){for(let o of this.players)this.deal(o.hands[0].cards,{player:o.id});this.deal(this.dealer.cards,{dealer:!0,hole:n===1})}this.turn=null,this.phase=this.upcard()===14?"insurance":"peek",this.phase==="peek"&&this.peek()}deal(t,s){let n=this.shoe.draw();return t.push(n),this.order.push({card:n,...s}),n}upcard(){return us.rankOf(this.dealer.cards[0])}player(t){return this.players.find(s=>s.id===t)}insure(t,s){let n=this.player(t);if(this.phase!=="insurance"||!n||n.insured!==null)return!1;let o=Math.floor(n.hands[0].bet/2);return s&&n.stack<o?!1:(n.insured=!!s,s&&(n.insurance=o,n.stack-=o),this.players.every(a=>a.insured!==null)&&(this.phase="peek",this.peek()),!0)}peek(){let t=ls(this.dealer.cards[0]);if((t===11||t===10)&&Pe(this.dealer.cards).total===21)return this.dealerBJ=!0,this.finish();for(let s of this.players)Ds(s.hands[0])&&(s.hands[0].done=!0);this.phase="play",this.nextTurn()}nextTurn(){for(let s=0;s<this.players.length;s++){let n=this.players[s].hands;for(let o=0;o<n.length;o++)if(!n[o].done){if(n[o].cards.length===1&&this.deal(n[o].cards,{player:this.players[s].id}),n[o].splitAces||Pe(n[o].cards).total>=21){n[o].done=!0;continue}this.turn={p:s,h:o};return}}this.turn=null;let t=this.players.some(s=>s.hands.some(n=>Pe(n.cards).total<=21&&!Ds(n)));this.phase=t?"dealer":"settle",t||this.finish()}current(){if(!this.turn)return null;let t=this.players[this.turn.p];return{player:t,hand:t.hands[this.turn.h]}}legal(t){let s=this.current();if(this.phase!=="play"||!s||s.player.id!==t)return null;let{player:n,hand:o}=s,a=o.cards.length===2;return{hit:!0,stand:!0,double:a&&!o.splitAces&&n.stack>=o.bet,split:a&&ls(o.cards[0])===ls(o.cards[1])&&n.hands.length<Cr&&n.stack>=o.bet}}act(t,s){let n=this.legal(t);if(!n||!n[s])return!1;let{player:o,hand:a}=this.current();switch(s){case"hit":this.deal(a.cards,{player:t}),Pe(a.cards).total>=21&&(a.done=!0);break;case"stand":a.done=!0;break;case"double":o.stack-=a.bet,a.bet*=2,a.doubled=!0,this.deal(a.cards,{player:t}),a.done=!0;break;case"split":{o.stack-=a.bet;let r=us.rankOf(a.cards[0])===14,c={cards:[a.cards.pop()],bet:a.bet,doubled:!1,split:!0,splitAces:r,done:!1,result:null,paid:0};a.split=!0,a.splitAces=r,o.hands.splice(this.turn.h+1,0,c),this.deal(a.cards,{player:t}),(r||Pe(a.cards).total>=21)&&(a.done=!0);break}}return a.done&&this.nextTurn(),!0}dealerStep(){return this.phase!=="dealer"?!1:Pe(this.dealer.cards).total<17?(this.deal(this.dealer.cards,{dealer:!0}),!0):(this.finish(),!1)}finish(){this.phase="done",this.turn=null;let t=Pe(this.dealer.cards).total,s=this.dealerBJ||this.dealer.cards.length===2&&t===21;for(let n of this.players){n.insurance&&s&&(n.stack+=n.insurance*3);for(let o of n.hands){let a=Pe(o.cards).total,r=Ds(o),c=0;r&&!s?(o.result="blackjack",c=o.bet+Math.floor(o.bet*1.5)):s?(o.result=r?"push":"lose",c=r?o.bet:0):a>21?o.result="bust":t>21||a>t?(o.result="win",c=o.bet*2):a===t?(o.result="push",c=o.bet):o.result="lose",o.paid=c,n.stack+=c}n.net=n.stack-n.start}}committed(t){let s=this.player(t);return s?s.hands.reduce((n,o)=>n+o.bet,0)+s.insurance:0}};Er.exports={Shoe:ao,Round:ro,total:Pe,value:ls,isBlackjack:Ds,DECKS:Rr,MAX_HANDS:Cr}});var Br=pe((Zl,Or)=>{"use strict";var fl=require("events"),{Shoe:xl,Round:pl,total:io}=Ir(),co=5,_t=10,lo=500,uo=100,ho=5e3,ml=3,fo=class extends fl{constructor(t={}){super(),this.opts={betMs:0,turnMs:0,autoNextMs:0,dealMs:260,dealerMs:700,rng:Math.random,...t},this.seats=new Array(co).fill(null),this.shoe=new xl(this.opts.rng),this.phase="betting",this.round=null,this.ids=[],this.dealt=0,this.roundNo=0,this.notes=[],this.chat=[],this.ready=new Set,this.timers={},this.deadline=0,this.closed=!1}addPerson(t,s){t=String(t||"").trim().slice(0,14)||"Player";let n=this.seats.find(r=>r&&r.name.toLowerCase()===t.toLowerCase());if(n){if(n.connected)throw new Error(`the name "${t}" is taken at this table`);return n.connected=!0,n.away=0,this.note(`${n.name} reconnected`),this.changed(),n}let o=this.seats.findIndex(r=>!r);if(o<0)throw new Error("the table is full");s=Math.max(uo,Math.min(ho,Math.floor(s)||0));let a={name:t,stack:s,connected:!0,away:0,pendingNet:0,bet:Math.min(50,s),confirmed:!1,lastBet:50};return this.seats[o]=a,this.note(`${t} sits down`),this.changed(),a}seatOf(t){return this.seats.indexOf(t)}inRound(t){return this.round&&this.phase!=="results"&&this.ids.includes(t)}removePerson(t){let s=this.seats[t];s&&(this.note(`${s.name} leaves`),this.inRound(t)?(s.leaving=!0,s.connected=!1,this.autoForAbsent()):this.seats[t]=null,this.changed(),this.checkBets(),this.checkReady())}disconnect(t){let s=this.seats[t];s&&(s.connected=!1,this.note(`${s.name} disconnected`),this.autoForAbsent(),this.changed(),this.checkBets(),this.checkReady())}rebuy(t,s){let n=this.seats[t];return!n||n.stack>=_t||this.inRound(t)?!1:(n.stack=Math.max(uo,Math.min(ho,Math.floor(s)||0)),n.bet=Math.min(n.lastBet,n.stack),this.note(`${n.name} buys in for ${n.stack}`),this.changed(),!0)}takePending(t){let s=this.seats[t];if(!s)return 0;let n=s.pendingNet;return s.pendingNet=0,n}say(t,s){let n=this.seats[t];s=String(s||"").replace(/[\x00-\x1f\x7f]/g,"").trim().slice(0,120),!(!n||!s)&&(this.chat.push({name:n.name,text:s}),this.chat=this.chat.slice(-6),this.changed())}note(t){this.notes.push(t),this.notes=this.notes.slice(-4)}bettors(){return this.seats.map((t,s)=>t&&t.connected&&!t.leaving&&t.stack>=_t?s:-1).filter(t=>t>=0)}checkBets(){if(this.phase!=="betting"||this.closed)return;let t=this.bettors(),s=t.filter(n=>this.seats[n].confirmed);if(!s.length){clearTimeout(this.timers.bet),delete this.timers.bet,this.deadline=0;return}if(s.length===t.length)return this.startRound();this.opts.betMs&&!this.timers.bet&&(this.deadline=Date.now()+this.opts.betMs,this.timers.bet=setTimeout(()=>{delete this.timers.bet,this.startRound()},this.opts.betMs))}startRound(){this.clearTimers();let t=this.bettors().filter(n=>this.seats[n].confirmed);if(!t.length)return this.changed();this.shoe.needsShuffle&&(this.shoe.shuffle(),this.note("New shoe \u2014 the dealer shuffles"));let s=t.map(n=>{let o=this.seats[n];return o.stack-=o.bet,o.lastBet=o.bet,{id:n,bet:o.bet,stack:o.stack}});this.ids=t,this.round=new pl(s,this.shoe),this.roundNo++,this.ready.clear(),this.dealt=0,this.phase="dealing",this.dealNext()}dealNext(){let t=this.ids.length*2+2;if(this.dealt<t){this.dealt++,this.changed(),this.timers.deal=setTimeout(()=>this.dealNext(),this.opts.dealMs);return}this.dealt=1/0,this.afterAction()}syncPhase(){let t=this.round;this.phase=t.phase==="insurance"?"insurance":t.phase==="play"?"play":t.phase==="dealer"?"dealer":"results"}afterAction(){this.clearTimers(),this.syncPhase();let t=this.round;if(this.phase==="insurance")this.autoForAbsent(),this.opts.turnMs&&this.phase==="insurance"&&(this.deadline=Date.now()+this.opts.turnMs,this.timers.turn=setTimeout(()=>{for(let s of t.players)s.insured===null&&t.insure(s.id,!1);this.afterAction()},this.opts.turnMs));else if(this.phase==="play"){let s=t.current().player.id,n=this.seats[s];!n||!n.connected||n.leaving?this.timers.turn=setTimeout(()=>{t.act(s,"stand"),this.afterAction()},300):this.opts.turnMs&&(this.deadline=Date.now()+this.opts.turnMs,this.timers.turn=setTimeout(()=>{t.act(s,"stand"),this.afterAction()},this.opts.turnMs))}else if(this.phase==="dealer")this.timers.dealer=setTimeout(()=>{t.dealerStep(),this.afterAction()},this.opts.dealerMs);else if(this.phase==="results")return this.settle();this.changed()}autoForAbsent(){let t=this.round;if(!t||this.phase==="results"||this.phase==="dealing")return;let s=!1;if(t.phase==="insurance")for(let n of t.players){let o=this.seats[n.id];n.insured===null&&(!o||!o.connected||o.leaving)&&(t.insure(n.id,!1),s=!0)}s&&this.afterAction()}settle(){let t=this.round;for(let s of t.players){let n=s.id,o=this.seats[n];o&&(o.stack=s.stack,o.confirmed=!1,!o.leaving&&(o.connected?this.emit("settle",n,s.net,t):o.pendingNet+=s.net,o.stack<_t&&this.emit("busted",n),o.bet=Math.min(o.lastBet,o.stack)))}this.opts.autoNextMs&&(this.deadline=Date.now()+this.opts.autoNextMs,this.timers.next=setTimeout(()=>this.nextRound(),this.opts.autoNextMs)),this.changed()}nextRound(){this.clearTimers();for(let t=0;t<co;t++){let s=this.seats[t];s&&(s.leaving||!s.connected&&++s.away>ml)&&(this.seats[t]=null)}this.round=null,this.ids=[],this.phase="betting",this.ready.clear(),this.changed()}setReady(t){this.phase==="results"&&(this.ready.add(t),this.checkReady())}checkReady(){this.phase==="results"&&this.seats.every((t,s)=>!t||!t.connected||t.leaving||this.ready.has(s))&&this.nextRound()}act(t,s){let n=this.seats[t];if(!n||!s||this.closed)return!1;let o=this.round;switch(s.type){case"bet":return this.phase!=="betting"||n.confirmed?!1:(n.bet=Math.max(0,Math.min(lo,n.stack,Math.floor(Number(s.amount))||0)),this.changed(),!0);case"deal":return this.phase!=="betting"||n.confirmed||n.bet<_t||n.bet>n.stack?!1:(n.confirmed=!0,this.changed(),this.checkBets(),!0);case"unbet":return this.phase!=="betting"||!n.confirmed?!1:(n.confirmed=!1,this.changed(),this.checkBets(),!0);case"insurance":return this.phase!=="insurance"||!o.insure(t,!!s.take)?!1:(this.afterAction(),!0);case"hit":case"stand":case"double":case"split":return this.phase!=="play"||!o.act(t,s.type)?!1:(this.afterAction(),!0)}return!1}start(){this.changed()}close(){this.closed=!0,this.clearTimers(),this.removeAllListeners()}clearTimers(){for(let t of Object.keys(this.timers))clearTimeout(this.timers[t]),delete this.timers[t];this.deadline=0}changed(){this.closed||this.emit("change")}view(t){let s=this.round,n=this.ids.length,o=this.phase==="dealer"||this.phase==="results",a=(l,f)=>this.dealt===1/0||this.dealt>(f===0?l:n+1+l),r={you:t,roundNo:this.roundNo,phase:this.phase,minBet:_t,maxBet:lo,deadline:this.deadline?Math.max(0,this.deadline-Date.now()):0,shoe:Math.round(this.shoe.used*100),notes:this.notes.slice(),chat:this.chat.slice(),seats:this.seats.map(l=>l&&{name:l.name,stack:l.stack,connected:l.connected,leaving:!!l.leaving,bet:l.bet,confirmed:l.confirmed}),waitingNext:this.phase==="results"&&!this.ready.has(t),dealer:null,players:{},turn:null,legal:null,insurance:!1};if(!s)return r;let c=s.dealer.cards.filter((l,f)=>f===0?a(n,0):f===1?o||!1:o);r.dealer={cards:c,hidden:!o&&a(n,1)?1:0,total:c.length?io(c).total:0,soft:c.length?io(c).soft:!1,blackjack:!!s.dealerBJ&&o},s.players.forEach((l,f)=>{r.players[l.id]={hands:l.hands.map((d,x)=>{let m=x===0&&this.dealt!==1/0?d.cards.filter((k,S)=>a(f,S)):d.cards.slice(),g=io(m);return{cards:m,bet:d.bet,doubled:d.doubled,total:g.total,soft:g.soft,result:this.phase==="results"?d.result:null,paid:d.paid,done:d.done}}),insurance:l.insurance,insured:l.insured,net:this.phase==="results"?l.net:null}});let u=s.current();this.phase==="play"&&u&&(r.turn={seat:u.player.id,hand:this.round.turn.h}),r.legal=this.phase==="play"?s.legal(t):null;let h=s.player(t);return r.insurance=this.phase==="insurance"&&h&&h.insured===null?Math.floor(h.hands[0].bet/2):0,r.committed=s.committed(t),r}};Or.exports={BlackjackTable:fo,SEATS:co,MIN_BET:_t,MAX_BET:lo,MIN_BUYIN:uo,MAX_BUYIN:ho}});var oi=pe((eu,ni)=>{"use strict";var bl=require("os"),Ze=tt(),{RESET:Y,BOLD:U,DIM:qr,fg:Fs,bg:yo,C:y,visLen:hs,Line:qe,button:Z,draw:po}=Ze,{save:je,persist:Dr,wallet:re,START_CHIPS:$l}=Et(),{cardRows:xo,cardsRows:Lr,mini:gl}=In(),{bigText:jr,shimmer:Kr}=bn(),{BlackjackTable:Fr,MIN_BET:wo,MAX_BET:Gr,MIN_BUYIN:ze,MAX_BUYIN:yl}=Br(),{PORT:Hr,hostTable:wl,joinTable:kl,addresses:Wl}=Kn(),Qr="blackjack";je.blackjack=je.blackjack||{};var Sl=()=>{try{return bl.userInfo().username.slice(0,14)}catch{return"Player"}},w={screen:"lobby",name:je.blackjack.name||je.holdem.name||Sl(),addr:je.blackjack.addr||je.holdem.addr||"",port:je.blackjack.port||Hr,buyin:Math.min(1e3,Math.max(ze,re.chips)),message:"",input:null,ctrl:null,busted:!1,rebet:!1,flash:null},Jr=()=>je.blackjack.stats={rounds:0,won:0,net:0,blackjacks:0,biggest:0,...je.blackjack.stats};function Ur(){Object.assign(je.blackjack,{name:w.name,addr:w.addr,port:w.port}),Dr("blackjack")}function Dt(){w.buyin=Math.max(ze,Math.min(yl,re.chips,w.buyin))}function ko(e,t={}){e&&re.adjust(e);let s=Jr();s.rounds++,e>0&&s.won++,s.net+=e,e>s.biggest&&(s.biggest=e),t.blackjack&&s.blackjacks++,Dr("blackjack"),t.blackjack?w.flash={text:"BLACKJACK",until:Date.now()+2600}:e>=500&&(w.flash={text:"BIG WIN",until:Date.now()+2600})}function Yr(e,t,s,n=null){let o=()=>e.seatOf(t);return e.on("change",()=>{Xr(e.view(o()),()=>e.act(o(),{type:"deal"})),Ze.render()}),e.on("settle",(a,r,c)=>{if(a!==o())return;let u=c.player(a);ko(r,{blackjack:u&&u.hands.some(h=>h.result==="blackjack")})}),e.on("busted",a=>{a===o()&&(w.busted=!0)}),{mode:s,server:n,view:()=>e.view(o()),viewAge:()=>0,act:a=>e.act(o(),a),ready:()=>e.setReady(o()),say:a=>e.say(o(),a),rebuy:a=>{e.rebuy(o(),a)&&(w.busted=!1)},close(){n&&n.close(),e.removePerson(o()),e.close()}}}function Xr(e,t){w.rebet&&e&&e.phase==="betting"&&e.seats[e.you]&&!e.seats[e.you].confirmed&&(w.rebet=!1,e.seats[e.you].bet>=e.minBet&&setImmediate(t))}function Wo(){return re.sync(),Dt(),re.chips<ze?(w.message=`${y.bad}You need at least ${ze} chips to sit down.`,!1):!w.ctrl}function Vr(){if(!Wo())return;let e=new Fr,t=e.addPerson("You",w.buyin);w.ctrl=Yr(e,t,"solo"),vo(),e.start()}function So(){if(!Wo())return;let e=new Fr({betMs:15e3,turnMs:3e4,autoNextMs:6e3}),t=e.addPerson(w.name,w.buyin),s=wl(e,{game:Qr,port:w.port,onError:n=>{ht(!0),w.message=`${y.bad}Couldn't host on port ${w.port}: ${n.code==="EADDRINUSE"?"something else is using it (another table?)":n.message}`,Ze.render()}});w.ctrl=Yr(e,t,"host",s),vo(),e.start()}function Mo(e){if(!Wo())return;if(!e){w.message=`${y.bad}Enter the host's address first (J).`;return}w.addr=e,Ur();let t=null,s=0,n=!1;w.message=`${y.accent}Connecting to ${e}\u2026`;let o=kl(e,{game:Qr,name:w.name,buyin:w.buyin},{onMessage(a){if(a.t==="welcome")w.name=a.name;else if(a.t==="view")t=a.view,s=Date.now(),w.screen!=="table"&&vo(),Xr(t,()=>o.send({t:"act",action:{type:"deal"}}));else if(a.t==="settle"){let r=t&&t.players[t.you];ko(a.net,{blackjack:!!r&&r.hands.length===1&&r.hands[0].cards.length===2&&r.hands[0].total===21})}else a.t==="busted"&&(w.busted=!0);Ze.render()},onClose(a){n||(w.ctrl&&w.ctrl.conn===o&&(Ao(t),w.ctrl=null,w.screen="lobby"),w.message=`${y.bad}${a}`,Ze.render())}});w.ctrl={mode:"join",conn:o,view:()=>t,viewAge:()=>Date.now()-s,act:a=>o.send({t:"act",action:a}),ready:()=>o.send({t:"ready"}),say:a=>o.send({t:"chat",text:a}),rebuy:a=>{o.send({t:"rebuy",buyin:a}),w.busted=!1},close(){n=!0,o.send({t:"leave"}),o.close()}}}function vo(){w.screen="table",w.message="",w.busted=!1,w.rebet=!1}function Ao(e){e&&e.players&&e.players[e.you]&&e.phase!=="results"&&e.phase!=="betting"&&e.committed>0&&ko(-e.committed)}function ht(e=!1){let t=w.ctrl;if(!t){w.screen="lobby";return}Ao(t.view()),w.ctrl=null,t.close(),w.screen="lobby",e||(w.message=t.mode==="host"?`${y.muted}Table closed.`:"")}var ft=()=>w.ctrl?w.ctrl.view():null,jt=e=>e&&e.seats[e.you];function De(e){let t=ft(),s=jt(t);!t||t.phase!=="betting"||!s||s.confirmed||w.ctrl.act({type:"bet",amount:Math.max(0,Math.min(Gr,s.stack,s.bet+e))})}function Nr(e){let t=ft(),s=jt(t);t&&t.phase==="betting"&&s&&!s.confirmed&&w.ctrl.act({type:"bet",amount:e})}function js(){let e=ft(),t=jt(e);!e||!t||(e.phase==="betting"?w.ctrl.act({type:t.confirmed?"unbet":"deal"}):e.phase==="results"&&e.waitingNext&&(w.rebet=!0,w.ctrl.ready()))}function dt(e){let t=ft();t&&t.legal&&t.legal[e]&&w.ctrl.act({type:e})}function Ks(e){let t=ft();t&&t.insurance&&w.ctrl.act({type:"insurance",take:e})}function zr(){if(re.sync(),Dt(),re.chips<ze){w.message=`${y.bad}Not enough chips in your wallet to rebuy.`;return}w.ctrl.rebuy(w.buyin)}var _r=yo(18,82,54),Zr=96,mo=19,Ml=Fs(200,230,210),qt=Fs(255,230,140),vl=Fs(255,206,84),ei={blackjack:[Fs(255,215,90),"BLACKJACK"],win:[y.good,"WIN"],push:[y.accent,"PUSH"],lose:[y.bad,"LOSE"],bust:[y.bad,"BUST"]};function xe(e=""){let t=Math.max(0,Zr-2-hs(e));return _r+" "+e.split(Y).join(Y+_r)+" ".repeat(t)+" "+Y}var ds=(e,t)=>e+" ".repeat(Math.max(0,t-hs(e))),Pt=(e,t)=>ds(" ".repeat(Math.max(0,Math.floor((t-hs(e))/2)))+e,t),Pr=e=>Math.ceil(Math.max(0,e.deadline-w.ctrl.viewAge())/1e3),bo=e=>e.cards.length?`${e.soft&&e.total<21?`${e.total-10}/${e.total}`:e.total}`:"";function Al(e,t){let s=e.seats[t];if(!s)return["",` ${y.muted}${qr}empty seat`,"","",""].map(u=>ds(u,mo));let n=e.players[t],o=e.turn&&e.turn.seat===t,a=o?yo(240,196,64)+y.dark+U:(t===e.you?y.accent:y.text)+U,r=s.connected?s.leaving?` ${y.muted}leaving`:"":` ${y.bad}offline`,c=[`${o?`${y.title}\u25B6`:" "}${a}${s.name}${Y}${r}`,` ${Ml}${s.stack}${Y}`];if(!n)c.push(e.phase==="betting"?` ${s.confirmed?`${qt}\u25CF ${s.bet} ${y.good}\u2713`:`${y.muted}betting\u2026`}`:` ${y.muted}sitting out`);else{n.hands.forEach((h,l)=>{let f=o&&e.turn.hand===l,d=h.result&&ei[h.result],x=h.cards.map(m=>gl(m)).join("");c.push(`${f?`${y.title}\u203A`:" "}${x} ${y.text}${U}${bo(h)}${Y}${d?` ${d[0]}${U}${d[1]}`:""}`)});let u=n.hands.reduce((h,l)=>h+l.bet,0);c.push(` ${qt}\u25CF ${u}${n.insurance?` +${n.insurance} ins`:""}${Y}${n.net!==null?` ${n.net>0?y.good+"+":n.net<0?y.bad:y.muted}${n.net}`:""}`)}for(;c.length<5;)c.push("");return c.slice(0,5).map(u=>ds(u,mo))}function Tl(){let e=w.ctrl.server?w.ctrl.server.port():w.port,[t,...s]=Wl();if(!t)return`${y.bad}No network connection found \u2014 friends can't reach this table.`;let n=e===Hr?"":`:${e}`,o=s.length?`${y.muted} other: ${s.map(a=>`${a.address}${n} (${a.label})`).join(", ")}`:"";return`${y.muted}Friends join with ${y.title}${U}blackjack join ${t.address}${n}${Y}${y.muted} (${t.label})${o}`}function Rl(){let e=ft();if(!e){po(["",`${y.accent}Connecting\u2026`]);return}let t=Date.now(),s=Zr-2,n=[],o=w.ctrl.mode==="host"?`${y.good}hosting`:w.ctrl.mode==="join"?`${y.accent}online`:`${y.muted}solo`;n.push(`${y.title}${U}BLACKJACK${Y} ${o}${Y} ${y.muted}6 decks \xB7 dealer stands on soft 17 \xB7 blackjack pays 3:2 \xB7 shoe ${e.shoe}% used wallet ${y.text}${re.chips}`),n.push(w.ctrl.mode==="host"?Tl():""),n.push(xe());let a=e.dealer,r=a?[...a.cards.map(k=>xo(k)),...Array.from({length:a.hidden},()=>xo(0,{hidden:!0}))]:[],c=a&&a.cards.length?`${a.blackjack?`${vl}${U}BLACKJACK`:`${y.text}${U}${a.total}${a.total>21?` ${y.bad}BUST`:""}`}`:"";n.push(xe(Pt(`${y.muted}${U}DEALER${Y} ${c}`,s)));let u=r.length?Lr(r):["","",""];for(let k of u)n.push(xe(Pt(k,s)));n.push(xe(Pt(`${y.muted}${qr}\u2014 insurance pays 2 to 1 \u2014`,s)));let h=w.flash&&w.flash.until>t?w.flash.text:"";if(h?jr(h).forEach(k=>n.push(xe(Pt(Kr(k,t,1.6,!0),s)))):n.push(xe(),xe(),xe()),e.seats.filter(Boolean).length>1){let S=[0,1,2,3,4].map(C=>(e.you+C+3)%5).map(C=>Al(e,C)),A=Math.max(0,Math.floor((s-5*mo)/4));for(let C=0;C<5;C++)n.push(xe(S.map(W=>W[C]).join(" ".repeat(A))));n.push(xe())}let l=e.players[e.you];if(l){let k=l.hands.map((S,A)=>{let C=e.turn&&e.turn.seat===e.you&&e.turn.hand===A,W=Lr(S.cards.map(H=>xo(H))),v=S.result&&ei[S.result],T=`${C?`${y.title}${U}\u25B6 `:" "}${y.text}${U}${bo(S)}${Y} ${qt}\u25CF ${S.bet}${S.doubled?" \xD72":""}${Y}${v?` ${v[0]}${U}${v[1]}`:""}`,G=Math.max(hs(W[0]),hs(T));return[...W.map(H=>ds(H,G)),ds(T,G)]});for(let S=0;S<4;S++)n.push(xe(Pt(k.map(A=>A[S]).join(" "),s)))}else n.push(xe(),xe(Pt(`${y.muted}${e.phase==="betting"?"Place your bet.":"You sit this round out."}`,s)),xe(),xe());n.push(xe()),n.push("");let f=jt(e),d=e.deadline?` ${y.title}\u23F1 ${Pr(e)}s`:"";if(w.busted||f&&f.stack<wo&&e.phase==="betting"){n.push(`${y.bad}${U}You're out of chips at this table.`,"");let k=new qe;Z(k,`Rebuy ${w.buyin}`,zr,{hot:!0,enabled:re.chips>=ze}),Z(k,"Leave table",()=>ht()),n.push(k)}else if(e.phase==="betting"&&f)if(f.confirmed){n.push(`${y.text}Bet ${qt}${U}${f.bet}${Y}${y.text} placed \u2014 waiting for the other players.${d}`,"");let k=new qe;Z(k,"Change bet",js),Z(k,w.ctrl.mode==="host"?"Close table":"Leave table",()=>ht()),n.push(k)}else{n.push(`${y.text}Place your bet (${e.minBet}\u2013${e.maxBet}).${d}`,"");let k=new qe(`${y.muted}bet `);k.add(`${y.title}${U} \u2039 ${Y}`,()=>De(-10),S=>De(-S*10)),k.add(`${qt}${U}${String(f.bet).padStart(4)}${Y}`,null,S=>De(-S*10)),k.add(`${y.title}${U} \u203A ${Y} `,()=>De(10),S=>De(-S*10));for(let S of[10,25,100])Z(k,`+${S}`,()=>De(S));Z(k,"Max",()=>Nr(Math.min(e.maxBet,f.stack))),Z(k,"Clear",()=>Nr(0)),Z(k,"DEAL",js,{hot:f.bet>=e.minBet,enabled:f.bet>=e.minBet}),Z(k,w.ctrl.mode==="host"?"Close table":"Leave",()=>ht()),n.push(k)}else if(e.phase==="insurance"&&e.insurance){n.push(`${y.text}The dealer shows an ace. Insurance costs ${qt}${e.insurance}${y.text} and pays 2:1 if the dealer has blackjack.${d}`,"");let k=new qe;Z(k,"Insure (I)",()=>Ks(!0),{enabled:f&&f.stack>=e.insurance}),Z(k,"No thanks (N)",()=>Ks(!1),{hot:!0}),n.push(k)}else if(e.legal){let k=l.hands[e.turn.hand];n.push(`${y.text}Your move \u2014 ${U}${bo(k)}${Y}${y.text}${l.hands.length>1?` (hand ${e.turn.hand+1} of ${l.hands.length})`:""}.${d}`,"");let S=new qe;Z(S,"Hit (H)",()=>dt("hit"),{hot:!0}),Z(S,"Stand (S)",()=>dt("stand")),Z(S,"Double (D)",()=>dt("double"),{enabled:e.legal.double}),Z(S,"Split (P)",()=>dt("split"),{enabled:e.legal.split}),n.push(S)}else if(e.phase==="results"){let k=l?l.net:null,S=k===null?`${y.muted}Round over.`:k>0?`${y.good}${U}You win ${k}!`:k<0?`${y.bad}${U}You lose ${-k}.`:`${y.accent}${U}Push \u2014 your bet comes back.`;n.push(`${S}${Y}${e.deadline?` ${y.muted}next round in ${Pr(e)}s`:""}`,"");let A=new qe;Z(A,e.waitingNext?`Rebet ${f?f.bet:""} & deal`:"Waiting for others\u2026",js,{hot:e.waitingNext,enabled:e.waitingNext}),Z(A,w.ctrl.mode==="host"?"Close table":"Leave table",()=>ht()),n.push(A)}else{let k=e.turn?e.seats[e.turn.seat]&&e.seats[e.turn.seat].name:null,S=e.phase==="dealing"?"Dealing\u2026":e.phase==="dealer"?"Dealer plays\u2026":e.phase==="insurance"?"Waiting for insurance decisions\u2026":k?`${k} is playing\u2026${d}`:"";n.push(`${y.muted}${S}`,"");let A=new qe;Z(A,w.ctrl.mode==="host"?"Close table":"Leave table",()=>ht()),n.push(A)}n.push("");let m=[...(w.ctrl.mode==="solo"?e.notes.filter(k=>k.startsWith("New shoe")):e.notes).slice(-2).map(k=>`${y.muted}\xBB ${k}`),...e.chat.slice(-3).map(k=>`${y.accent}${k.name}:${Y} ${y.text}${k.text}`)];for(let k of m.slice(-4))n.push(k);for(let k=m.length;k<4;k++)n.push("");n.push(w.input?`${y.title}${w.input.label}: ${y.text}${w.input.value}${y.title}\u258C`:"");let g=w.ctrl.mode==="solo"?"":` \xB7 ${y.text}T${y.muted} chat`;n.push(`${y.muted}Keys: ${y.text}Space${y.muted} deal/rebet \xB7 ${y.text}\u2190\u2192${y.muted} bet \xB110 \xB7 ${y.text}\u2191\u2193${y.muted} \xB1100 \xB7 ${y.text}H${y.muted} hit \xB7 ${y.text}S${y.muted} stand \xB7 ${y.text}D${y.muted} double \xB7 ${y.text}P${y.muted} split \xB7 ${y.text}I/N${y.muted} insurance${g} \xB7 ${y.text}Esc${y.muted} leave`),po(n)}function Cl(){re.sync(),Dt();let e=[""];jr("BLACKJACK").forEach(a=>e.push(Kr(a,Date.now(),.5))),e.push(`${y.muted}vs the house \xB7 6 decks \xB7 blackjack pays 3:2 \xB7 dealer stands on soft 17 \xB7 up to 5 players`,""),e.push(`${y.text}Wallet: ${U}${re.chips}${Y}${y.text} chips`,"");let t=(a,r,c,u)=>{let h=new qe(`${y.text}${a.padEnd(11)}`);h.add(`${yo(40,44,58)}${y.text} ${r||`${y.muted}\u2014`} ${Y}`,u),h.add(` ${y.muted}${c}`),e.push(h)};if(t("Name",w.name,"E to edit (used online)",ti),re.chips>=ze){let a=new qe(`${y.text}${"Buy-in".padEnd(11)}`),r=c=>{w.buyin+=c*100,Dt()};a.add(`${y.title}${U} \u2039 ${Y}`,()=>r(-1),c=>r(-c)),a.add(`${y.text}${U}${String(w.buyin).padStart(6)}${Y}`,()=>r(1),c=>r(-c)),a.add(`${y.title}${U} \u203A ${Y}`,()=>r(1),c=>r(-c)),a.add(` ${y.muted}bets ${wo}\u2013${Gr}`),e.push(a)}else e.push(`${y.bad}You need at least ${ze} chips to play.`);t("Join",w.addr,"J to type a host address and join",$o),e.push("");let s=new qe,n=re.chips>=ze;Z(s,"Play",Vr,{enabled:n,hot:!0}),Z(s,`Host on :${w.port}`,So,{enabled:n}),Z(s,"Join",()=>w.addr?Mo(w.addr):$o(),{enabled:n}),re.canRefill()&&Z(s,`Refill to ${$l}`,()=>re.refill()),Z(s,Ze.hasLauncher()?"Arcade":"Quit",si),e.push(s,""),w.message&&e.push(`${y.text}${w.message}`,"");let o=Jr();e.push(`${y.muted}rounds ${o.rounds} \xB7 won ${o.won} \xB7 blackjacks ${o.blackjacks} \xB7 net ${o.net>=0?"+":""}${o.net} \xB7 best ${o.biggest}`,""),e.push(`${y.muted}Host: friends with the arcade join your table with ${y.text}blackjack join <your address>${y.muted}.`),e.push(`${y.muted}Everyone plays their own hands against the same dealer.`,""),e.push(w.input?`${y.title}${w.input.label}: ${y.text}${w.input.value}${y.title}\u258C${y.muted} Enter to confirm \xB7 Esc to cancel`:""),e.push(`${y.muted}Keys: ${y.text}Enter${y.muted} play \xB7 ${y.text}H${y.muted} host \xB7 ${y.text}J${y.muted} join \xB7 ${y.text}E${y.muted} name \xB7 ${y.text}\u2190\u2192${y.muted} buy-in \xB7 ${y.text}F${y.muted} refill \xB7 ${y.text}Esc${y.muted} ${Ze.hasLauncher()?"arcade":"quit"}`),po(e)}function ti(){w.input={label:"Your name",value:w.name,max:14,onDone:e=>{e.trim()&&(w.name=e.trim(),Ur())}}}function $o(){w.input={label:"Host address (ip or ip:port)",value:w.addr,max:60,onDone:e=>{e.trim()&&Mo(e.trim())}}}function si(){w.ctrl&&ht(!0),Ze.leave()}function El(e,t){let s=w.input;if(e==="enter"){w.input=null,s.onDone(s.value);return}if(e==="escape"){w.input=null;return}let n=t&&t.ch;if(n==="\x7F"||n==="\b"){s.value=s.value.slice(0,-1);return}if(e==="space"){s.value.length<s.max&&(s.value+=" ");return}n&&n.length===1&&n>=" "&&s.value.length<s.max&&(s.value+=n)}var go={render(){w.screen==="table"&&w.ctrl?Rl():Cl()},onShow(){re.sync()},onQuit(){w.ctrl&&(Ao(w.ctrl.view()),w.ctrl.close(),w.ctrl=null)},onTick(){let e=w.screen==="table"&&ft();(e&&e.deadline||w.flash&&w.flash.until>Date.now()-200)&&Ze.render()},onKey(e,t){if(w.input)return El(e,t);if(w.screen!=="table"||!w.ctrl){if(e==="escape"||e==="q")return si();e==="left"?(w.buyin-=100,Dt()):e==="right"?(w.buyin+=100,Dt()):e==="enter"||e==="space"?Vr():e==="h"?So():e==="j"?$o():e==="e"?ti():e==="f"&&re.canRefill()&&re.refill();return}if(e==="escape"||e==="q")return ht();if(e==="t"&&w.ctrl.mode!=="solo"){w.input={label:"Say",value:"",max:120,onDone:n=>{n.trim()&&w.ctrl.say(n)}};return}let s=ft();if(s){if(w.busted||jt(s)&&jt(s).stack<wo&&s.phase==="betting"){e==="r"&&zr();return}switch(e){case"space":case"enter":js();break;case"left":De(-10);break;case"right":De(10);break;case"up":De(100);break;case"down":De(-100);break;case"h":dt("hit");break;case"s":dt("stand");break;case"d":dt("double");break;case"p":dt("split");break;case"i":Ks(!0);break;case"n":Ks(!1);break}}}};function Il(e){let t=o=>{let a=e.indexOf(o);return a>=0?e[a+1]:void 0};t("--name")&&(w.name=t("--name").slice(0,14)),t("--buyin")&&(w.buyin=+t("--buyin")||w.buyin);let[s,n]=e.filter((o,a)=>!o.startsWith("--")&&!(a>0&&e[a-1].startsWith("--")));s==="host"?(n&&+n&&(w.port=+n),go.onShow=()=>{re.sync(),w.ctrl||So()}):s==="join"&&n&&(go.onShow=()=>{re.sync(),w.ctrl||Mo(n)})}ni.exports={name:"Blackjack",screen:go,configure:Il}});var Rt=tt(),{RESET:To,BOLD:Tt,C:$e,Line:ai,button:Ol,draw:li}=Rt,{wallet:ri,takeNotice:Bl}=Et(),fs={minesweeper:()=>ha(),slots:()=>qa(),holdem:()=>Tr(),blackjack:()=>oi()},Kt=[{key:"minesweeper",name:"Minesweeper",desc:"no-guess boards, hints, rewind, best times"},{key:"slots",name:"Book of Ra",desc:"5\xD73 slots, free games, expanding symbol, gamble"},{key:"holdem",name:"Texas Hold'em",desc:"vs bots, or host / join friends online"},{key:"blackjack",name:"Blackjack",desc:"vs the house, solo or with friends at one table"}],et={sel:0};function Ll(e){Rt.show(fs[e]().screen)}var ii={onShow(){ri.sync()},render(){let e=["",`${$e.title}${Tt} \u2554\u2566\u2557\u2554\u2550\u2557\u2566\u2550\u2557\u2554\u2566\u2557\u2566\u2554\u2557\u2554\u2554\u2550\u2557\u2566 \u2554\u2550\u2557\u2566\u2550\u2557\u2554\u2550\u2557\u2554\u2550\u2557\u2554\u2566\u2557\u2554\u2550\u2557`,`${$e.title}${Tt} \u2551 \u2551\u2563 \u2560\u2566\u255D\u2551\u2551\u2551\u2551\u2551\u2551\u2551\u2560\u2550\u2563\u2551 \u2560\u2550\u2563\u2560\u2566\u255D\u2551 \u2560\u2550\u2563 \u2551\u2551\u2551\u2563 `,`${$e.title}${Tt} \u2569 \u255A\u2550\u255D\u2569\u255A\u2550\u2569 \u2569\u2569\u255D\u255A\u255D\u2569 \u2569\u2569\u2550\u255D \u2569 \u2569\u2569\u255A\u2550\u255A\u2550\u255D\u2569 \u2569\u2550\u2569\u255D\u255A\u2550\u255D`,"",`${$e.muted} wallet ${$e.text}${Tt}${ri.chips}${To}${$e.muted} chips \xB7 v2.4.0`,""],t=[...Kt,{key:"quit",name:"Quit",desc:""}];t.forEach((n,o)=>{let a=o===et.sel,r=new ai(a?`${$e.title}${Tt} \u25B6 ${To}`:" ");r.add(`${a?$e.text+Tt:$e.text}${n.name.padEnd(16)}${To}${$e.muted}${n.desc}`),r.whole(()=>{et.sel=o,Gs(n)}),e.push(r)}),e.push("");let s=new ai(" ");Ol(s,"Play",()=>Gs(t[et.sel]),{hot:!0}),e.push(s),e.push("",`${$e.muted} \u2191\u2193 select \xB7 Enter play \xB7 Q quit \xB7 Q inside a game comes back here`),li(e)},onKey(e){let t=Kt.length+1;e==="up"||e==="w"?et.sel=(et.sel-1+t)%t:e==="down"||e==="s"?et.sel=(et.sel+1)%t:e==="enter"||e==="space"?Gs(et.sel<Kt.length?Kt[et.sel]:{key:"quit"}):e==="q"||e==="escape"?Rt.quit():e>="1"&&e<=String(Kt.length)&&Gs(Kt[+e-1])}};function Nl(e,t){let s=()=>Rt.show(t);return{render(){li(["",`${$e.bad}${Tt} Save reset`,"",` ${$e.text}${e}`,"",` ${$e.muted}Press any key to continue.`])},onKey:s,onMouse(n){n.press&&s()}}}var ci=e=>{let t=Bl();return t?Nl(t,e):e};function Gs(e){e.key==="quit"?Rt.quit():Ll(e.key)}var Hs=process.argv.slice(2),Ft=Hs.find(e=>!e.startsWith("-"));Ft&&!fs[Ft]&&(console.error(`Unknown game "${Ft}". Choose one of: ${Object.keys(fs).join(", ")}`),process.exit(1));if(Hs.includes("--bench"))fs.minesweeper().bench().catch(e=>{console.error(e),process.exit(1)});else if(Ft){let e=fs[Ft]();e.configure&&e.configure(Hs.slice(Hs.indexOf(Ft)+1)),Rt.run(ci(e.screen))}else Rt.run(ci(ii),ii);
|
package/package.json
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "tui-arcade",
|
|
3
|
+
"version": "2.4.0",
|
|
4
|
+
"description": "Minesweeper, Book of Ra slots, Texas Hold'em and Blackjack in your terminal — solo or with friends over the network.",
|
|
5
|
+
"bin": {
|
|
6
|
+
"tui-arcade": "arcade.js"
|
|
7
|
+
},
|
|
8
|
+
"files": [
|
|
9
|
+
"arcade.js",
|
|
10
|
+
"README.md"
|
|
11
|
+
],
|
|
12
|
+
"engines": {
|
|
13
|
+
"node": ">=18"
|
|
14
|
+
},
|
|
15
|
+
"license": "UNLICENSED",
|
|
16
|
+
"keywords": [
|
|
17
|
+
"terminal",
|
|
18
|
+
"tui",
|
|
19
|
+
"game",
|
|
20
|
+
"arcade",
|
|
21
|
+
"minesweeper",
|
|
22
|
+
"poker",
|
|
23
|
+
"holdem",
|
|
24
|
+
"blackjack",
|
|
25
|
+
"slots",
|
|
26
|
+
"multiplayer"
|
|
27
|
+
]
|
|
28
|
+
}
|