Repository: jesseduffield/lazygit (language: go)

Issue:
Not loading/parsing unknown terminfo files
**Describe the bug**
Hi! 👋  I'm working [on a new terminal emulator](https://mitchellh.com/ghostty). It is very full featured and has dozens of full time testers. One recently reported `lazygit` doesn't work in it, and I realized that doing `TERM=xterm-256color lazygit` fixes everything.

Ghostty sets `TERM` to `xterm-ghostty` but also sets `TERMINFO` to a valid terminfo database path. (See https://man7.org/linux/man-pages/man5/terminfo.5.html) See below:

<img width="933" alt="CleanShot 2023-08-26 at 08 10 30@2x" src="https://github.com/jesseduffield/lazygit/assets/1299/33abcdc9-a124-4ec6-8a64-f9ff91829ff6">

**To Reproduce**
I can get you access to the terminal, but running `lazygit` with a `TERM` thats unknown and a `TERMINFO` set to a path that defines `$TERM` will work just as well.

**Expected behavior**
lazygit should dynamically parse terminfo to accept terminals it doesn't know about.

**Screenshots**
The below happens instead, but it renders and functions perfectly if I set `TERM=xterm-256color`.

![CleanShot 2023-08-26 at 08 12 12@2x](https://github.com/jesseduffield/lazygit/assets/1299/35b826ab-158c-42b5-8bb9-dab7fa912ff9)

**Version info:**
```
commit=, build date=, build source=homebrew, version=0.40.2, os=darwin, arch=arm64, git version=2.36.0
```

**Additional context**
I dug into it a bit and it looks like your dependency `tcell` supports dynamically parsing terminfo/termcap files. Please let me know if I'm doing anything wrong here.



Discussion / hints:
And if it helps, our `infocmp` output:

```
#	Reconstructed via infocmp from file: /Applications/Ghostty.app/Contents/Resources/terminfo/78/xterm-ghostty
ghostty|xterm-ghostty|Ghostty,
	am, bce, ccc, hs, km, mc5i, mir, msgr, npc, xenl,
	colors#0x100, cols#80, it#8, lines#24, pairs#0x7fff,
	acsc=++\,\,--..00``aaffgghhiijjkkllmmnnooppqqrrssttuuvvwwxxyyzz{{||}}~~,
	bel=^G, blink=\E[5m, bold=\E[1m, cbt=\E[Z, civis=\E[?25l,
	clear=\E[H\E[2J, cnorm=\E[?12l\E[?25h, cr=\r,
	csr=\E[%i%p1%d;%p2%dr, cub=\E[%p1%dD, cub1=^H,
	cud=\E[%p1%dB, cud1=\n, cuf=\E[%p1%dC, cuf1=\E[C,
	cup=\E[%i%p1%d;%p2%dH, cuu=\E[%p1%dA, cuu1=\E[A,
	cvvis=\E[?12;25h, dch=\E[%p1%dP, dch1=\E[P, dim=\E[2m,
	dl=\E[%p1%dM, dl1=\E[M, dsl=\E]2;\007, ech=\E[%p1%dX,
	ed=\E[J, el=\E[K, el1=\E[1K, flash=\E[?5h$<100/>\E[?5l,
	fsl=^G, home=\E[H, hpa=\E[%i%p1%dG, ht=^I, hts=\EH,
	ich=\E[%p1%d@, il=\E[%p1%dL, il1=\E[L, ind=\n,
	indn=\E[%p1%dS,
	initc=\E]4;%p1%d;rgb:%p2%{255}%*%{1000}%/%2.2X/%p3%{255}%*%{1000}%/%2.2X/%p4%{255}%*%{1000}%/%2.2X\E\\,
	invis=\E[8m, kDC=\E[3;2~, kEND=\E[1;2F, kHOM=\E[1;2H,
	kIC=\E[2;2~, kLFT=\E[1;2D, kNXT=\E[6;2~, kPRV=\E[5;2~,
	kRIT=\E[1;2C, kbs=^?, kcbt=\E[Z, kcub1=\EOD, kcud1=\EOB,
	kcuf1=\EOC, kcuu1=\EOA, kdch1=\E[3~, kend=\EOF, kent=\EOM,
	kf1=\EOP, kf10=\E[21~, kf11=\E[23~, kf12=\E[24~,
	kf13=\E[1;2P, kf14=\E[1;2Q, kf15=\E[1;2R, kf16=\E[1;2S,
	kf17=\E[15;2~, kf18=\E[17;2~, kf19=\E[18;2~, kf2=\EOQ,
	kf20=\E[19;2~, kf21=\E[20;2~, kf22=\E[21;2~,
	kf23=\E[23;2~, kf24=\E[24;2~, kf25=\E[1;5P, kf26=\E[1;5Q,
	kf27=\E[1;5R, kf28=\E[1;5S, kf29=\E[15;5~, kf3=\EOR,
	kf30=\E[17;5~, kf31=\E[18;5~, kf32=\E[19;5~,
	kf33=\E[20;5~, kf34=\E[21;5~, kf35=\E[23;5~,
	kf36=\E[24;5~, kf37=\E[1;6P, kf38=\E[1;6Q, kf39=\E[1;6R,
	kf4=\EOS, kf40=\E[1;6S, kf41=\E[15;6~, kf42=\E[17;6~,
	kf43=\E[18;6~, kf44=\E[19;6~, kf45=\E[20;6~,
	kf46=\E[21;6~, kf47=\E[23;6~, kf48=\E[24;6~,
	kf49=\E[1;3P, kf5=\E[15~, kf50=\E[1;3Q, kf51=\E[1;3R,
	kf52=\E[1;3S, kf53=\E[15;3~, kf54=\E[17;3~,
	kf55=\E[18;3~, kf56=\E[19;3~, kf57=\E[20;3~,
	kf58=\E[21;3~, kf59=\E[23;3~, kf6=\E[17~, kf60=\E[24;3~,
	kf61=\E[1;4P, kf62=\E[1;4Q, kf63=\E[1;4R, kf7=\E[18~,
	kf8=\E[19~, kf9=\E[20~, khome=\EOH, kich1=\E[2~,
	kind=\E[1;2B, kmous=\E[M, knp=\E[6~, kpp=\E[5~,
	kri=\E[1;2A, oc=\E]104\007, op=\E[39;49m, rc=\E8,
	rep=%p1%c\E[%p2%{1}%-%db, rev=\E[7m, ri=\EM,
	rin=\E[%p1%dT, ritm=\E[23m, rmacs=\E(B, rmam=\E[?7l,
	rmcup=\E[?1049l, rmir=\E[4l, rmkx=\E[?1l, rmso=\E[27m,
	rmul=\E[24m, rs1=\E]\E\\\Ec, sc=\E7,
	setab=\E[%?%p1%{8}%<%t4%p1%d%e%p1%{16}%<%t10%p1%{8}%-%d%e48;5;%p1%d%;m,
	setaf=\E[%?%p1%{8}%<%t3%p1%d%e%p1%{16}%<%t9%p1%{8}%-%d%e38;5;%p1%d%;m,
	sgr=%?%p9%t\E(0%e\E(B%;\E[0%?%p6%t;1%;%?%p2%t;4%;%?%p1%p3%|%t;7%;%?%p4%t;5%;%?%p7%t;8%;m,
	sgr0=\E(B\E[m, sitm=\E[3m, smacs=\E(0, smam=\E[?7h,
	smcup=\E[?1049h, smir=\E[4h, smkx=\E[?1h, smso=\E[7m,
	smul=\E[4m, tbc=\E[3g, tsl=\E]2;, u6=\E[%i%d;%dR, u7=\E[6n,
	u8=\E[?%[;0123456789]c, u9=\E[c, vpa=\E[%i%p1%dd,
```
Similar issue here. I use iterm2. I have compiled and installed the iterm2's terminfo file to `~/.terminfo`. Other command line utilities (like macOS builtin `ls`) are confirmed to respect the installed terminfo file.
Now that Ghostty has full released and I've been able to use it I've run into a similar issue as well. Is there anything any of us can do to help get this fixed?
I'm running into this same issue too.

Fix patch:
diff --git a/go.mod b/go.mod
index 21cf64fc746..c7f6f768210 100644
--- a/go.mod
+++ b/go.mod
@@ -8,7 +8,7 @@ require (
 	github.com/aybabtme/humanlog v0.4.1
 	github.com/cloudfoundry/jibber_jabber v0.0.0-20151120183258-bcc4c8345a21
 	github.com/creack/pty v1.1.11
-	github.com/gdamore/tcell/v2 v2.7.4
+	github.com/gdamore/tcell/v2 v2.8.0
 	github.com/go-errors/errors v1.5.1
 	github.com/gookit/color v1.4.2
 	github.com/iancoleman/orderedmap v0.3.0
@@ -16,7 +16,7 @@ require (
 	github.com/integrii/flaggy v1.4.0
 	github.com/jesseduffield/generics v0.0.0-20220320043834-727e535cbe68
 	github.com/jesseduffield/go-git/v5 v5.1.2-0.20221018185014-fdd53fef665d
-	github.com/jesseduffield/gocui v0.3.1-0.20250107151125-716b1eb82fb4
+	github.com/jesseduffield/gocui v0.3.1-0.20250111205211-82d518436b5a
 	github.com/jesseduffield/kill v0.0.0-20250101124109-e216ddbe133a
 	github.com/jesseduffield/lazycore v0.0.0-20221012050358-03d2e40243c5
 	github.com/jesseduffield/minimal/gitignore v0.3.3-0.20211018110810-9cde264e6b1e
@@ -54,7 +54,6 @@ require (
 	github.com/go-git/go-billy/v5 v5.0.0 // indirect
 	github.com/go-logfmt/logfmt v0.5.0 // indirect
 	github.com/gobwas/glob v0.2.3 // indirect
-	github.com/google/go-cmp v0.5.6 // indirect
 	github.com/invopop/jsonschema v0.10.0 // indirect
 	github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 // indirect
 	github.com/kevinburke/ssh_config v0.0.0-20190725054713-01f96b0aa0cd // indirect
diff --git a/go.sum b/go.sum
index 3f2f028a45c..0a7458a854e 100644
--- a/go.sum
+++ b/go.sum
@@ -85,11 +85,10 @@ github.com/fatih/color v1.9.0 h1:8xPHl4/q1VyqGIPif1F+1V3Y3lSmrq01EabUW3CoW5s=
 github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL+zU=
 github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc=
 github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
-github.com/gdamore/encoding v1.0.0/go.mod h1:alR0ol34c49FCSBLjhosxzcPHQbf2trDkoo5dl+VrEg=
 github.com/gdamore/encoding v1.0.1 h1:YzKZckdBL6jVt2Gc+5p82qhrGiqMdG/eNs6Wy0u3Uhw=
 github.com/gdamore/encoding v1.0.1/go.mod h1:0Z0cMFinngz9kS1QfMjCP8TY7em3bZYeeklsSDPivEo=
-github.com/gdamore/tcell/v2 v2.7.4 h1:sg6/UnTM9jGpZU+oFYAsDahfchWAFW8Xx2yFinNSAYU=
-github.com/gdamore/tcell/v2 v2.7.4/go.mod h1:dSXtXTSK0VsW1biw65DZLZ2NKr7j0qP/0J7ONmsraWg=
+github.com/gdamore/tcell/v2 v2.8.0 h1:IDclow1j6kKpU/gOhjmc+7Pj5Dxnukb74pfKN4Cxrfg=
+github.com/gdamore/tcell/v2 v2.8.0/go.mod h1:bj8ori1BG3OYMjmb3IklZVWfZUJ1UBQt9JXrOCOhGWw=
 github.com/gliderlabs/ssh v0.2.2 h1:6zsha5zo/TWhRhwqCD3+EarCAgZ2yN28ipRnGPnwkI0=
 github.com/gliderlabs/ssh v0.2.2/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0=
 github.com/go-errors/errors v1.0.2/go.mod h1:psDX2osz5VnTOnFWbDeWwS7yejl+uV3FEWEp4lssFEs=
@@ -145,8 +144,8 @@ github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/
 github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
 github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
 github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
-github.com/google/go-cmp v0.5.6 h1:BKbKCqvP6I+rmFHt06ZmyQtvB8xAkWdhFyr0ZUNZcxQ=
-github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
+github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
+github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
 github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
 github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0=
 github.com/google/martian/v3 v3.1.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0=
@@ -188,8 +187,8 @@ github.com/jesseduffield/generics v0.0.0-20220320043834-727e535cbe68 h1:EQP2Tv8T
 github.com/jesseduffield/generics v0.0.0-20220320043834-727e535cbe68/go.mod h1:+LLj9/WUPAP8LqCchs7P+7X0R98HiFujVFANdNaxhGk=
 github.com/jesseduffield/go-git/v5 v5.1.2-0.20221018185014-fdd53fef665d h1:bO+OmbreIv91rCe8NmscRwhFSqkDJtzWCPV4Y+SQuXE=
 github.com/jesseduffield/go-git/v5 v5.1.2-0.20221018185014-fdd53fef665d/go.mod h1:nGNEErzf+NRznT+N2SWqmHnDnF9aLgANB1CUNEan09o=
-github.com/jesseduffield/gocui v0.3.1-0.20250107151125-716b1eb82fb4 h1:hSAimLVb4b5ktU3uJRtBsZW0P2dtXECReTcsHYfOy58=
-github.com/jesseduffield/gocui v0.3.1-0.20250107151125-716b1eb82fb4/go.mod h1:XtEbqCbn45keRXEu+OMZkjN5gw6AEob59afsgHjokZ8=
+github.com/jesseduffield/gocui v0.3.1-0.20250111205211-82d518436b5a h1:GLFWB8rESraTt2eIe2yssy4d4VEkCnmKbPeeZ5vCT2s=
+github.com/jesseduffield/gocui v0.3.1-0.20250111205211-82d518436b5a/go.mod h1:sLIyZ2J42R6idGdtemZzsiR3xY5EF0KsvYEGh3dQv3s=
 github.com/jesseduffield/kill v0.0.0-20250101124109-e216ddbe133a h1:UDeJ3EBk04bXDLOPvuqM3on8HvyJfISw0+UMqW+0a4g=
 github.com/jesseduffield/kill v0.0.0-20250101124109-e216ddbe133a/go.mod h1:FSWDLKT0NQpntbDd1H3lbz51fhCVlMzy/J0S6nM727Q=
 github.com/jesseduffield/lazycore v0.0.0-20221012050358-03d2e40243c5 h1:CDuQmfOjAtb1Gms6a1p5L2P8RhbLUq5t8aL7PiQd2uY=
@@ -235,7 +234,6 @@ github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hd
 github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOAqxQCu2WE=
 github.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9Y=
 github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94=
-github.com/mattn/go-runewidth v0.0.15/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
 github.com/mattn/go-runewidth v0.0.16 h1:E5ScNMtiwvlvB5paMFdw9p4kSQzbXFikJ5SQO6TULQc=
 github.com/mattn/go-runewidth v0.0.16/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
 github.com/mgutz/str v1.2.0 h1:4IzWSdIz9qPQWLfKZ0rJcV0jcUDpxvP4JVZ4GXQyvSw=
@@ -328,6 +326,9 @@ golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPh
 golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
 golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
 golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
+golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc=
+golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU=
+golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8=
 golang.org/x/crypto v0.31.0 h1:ihbySMvVjLAeSH1IbfcRTkD/iNscyz8rGzjF/E5hV6U=
 golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk=
 golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
@@ -367,6 +368,9 @@ golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
 golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
 golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
 golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
+golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
+golang.org/x/mod v0.15.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
+golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
 golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
 golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
 golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
@@ -402,6 +406,10 @@ golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v
 golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
 golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
 golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
+golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
+golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk=
+golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44=
+golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM=
 golang.org/x/net v0.33.0 h1:74SYHlV8BIgHIFC/LrYkOGIwL19eTYXQ5wc6TBuO36I=
 golang.org/x/net v0.33.0/go.mod h1:HXLR5J+9DxmrqMwG9qjGCxZ+zKXxBru04zlTvWlWuN4=
 golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
@@ -425,6 +433,9 @@ golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJ
 golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y=
+golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
+golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
 golang.org/x/sync v0.10.0 h1:3NQrjDixjgGwUOCaF8w2+VYHv0Ve/vGYSbdkTa98gmQ=
 golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
 golang.org/x/sys v0.0.0-20170407050850-f3918c30c5c2/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
@@ -475,13 +486,20 @@ golang.org/x/sys v0.0.0-20211025201205-69cdffdb9359/go.mod h1:oPkhp1MJrh7nUepCBc
 golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
+golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
 golang.org/x/sys v0.29.0 h1:TPYlXGxvx1MGTn2GiZDhnjPA9wZzZeGKHHmKhHYvgaU=
 golang.org/x/sys v0.29.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
+golang.org/x/telemetry v0.0.0-20240228155512-f48c80bd79b2/go.mod h1:TeRTkGYfJXctD9OcfyVLyj2J3IxLnKwHJR8f4D8a3YE=
 golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
 golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
 golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
+golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo=
+golang.org/x/term v0.12.0/go.mod h1:owVbMEjm3cBLCHdkQu9b1opXd4ETQWc3BhuQGKgXgvU=
 golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk=
+golang.org/x/term v0.20.0/go.mod h1:8UkIAJTvZgivsXaD6/pH6U9ecQzZ45awqEOzuCvwpFY=
 golang.org/x/term v0.28.0 h1:/Ts8HFuMR2E6IP/jlo7QVLZHggjKQbhu/7H0LJFr3Gg=
 golang.org/x/term v0.28.0/go.mod h1:Sw/lC2IAUZ92udQNf3WodGtn4k/XoLyZoh8v/8uiwek=
 golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
@@ -493,7 +511,10 @@ golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
 golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
 golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
 golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
+golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
+golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
 golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
+golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
 golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo=
 golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ=
 golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
@@ -548,6 +569,8 @@ golang.org/x/tools v0.0.0-20210108195828-e2f9c7f1fc8e/go.mod h1:emZCQorbCU4vsT4f
 golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0=
 golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
 golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
+golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58=
+golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk=
 golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
 golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
 golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
diff --git a/vendor/github.com/gdamore/tcell/v2/README-wasm.md b/vendor/github.com/gdamore/tcell/v2/README-wasm.md
index faf96856f24..278bacad3de 100644
--- a/vendor/github.com/gdamore/tcell/v2/README-wasm.md
+++ b/vendor/github.com/gdamore/tcell/v2/README-wasm.md
@@ -20,7 +20,7 @@ In `tcell.js`, you also need to change the constant
 ```js
 const wasmFilePath = "yourfile.wasm"
 ```
-to the file you outputed to when building.
+to the file you outputted to when building.
 
 ## Displaying your project
 
@@ -49,7 +49,7 @@ func main() {
 To see the webpage with this example, you can type in `localhost:8080/tcell.html` into your browser while `server.go` is running.
 
 ### Embedding
-It is recomended to use an iframe if you want to embed the app into a webpage:
+It is recommended to use an iframe if you want to embed the app into a webpage:
 ```html
 <iframe src="tcell.html" title="Tcell app"></iframe>
 ```
diff --git a/vendor/github.com/gdamore/tcell/v2/README.md b/vendor/github.com/gdamore/tcell/v2/README.md
index 37c7dea3c06..8f5a7af5605 100644
--- a/vendor/github.com/gdamore/tcell/v2/README.md
+++ b/vendor/github.com/gdamore/tcell/v2/README.md
@@ -33,7 +33,7 @@ A brief, and still somewhat rough, [tutorial](TUTORIAL.md) is available.
 - [godu](https://github.com/viktomas/godu) - utility to discover large files/folders
 - [tview](https://github.com/rivo/tview/) - rich interactive widgets
 - [cview](https://code.rocketnine.space/tslocum/cview) - user interface toolkit (fork of _tview_)
-- [awsome gocui](https://github.com/awesome-gocui/gocui) - Go Console User Interface
+- [awesome gocui](https://github.com/awesome-gocui/gocui) - Go Console User Interface
 - [gomandelbrot](https://github.com/rgm3/gomandelbrot) - Mandelbrot!
 - [WTF](https://github.com/senorprogrammer/wtf) - personal information dashboard
 - [browsh](https://github.com/browsh-org/browsh) - modern web browser ([video](https://www.youtube.com/watch?v=HZq86XfBoRo))
@@ -67,6 +67,8 @@ A brief, and still somewhat rough, [tutorial](TUTORIAL.md) is available.
 - [gbb](https://github.com/sdemingo/gbb) - A classical bulletin board app for tildes or public unix servers
 - [lil](https://github.com/andrievsky/lil) - A simple and flexible interface for any service by implementing only list and get operations
 - [hero.go](https://github.com/barisbll/hero.go) - 2d monster shooter ([video](https://user-images.githubusercontent.com/40062673/277157369-240d7606-b471-4aa1-8c54-4379a513122b.mp4))
+- [go-tetris](https://github.com/aaronriekenberg/go-tetris) - simple tetris game for native terminal and WASM using github actions+pages
+- [oddshub](https://github.com/dos-2/oddshub) - A TUI designed for analyzing sports betting odds
 
 ## Pure Go Terminfo Database
 
@@ -143,7 +145,7 @@ Most _termbox-go_ programs will probably work without further modification.
 Internally _Tcell_ uses UTF-8, just like Go.
 However, _Tcell_ understands how to
 convert to and from other character sets, using the capabilities of
-the `golang.org/x/text/encoding packages`.
+the `golang.org/x/text/encoding` packages.
 Your application must supply
 them, as the full set of the most common ones bloats the program by about 2 MB.
 If you're lazy, and want them all anyway, see the `encoding` sub-directory.
@@ -285,4 +287,4 @@ please let me know. PRs are especially welcome.
 _Tcell_ is absolutely free, but if you want to obtain commercial, professional support, there are options.
 
 - [TideLift](https://tidelift.com/) subscriptions include support for _Tcell_, as well as many other open source packages.
-- [Staysail Systems Inc.](mailto:info@staysail.tech) offers direct support, and custom development around _Tcell_ on an hourly basis.
\ No newline at end of file
+- [Staysail Systems Inc.](mailto:info@staysail.tech) offers direct support, and custom development around _Tcell_ on an hourly basis.
diff --git a/vendor/github.com/gdamore/tcell/v2/attr.go b/vendor/github.com/gdamore/tcell/v2/attr.go
index 8b1eab77581..1e7543549f5 100644
--- a/vendor/github.com/gdamore/tcell/v2/attr.go
+++ b/vendor/github.com/gdamore/tcell/v2/attr.go
@@ -1,4 +1,4 @@
-// Copyright 2020 The TCell Authors
+// Copyright 2024 The TCell Authors
 //
 // Licensed under the Apache License, Version 2.0 (the "License");
 // you may not use file except in compliance with the License.
@@ -19,15 +19,16 @@ package tcell
 type AttrMask int
 
 // Attributes are not colors, but affect the display of text.  They can
-// be combined.
+// be combined, in some cases, but not others. (E.g. you can have Dim Italic,
+// but only CurlyUnderline cannot be mixed with DottedUnderline.)
 const (
 	AttrBold AttrMask = 1 << iota
 	AttrBlink
 	AttrReverse
-	AttrUnderline
+	AttrUnderline // Deprecated: Use UnderlineStyle
 	AttrDim
 	AttrItalic
 	AttrStrikeThrough
-	AttrInvalid              // Mark the style or attributes invalid
-	AttrNone    AttrMask = 0 // Just normal text.
+	AttrInvalid AttrMask = 1 << 31 // Mark the style or attributes invalid
+	AttrNone    AttrMask = 0       // Just normal text.
 )
diff --git a/vendor/github.com/gdamore/tcell/v2/cell.go b/vendor/github.com/gdamore/tcell/v2/cell.go
index 0debeeec665..43faedb3234 100644
--- a/vendor/github.com/gdamore/tcell/v2/cell.go
+++ b/vendor/github.com/gdamore/tcell/v2/cell.go
@@ -58,7 +58,7 @@ func (cb *CellBuffer) SetContent(x int, y int,
 		// dirty as well as the base cell, to make sure we consider
 		// both cells as dirty together.  We only need to do this
 		// if we're changing content
-		if (c.width > 0) && (mainc != c.currMain || !reflect.DeepEqual(combc, c.currComb)) {
+		if (c.width > 0) && (mainc != c.currMain || len(combc) != len(c.currComb) || (len(combc) > 0 && !reflect.DeepEqual(combc, c.currComb))) {
 			for i := 0; i < c.width; i++ {
 				cb.SetDirty(x+i, y, true)
 			}
@@ -246,11 +246,4 @@ func init() {
 	if os.Getenv("RUNEWIDTH_EASTASIAN") == "" {
 		runewidth.DefaultCondition.EastAsianWidth = false
 	}
-
-	// For performance reasons, we create a lookup table.  However, some users
-	// might be more memory conscious.  If that's you, set the TCELL_MINIMIZE
-	// environment variable.
-	if os.Getenv("TCELL_MINIMIZE") == "" {
-		runewidth.CreateLUT()
-	}
 }
diff --git a/vendor/github.com/gdamore/tcell/v2/color.go b/vendor/github.com/gdamore/tcell/v2/color.go
index face860fbee..904848eaa6f 100644
--- a/vendor/github.com/gdamore/tcell/v2/color.go
+++ b/vendor/github.com/gdamore/tcell/v2/color.go
@@ -314,129 +314,129 @@ const (
 	Color253
 	Color254
 	Color255
-	ColorAliceBlue
-	ColorAntiqueWhite
-	ColorAquaMarine
-	ColorAzure
-	ColorBeige
-	ColorBisque
-	ColorBlanchedAlmond
-	ColorBlueViolet
-	ColorBrown
-	ColorBurlyWood
-	ColorCadetBlue
-	ColorChartreuse
-	ColorChocolate
-	ColorCoral
-	ColorCornflowerBlue
-	ColorCornsilk
-	ColorCrimson
-	ColorDarkBlue
-	ColorDarkCyan
-	ColorDarkGoldenrod
-	ColorDarkGray
-	ColorDarkGreen
-	ColorDarkKhaki
-	ColorDarkMagenta
-	ColorDarkOliveGreen
-	ColorDarkOrange
-	ColorDarkOrchid
-	ColorDarkRed
-	ColorDarkSalmon
-	ColorDarkSeaGreen
-	ColorDarkSlateBlue
-	ColorDarkSlateGray
-	ColorDarkTurquoise
-	ColorDarkViolet
-	ColorDeepPink
-	ColorDeepSkyBlue
-	ColorDimGray
-	ColorDodgerBlue
-	ColorFireBrick
-	ColorFloralWhite
-	ColorForestGreen
-	ColorGainsboro
-	ColorGhostWhite
-	ColorGold
-	ColorGoldenrod
-	ColorGreenYellow
-	ColorHoneydew
-	ColorHotPink
-	ColorIndianRed
-	ColorIndigo
-	ColorIvory
-	ColorKhaki
-	ColorLavender
-	ColorLavenderBlush
-	ColorLawnGreen
-	ColorLemonChiffon
-	ColorLightBlue
-	ColorLightCoral
-	ColorLightCyan
-	ColorLightGoldenrodYellow
-	ColorLightGray
-	ColorLightGreen
-	ColorLightPink
-	ColorLightSalmon
-	ColorLightSeaGreen
-	ColorLightSkyBlue
-	ColorLightSlateGray
-	ColorLightSteelBlue
-	ColorLightYellow
-	ColorLimeGreen
-	ColorLinen
-	ColorMediumAquamarine
-	ColorMediumBlue
-	ColorMediumOrchid
-	ColorMediumPurple
-	ColorMediumSeaGreen
-	ColorMediumSlateBlue
-	ColorMediumSpringGreen
-	ColorMediumTurquoise
-	ColorMediumVioletRed
-	ColorMidnightBlue
-	ColorMintCream
-	ColorMistyRose
-	ColorMoccasin
-	ColorNavajoWhite
-	ColorOldLace
-	ColorOliveDrab
-	ColorOrange
-	ColorOrangeRed
-	ColorOrchid
-	ColorPaleGoldenrod
-	ColorPaleGreen
-	ColorPaleTurquoise
-	ColorPaleVioletRed
-	ColorPapayaWhip
-	ColorPeachPuff
-	ColorPeru
-	ColorPink
-	ColorPlum
-	ColorPowderBlue
-	ColorRebeccaPurple
-	ColorRosyBrown
-	ColorRoyalBlue
-	ColorSaddleBrown
-	ColorSalmon
-	ColorSandyBrown
-	ColorSeaGreen
-	ColorSeashell
-	ColorSienna
-	ColorSkyblue
-	ColorSlateBlue
-	ColorSlateGray
-	ColorSnow
-	ColorSpringGreen
-	ColorSteelBlue
-	ColorTan
-	ColorThistle
-	ColorTomato
-	ColorTurquoise
-	ColorViolet
-	ColorWheat
-	ColorWhiteSmoke
-	ColorYellowGreen
+	ColorAliceBlue            = ColorIsRGB | ColorValid | 0xF0F8FF
+	ColorAntiqueWhite         = ColorIsRGB | ColorValid | 0xFAEBD7
+	ColorAquaMarine           = ColorIsRGB | ColorValid | 0x7FFFD4
+	ColorAzure                = ColorIsRGB | ColorValid | 0xF0FFFF
+	ColorBeige                = ColorIsRGB | ColorValid | 0xF5F5DC
+	ColorBisque               = ColorIsRGB | ColorValid | 0xFFE4C4
+	ColorBlanchedAlmond       = ColorIsRGB | ColorValid | 0xFFEBCD
+	ColorBlueViolet           = ColorIsRGB | ColorValid | 0x8A2BE2
+	ColorBrown                = ColorIsRGB | ColorValid | 0xA52A2A
+	ColorBurlyWood            = ColorIsRGB | ColorValid | 0xDEB887
+	ColorCadetBlue            = ColorIsRGB | ColorValid | 0x5F9EA0
+	ColorChartreuse           = ColorIsRGB | ColorValid | 0x7FFF00
+	ColorChocolate            = ColorIsRGB | ColorValid | 0xD2691E
+	ColorCoral                = ColorIsRGB | ColorValid | 0xFF7F50
+	ColorCornflowerBlue       = ColorIsRGB | ColorValid | 0x6495ED
+	ColorCornsilk             = ColorIsRGB | ColorValid | 0xFFF8DC
+	ColorCrimson              = ColorIsRGB | ColorValid | 0xDC143C
+	ColorDarkBlue             = ColorIsRGB | ColorValid | 0x00008B
+	ColorDarkCyan             = ColorIsRGB | ColorValid | 0x008B8B
+	ColorDarkGoldenrod        = ColorIsRGB | ColorValid | 0xB8860B
+	ColorDarkGray             = ColorIsRGB | ColorValid | 0xA9A9A9
+	ColorDarkGreen            = ColorIsRGB | ColorValid | 0x006400
+	ColorDarkKhaki            = ColorIsRGB | ColorValid | 0xBDB76B
+	ColorDarkMagenta          = ColorIsRGB | ColorValid | 0x8B008B
+	ColorDarkOliveGreen       = ColorIsRGB | ColorValid | 0x556B2F
+	ColorDarkOrange           = ColorIsRGB | ColorValid | 0xFF8C00
+	ColorDarkOrchid           = ColorIsRGB | ColorValid | 0x9932CC
+	ColorDarkRed              = ColorIsRGB | ColorValid | 0x8B0000
+	ColorDarkSalmon           = ColorIsRGB | ColorValid | 0xE9967A
+	ColorDarkSeaGreen         = ColorIsRGB | ColorValid | 0x8FBC8F
+	ColorDarkSlateBlue        = ColorIsRGB | ColorValid | 0x483D8B
+	ColorDarkSlateGray        = ColorIsRGB | ColorValid | 0x2F4F4F
+	ColorDarkTurquoise        = ColorIsRGB | ColorValid | 0x00CED1
+	ColorDarkViolet           = ColorIsRGB | ColorValid | 0x9400D3
+	ColorDeepPink             = ColorIsRGB | ColorValid | 0xFF1493
+	ColorDeepSkyBlue          = ColorIsRGB | ColorValid | 0x00BFFF
+	ColorDimGray              = ColorIsRGB | ColorValid | 0x696969
+	ColorDodgerBlue           = ColorIsRGB | ColorValid | 0x1E90FF
+	ColorFireBrick            = ColorIsRGB | ColorValid | 0xB22222
+	ColorFloralWhite          = ColorIsRGB | ColorValid | 0xFFFAF0
+	ColorForestGreen          = ColorIsRGB | ColorValid | 0x228B22
+	ColorGainsboro            = ColorIsRGB | ColorValid | 0xDCDCDC
+	ColorGhostWhite           = ColorIsRGB | ColorValid | 0xF8F8FF
+	ColorGold                 = ColorIsRGB | ColorValid | 0xFFD700
+	ColorGoldenrod            = ColorIsRGB | ColorValid | 0xDAA520
+	ColorGreenYellow          = ColorIsRGB | ColorValid | 0xADFF2F
+	ColorHoneydew             = ColorIsRGB | ColorValid | 0xF0FFF0
+	ColorHotPink              = ColorIsRGB | ColorValid | 0xFF69B4
+	ColorIndianRed            = ColorIsRGB | ColorValid | 0xCD5C5C
+	ColorIndigo               = ColorIsRGB | ColorValid | 0x4B0082
+	ColorIvory                = ColorIsRGB | ColorValid | 0xFFFFF0
+	ColorKhaki                = ColorIsRGB | ColorValid | 0xF0E68C
+	ColorLavender             = ColorIsRGB | ColorValid | 0xE6E6FA
+	ColorLavenderBlush        = ColorIsRGB | ColorValid | 0xFFF0F5
+	ColorLawnGreen            = ColorIsRGB | ColorValid | 0x7CFC00
+	ColorLemonChiffon         = ColorIsRGB | ColorValid | 0xFFFACD
+	ColorLightBlue            = ColorIsRGB | ColorValid | 0xADD8E6
+	ColorLightCoral           = ColorIsRGB | ColorValid | 0xF08080
+	ColorLightCyan            = ColorIsRGB | ColorValid | 0xE0FFFF
+	ColorLightGoldenrodYellow = ColorIsRGB | ColorValid | 0xFAFAD2
+	ColorLightGray            = ColorIsRGB | ColorValid | 0xD3D3D3
+	ColorLightGreen           = ColorIsRGB | ColorValid | 0x90EE90
+	ColorLightPink            = ColorIsRGB | ColorValid | 0xFFB6C1
+	ColorLightSalmon          = ColorIsRGB | ColorValid | 0xFFA07A
+	ColorLightSeaGreen        = ColorIsRGB | ColorValid | 0x20B2AA
+	ColorLightSkyBlue         = ColorIsRGB | ColorValid | 0x87CEFA
+	ColorLightSlateGray       = ColorIsRGB | ColorValid | 0x778899
+	ColorLightSteelBlue       = ColorIsRGB | ColorValid | 0xB0C4DE
+	ColorLightYellow          = ColorIsRGB | ColorValid | 0xFFFFE0
+	ColorLimeGreen            = ColorIsRGB | ColorValid | 0x32CD32
+	ColorLinen                = ColorIsRGB | ColorValid | 0xFAF0E6
+	ColorMediumAquamarine     = ColorIsRGB | ColorValid | 0x66CDAA
+	ColorMediumBlue           = ColorIsRGB | ColorValid | 0x0000CD
+	ColorMediumOrchid         = ColorIsRGB | ColorValid | 0xBA55D3
+	ColorMediumPurple         = ColorIsRGB | ColorValid | 0x9370DB
+	ColorMediumSeaGreen       = ColorIsRGB | ColorValid | 0x3CB371
+	ColorMediumSlateBlue      = ColorIsRGB | ColorValid | 0x7B68EE
+	ColorMediumSpringGreen    = ColorIsRGB | ColorValid | 0x00FA9A
+	ColorMediumTurquoise      = ColorIsRGB | ColorValid | 0x48D1CC
+	ColorMediumVioletRed      = ColorIsRGB | ColorValid | 0xC71585
+	ColorMidnightBlue         = ColorIsRGB | ColorValid | 0x191970
+	ColorMintCream            = ColorIsRGB | ColorValid | 0xF5FFFA
+	ColorMistyRose            = ColorIsRGB | ColorValid | 0xFFE4E1
+	ColorMoccasin             = ColorIsRGB | ColorValid | 0xFFE4B5
+	ColorNavajoWhite          = ColorIsRGB | ColorValid | 0xFFDEAD
+	ColorOldLace              = ColorIsRGB | ColorValid | 0xFDF5E6
+	ColorOliveDrab            = ColorIsRGB | ColorValid | 0x6B8E23
+	ColorOrange               = ColorIsRGB | ColorValid | 0xFFA500
+	ColorOrangeRed            = ColorIsRGB | ColorValid | 0xFF4500
+	ColorOrchid               = ColorIsRGB | ColorValid | 0xDA70D6
+	ColorPaleGoldenrod        = ColorIsRGB | ColorValid | 0xEEE8AA
+	ColorPaleGreen            = ColorIsRGB | ColorValid | 0x98FB98
+	ColorPaleTurquoise        = ColorIsRGB | ColorValid | 0xAFEEEE
+	ColorPaleVioletRed        = ColorIsRGB | ColorValid | 0xDB7093
+	ColorPapayaWhip           = ColorIsRGB | ColorValid | 0xFFEFD5
+	ColorPeachPuff            = ColorIsRGB | ColorValid | 0xFFDAB9
+	ColorPeru                 = ColorIsRGB | ColorValid | 0xCD853F
+	ColorPink                 = ColorIsRGB | ColorValid | 0xFFC0CB
+	ColorPlum                 = ColorIsRGB | ColorValid | 0xDDA0DD
+	ColorPowderBlue           = ColorIsRGB | ColorValid | 0xB0E0E6
+	ColorRebeccaPurple        = ColorIsRGB | ColorValid | 0x663399
+	ColorRosyBrown            = ColorIsRGB | ColorValid | 0xBC8F8F
+	ColorRoyalBlue            = ColorIsRGB | ColorValid | 0x4169E1
+	ColorSaddleBrown          = ColorIsRGB | ColorValid | 0x8B4513
+	ColorSalmon               = ColorIsRGB | ColorValid | 0xFA8072
+	ColorSandyBrown           = ColorIsRGB | ColorValid | 0xF4A460
+	ColorSeaGreen             = ColorIsRGB | ColorValid | 0x2E8B57
+	ColorSeashell             = ColorIsRGB | ColorValid | 0xFFF5EE
+	ColorSienna               = ColorIsRGB | ColorValid | 0xA0522D
+	ColorSkyblue              = ColorIsRGB | ColorValid | 0x87CEEB
+	ColorSlateBlue            = ColorIsRGB | ColorValid | 0x6A5ACD
+	ColorSlateGray            = ColorIsRGB | ColorValid | 0x708090
+	ColorSnow                 = ColorIsRGB | ColorValid | 0xFFFAFA
+	ColorSpringGreen          = ColorIsRGB | ColorValid | 0x00FF7F
+	ColorSteelBlue            = ColorIsRGB | ColorValid | 0x4682B4
+	ColorTan                  = ColorIsRGB | ColorValid | 0xD2B48C
+	ColorThistle              = ColorIsRGB | ColorValid | 0xD8BFD8
+	ColorTomato               = ColorIsRGB | ColorValid | 0xFF6347
+	ColorTurquoise            = ColorIsRGB | ColorValid | 0x40E0D0
+	ColorViolet               = ColorIsRGB | ColorValid | 0xEE82EE
+	ColorWheat                = ColorIsRGB | ColorValid | 0xF5DEB3
+	ColorWhiteSmoke           = ColorIsRGB | ColorValid | 0xF5F5F5
+	ColorYellowGreen          = ColorIsRGB | ColorValid | 0x9ACD32
 )
 
 // These are aliases for the color gray, because some of us spell
diff --git a/vendor/github.com/gdamore/tcell/v2/console_win.go b/vendor/github.com/gdamore/tcell/v2/console_win.go
index e2652509eed..78077175203 100644
--- a/vendor/github.com/gdamore/tcell/v2/console_win.go
+++ b/vendor/github.com/gdamore/tcell/v2/console_win.go
@@ -42,6 +42,7 @@ type cScreen struct {
 	truecolor  bool
 	running    bool
 	disableAlt bool // disable the alternate screen
+	title      string
 
 	w int
 	h int
@@ -49,6 +50,7 @@ type cScreen struct {
 	oscreen     consoleInfo
 	ocursor     cursorInfo
 	cursorStyle CursorStyle
+	cursorColor Color
 	oimode      uint32
 	oomode      uint32
 	cells       CellBuffer
@@ -164,6 +166,20 @@ const (
 	vtEnableAm                = "\x1b[?7h"
 	vtEnterCA                 = "\x1b[?1049h\x1b[22;0;0t"
 	vtExitCA                  = "\x1b[?1049l\x1b[23;0;0t"
+	vtDoubleUnderline         = "\x1b[4:2m"
+	vtCurlyUnderline          = "\x1b[4:3m"
+	vtDottedUnderline         = "\x1b[4:4m"
+	vtDashedUnderline         = "\x1b[4:5m"
+	vtUnderColor              = "\x1b[58:5:%dm"
+	vtUnderColorRGB           = "\x1b[58:2::%d:%d:%dm"
+	vtUnderColorReset         = "\x1b[59m"
+	vtEnterUrl                = "\x1b]8;%s;%s\x1b\\" // NB arg 1 is id, arg 2 is url
+	vtExitUrl                 = "\x1b]8;;\x1b\\"
+	vtCursorColorRGB          = "\x1b]12;#%02x%02x%02x\007"
+	vtCursorColorReset        = "\x1b]112\007"
+	vtSaveTitle               = "\x1b[22;2t"
+	vtRestoreTitle            = "\x1b[23;2t"
+	vtSetTitle                = "\x1b]2;%s\x1b\\"
 )
 
 var vtCursorStyles = map[CursorStyle]string{
@@ -335,8 +351,10 @@ func (s *cScreen) disengage() {
 
 	if s.vten {
 		s.emitVtString(vtCursorStyles[CursorStyleDefault])
+		s.emitVtString(vtCursorColorReset)
 		s.emitVtString(vtEnableAm)
 		if !s.disableAlt {
+			s.emitVtString(vtRestoreTitle)
 			s.emitVtString(vtExitCA)
 		}
 	} else if !s.disableAlt {
@@ -374,9 +392,13 @@ func (s *cScreen) engage() error {
 	if s.vten {
 		s.setOutMode(modeVtOutput | modeNoAutoNL | modeCookedOut | modeUnderline)
 		if !s.disableAlt {
+			s.emitVtString(vtSaveTitle)
 			s.emitVtString(vtEnterCA)
 		}
 		s.emitVtString(vtDisableAm)
+		if s.title != "" {
+			s.emitVtString(fmt.Sprintf(vtSetTitle, s.title))
+		}
 	} else {
 		s.setOutMode(0)
 	}
@@ -426,6 +448,12 @@ func (s *cScreen) showCursor() {
 	if s.vten {
 		s.emitVtString(vtShowCursor)
 		s.emitVtString(vtCursorStyles[s.cursorStyle])
+		if s.cursorColor == ColorReset {
+			s.emitVtString(vtCursorColorReset)
+		} else if s.cursorColor.Valid() {
+			r, g, b := s.cursorColor.RGB()
+			s.emitVtString(fmt.Sprintf(vtCursorColorRGB, r, g, b))
+		}
 	} else {
 		s.setCursorInfo(&cursorInfo{size: 100, visible: 1})
 	}
@@ -449,11 +477,12 @@ func (s *cScreen) ShowCursor(x, y int) {
 	s.Unlock()
 }
 
-func (s *cScreen) SetCursorStyle(cs CursorStyle) {
+func (s *cScreen) SetCursor(cs CursorStyle, cc Color) {
 	s.Lock()
 	if !s.fini {
 		if _, ok := vtCursorStyles[cs]; ok {
 			s.cursorStyle = cs
+			s.cursorColor = cc
 			s.doCursor()
 		}
 	}
@@ -875,7 +904,7 @@ func mapColor2RGB(c Color) uint16 {
 
 // Map a tcell style to Windows attributes
 func (s *cScreen) mapStyle(style Style) uint16 {
-	f, b, a := style.Decompose()
+	f, b, a := style.fg, style.bg, style.attrs
 	fa := s.oscreen.attrs & 0xf
 	ba := (s.oscreen.attrs) >> 4 & 0xf
 	if f != ColorDefault && f != ColorReset {
@@ -912,19 +941,41 @@ func (s *cScreen) mapStyle(style Style) uint16 {
 func (s *cScreen) sendVtStyle(style Style) {
 	esc := &strings.Builder{}
 
-	fg, bg, attrs := style.Decompose()
+	fg, bg, attrs := style.fg, style.bg, style.attrs
+	us, uc := style.ulStyle, style.ulColor
 
 	esc.WriteString(vtSgr0)
-
 	if attrs&(AttrBold|AttrDim) == AttrBold {
 		esc.WriteString(vtBold)
 	}
 	if attrs&AttrBlink != 0 {
 		esc.WriteString(vtBlink)
 	}
-	if attrs&AttrUnderline != 0 {
+	if us != UnderlineStyleNone {
+		if uc == ColorReset {
+			esc.WriteString(vtUnderColorReset)
+		} else if uc.IsRGB() {
+			r, g, b := uc.RGB()
+			_, _ = fmt.Fprintf(esc, vtUnderColorRGB, int(r), int(g), int(b))
+		} else if uc.Valid() {
+			_, _ = fmt.Fprintf(esc, vtUnderColor, uc&0xff)
+		}
+
 		esc.WriteString(vtUnderline)
+		// legacy ConHost does not understand these but Terminal does
+		switch us {
+		case UnderlineStyleSolid:
+		case UnderlineStyleDouble:
+			esc.WriteString(vtDoubleUnderline)
+		case UnderlineStyleCurly:
+			esc.WriteString(vtCurlyUnderline)
+		case UnderlineStyleDotted:
+			esc.WriteString(vtDottedUnderline)
+		case UnderlineStyleDashed:
+			esc.WriteString(vtDashedUnderline)
+		}
 	}
+
 	if attrs&AttrReverse != 0 {
 		esc.WriteString(vtReverse)
 	}
@@ -940,6 +991,13 @@ func (s *cScreen) sendVtStyle(style Style) {
 	} else if bg.Valid() {
 		_, _ = fmt.Fprintf(esc, vtSetBg, bg&0xff)
 	}
+	// URL string can be long, so don't send it unless we really need to
+	if style.url != "" {
+		_, _ = fmt.Fprintf(esc, vtEnterUrl, style.urlId, style.url)
+	} else {
+		esc.WriteString(vtExitUrl)
+	}
+
 	s.emitVtString(esc.String())
 }
 
@@ -1062,7 +1120,6 @@ func (s *cScreen) setCursorInfo(info *cursorInfo) {
 	_, _, _ = procSetConsoleCursorInfo.Call(
 		uintptr(s.out),
 		uintptr(unsafe.Pointer(info)))
-
 }
 
 func (s *cScreen) setCursorPos(x, y int, vtEnable bool) {
@@ -1227,6 +1284,15 @@ func (s *cScreen) SetStyle(style Style) {
 	s.Unlock()
 }
 
+func (s *cScreen) SetTitle(title string) {
+	s.Lock()
+	s.title = title
+	if s.vten {
+		s.emitVtString(fmt.Sprintf(vtSetTitle, title))
+	}
+	s.Unlock()
+}
+
 // No fallback rune support, since we have Unicode.  Yay!
 
 func (s *cScreen) RegisterRuneFallback(_ rune, _ string) {
@@ -1246,6 +1312,12 @@ func (s *cScreen) HasMouse() bool {
 	return true
 }
 
+func (s *cScreen) SetClipboard(_ []byte) {
+}
+
+func (s *cScreen) GetClipboard() {
+}
+
 func (s *cScreen) Resize(int, int, int, int) {}
 
 func (s *cScreen) HasKey(k Key) bool {
diff --git a/vendor/github.com/gdamore/tcell/v2/paste.go b/vendor/github.com/gdamore/tcell/v2/paste.go
index cbe6979f93b..f511f63cb59 100644
--- a/vendor/github.com/gdamore/tcell/v2/paste.go
+++ b/vendor/github.com/gdamore/tcell/v2/paste.go
@@ -1,4 +1,4 @@
-// Copyright 2020 The TCell Authors
+// Copyright 2024 The TCell Authors
 //
 // Licensed under the Apache License, Version 2.0 (the "License");
 // you may not use file except in compliance with the License.
@@ -19,12 +19,14 @@ import (
 )
 
 // EventPaste is used to mark the start and end of a bracketed paste.
-// An event with .Start() true will be sent to mark the start.
-// Then a number of keys will be sent to indicate that the content
-// is pasted in.  At the end, an event with .Start() false will be sent.
+//
+// An event with .Start() true will be sent to mark the start of a bracketed paste,
+// followed by a number of keys (string data) for the content, ending with the
+// an event with .End() true.
 type EventPaste struct {
 	start bool
 	t     time.Time
+	data  []byte
 }
 
 // When returns the time when this EventPaste was created.
@@ -46,3 +48,25 @@ func (ev *EventPaste) End() bool {
 func NewEventPaste(start bool) *EventPaste {
 	return &EventPaste{t: time.Now(), start: start}
 }
+
+// NewEventClipboard returns a new NewEventClipboard with a data payload
+func NewEventClipboard(data []byte) *EventClipboard {
+	return &EventClipboard{t: time.Now(), data: data}
+}
+
+// EventClipboard represents data from the clipboard,
+// in response to a GetClipboard request.
+type EventClipboard struct {
+	t    time.Time
+	data []byte
+}
+
+// Data returns the attached binary data.
+func (ev *EventClipboard) Data() []byte {
+	return ev.data
+}
+
+// When returns the time when this event was created.
+func (ev *EventClipboard) When() time.Time {
+	return ev.t
+}
diff --git a/vendor/github.com/gdamore/tcell/v2/screen.go b/vendor/github.com/gdamore/tcell/v2/screen.go
index 6ab27ca96cd..18dc551912b 100644
--- a/vendor/github.com/gdamore/tcell/v2/screen.go
+++ b/vendor/github.com/gdamore/tcell/v2/screen.go
@@ -1,4 +1,4 @@
-// Copyright 2023 The TCell Authors
+// Copyright 2024 The TCell Authors
 //
 // Licensed under the Apache License, Version 2.0 (the "License");
 // you may not use file except in compliance with the License.
@@ -79,8 +79,9 @@ type Screen interface {
 
 	// SetCursorStyle is used to set the cursor style.  If the style
 	// is not supported (or cursor styles are not supported at all),
-	// then this will have no effect.
-	SetCursorStyle(CursorStyle)
+	// then this will have no effect.  Color will be changed if supplied,
+	// and the terminal supports doing so.
+	SetCursorStyle(CursorStyle, ...Color)
 
 	// Size returns the screen size as width, height.  This changes in
 	// response to a call to Clear or Flush.
@@ -265,6 +266,23 @@ type Screen interface {
 	// Tty returns the underlying Tty. If the screen is not a terminal, the
 	// returned bool will be false
 	Tty() (Tty, bool)
+
+	// SetTitle sets a window title on the screen.
+	// Terminals may be configured to ignore this, or unable to.
+	// Tcell may attempt to save and restore the window title on entry and exit, but
+	// the results may vary.  Use of unicode characters may not be supported.
+	SetTitle(string)
+
+	// SetClipboard is used to post arbitrary data to the system clipboard.
+	// This need not be UTF-8 string data.  It's up to the recipient to decode the
+	// data meaningfully.  Terminals may prevent this for security reasons.
+	SetClipboard([]byte)
+
+	// GetClipboard is used to request the clipboard contents.  It may be ignored.
+	// If the terminal is willing, it will be post the clipboard contents using an
+	// EventPaste with the clipboard content as the Data() field.  Terminals may
+	// prevent this for security reasons.
+	GetClipboard()
 }
 
 // NewScreen returns a default Screen suitable for the user's terminal
@@ -312,7 +330,7 @@ type screenImpl interface {
 	SetStyle(style Style)
 	ShowCursor(x int, y int)
 	HideCursor()
-	SetCursorStyle(CursorStyle)
+	SetCursor(CursorStyle, Color)
 	Size() (width, height int)
 	EnableMouse(...MouseFlags)
 	DisableMouse()
@@ -334,7 +352,10 @@ type screenImpl interface {
 	Resume() error
 	Beep() error
 	SetSize(int, int)
+	SetTitle(string)
 	Tty() (Tty, bool)
+	SetClipboard([]byte)
+	GetClipboard()
 
 	// Following methods are not part of the Screen api, but are used for interaction with
 	// the common layer code.
@@ -464,3 +485,11 @@ func (b *baseScreen) PostEvent(ev Event) error {
 		return ErrEventQFull
 	}
 }
+
+func (b *baseScreen) SetCursorStyle(cs CursorStyle, ccs ...Color) {
+	if len(ccs) > 0 {
+		b.SetCursor(cs, ccs[0])
+	} else {
+		b.SetCursor(cs, ColorNone)
+	}
+}
diff --git a/vendor/github.com/gdamore/tcell/v2/simulation.go b/vendor/github.com/gdamore/tcell/v2/simulation.go
index eb08b8fe927..66efaa94e10 100644
--- a/vendor/github.com/gdamore/tcell/v2/simulation.go
+++ b/vendor/github.com/gdamore/tcell/v2/simulation.go
@@ -1,4 +1,4 @@
-// Copyright 2023 The TCell Authors
+// Copyright 2024 The TCell Authors
 //
 // Licensed under the Apache License, Version 2.0 (the "License");
 // you may not use file except in compliance with the License.
@@ -60,6 +60,12 @@ type SimulationScreen interface {
 
 	// GetCursor returns the cursor details.
 	GetCursor() (x int, y int, visible bool)
+
+	// GetTitle gets the previously set title.
+	GetTitle() string
+
+	// GetClipboardData gets the actual data for the clipboard.
+	GetClipboardData() []byte
 }
 
 // SimCell represents a simulated screen cell.  The purpose of this
@@ -98,6 +104,8 @@ type simscreen struct {
 	fillchar  rune
 	fillstyle Style
 	fallback  map[rune]string
+	title     string
+	clipboard []byte
 
 	Screen
 	sync.Mutex
@@ -239,7 +247,7 @@ func (s *simscreen) hideCursor() {
 	s.cursorvis = false
 }
 
-func (s *simscreen) SetCursorStyle(CursorStyle) {}
+func (s *simscreen) SetCursor(CursorStyle, Color) {}
 
 func (s *simscreen) Show() {
 	s.Lock()
@@ -495,3 +503,26 @@ func (s *simscreen) EventQ() chan Event {
 func (s *simscreen) StopQ() <-chan struct{} {
 	return s.quit
 }
+
+func (s *simscreen) SetTitle(title string) {
+	s.title = title
+}
+
+func (s *simscreen) GetTitle() string {
+	return s.title
+}
+
+func (s *simscreen) SetClipboard(data []byte) {
+	s.clipboard = data
+}
+
+func (s *simscreen) GetClipboard() {
+	if s.clipboard != nil {
+		ev := NewEventClipboard(s.clipboard)
+		s.postEvent(ev)
+	}
+}
+
+func (s *simscreen) GetClipboardData() []byte {
+	return s.clipboard
+}
diff --git a/vendor/github.com/gdamore/tcell/v2/style.go b/vendor/github.com/gdamore/tcell/v2/style.go
index 98354c85386..14d05b15dd0 100644
--- a/vendor/github.com/gdamore/tcell/v2/style.go
+++ b/vendor/github.com/gdamore/tcell/v2/style.go
@@ -1,4 +1,4 @@
-// Copyright 2022 The TCell Authors
+// Copyright 2024 The TCell Authors
 //
 // Licensed under the Apache License, Version 2.0 (the "License");
 // you may not use file except in compliance with the License.
@@ -23,11 +23,13 @@ package tcell
 //
 // To use Style, just declare a variable of its type.
 type Style struct {
-	fg    Color
-	bg    Color
-	attrs AttrMask
-	url   string
-	urlId string
+	fg      Color
+	bg      Color
+	ulStyle UnderlineStyle
+	ulColor Color
+	attrs   AttrMask
+	url     string
+	urlId   string
 }
 
 // StyleDefault represents a default style, based upon the context.
@@ -40,50 +42,35 @@ var styleInvalid = Style{attrs: AttrInvalid}
 // Foreground returns a new style based on s, with the foreground color set
 // as requested.  ColorDefault can be used to select the global default.
 func (s Style) Foreground(c Color) Style {
-	return Style{
-		fg:    c,
-		bg:    s.bg,
-		attrs: s.attrs,
-		url:   s.url,
-		urlId: s.urlId,
-	}
+	s2 := s
+	s2.fg = c
+	return s2
 }
 
 // Background returns a new style based on s, with the background color set
 // as requested.  ColorDefault can be used to select the global default.
 func (s Style) Background(c Color) Style {
-	return Style{
-		fg:    s.fg,
-		bg:    c,
-		attrs: s.attrs,
-		url:   s.url,
-		urlId: s.urlId,
-	}
+	s2 := s
+	s2.bg = c
+	return s2
 }
 
 // Decompose breaks a style up, returning the foreground, background,
 // and other attributes.  The URL if set is not included.
+// Deprecated: Applications should not attempt to decompose style,
+// as this content is not sufficient to describe the actual style.
 func (s Style) Decompose() (fg Color, bg Color, attr AttrMask) {
 	return s.fg, s.bg, s.attrs
 }
 
 func (s Style) setAttrs(attrs AttrMask, on bool) Style {
+	s2 := s
 	if on {
-		return Style{
-			fg:    s.fg,
-			bg:    s.bg,
-			attrs: s.attrs | attrs,
-			url:   s.url,
-			urlId: s.urlId,
-		}
-	}
-	return Style{
-		fg:    s.fg,
-		bg:    s.bg,
-		attrs: s.attrs &^ attrs,
-		url:   s.url,
-		urlId: s.urlId,
+		s2.attrs |= attrs
+	} else {
+		s2.attrs &^= attrs
 	}
+	return s2
 }
 
 // Normal returns the style with all attributes disabled.
@@ -125,40 +112,73 @@ func (s Style) Reverse(on bool) Style {
 	return s.setAttrs(AttrReverse, on)
 }
 
-// Underline returns a new style based on s, with the underline attribute set
-// as requested.
-func (s Style) Underline(on bool) Style {
-	return s.setAttrs(AttrUnderline, on)
-}
-
 // StrikeThrough sets strikethrough mode.
 func (s Style) StrikeThrough(on bool) Style {
 	return s.setAttrs(AttrStrikeThrough, on)
 }
 
+// Underline style.  Modern terminals have the option of rendering the
+// underline using different styles, and even different colors.
+type UnderlineStyle int
+
+const (
+	UnderlineStyleNone = UnderlineStyle(iota)
+	UnderlineStyleSolid
+	UnderlineStyleDouble
+	UnderlineStyleCurly
+	UnderlineStyleDotted
+	UnderlineStyleDashed
+)
+
+// Underline returns a new style based on s, with the underline attribute set
+// as requested.  The parameters can be:
+//
+// bool: on / off - enables just a simple underline
+// UnderlineStyle: sets a specific style (should not coexist with the bool)
+// Color: the color to use
+func (s Style) Underline(params ...interface{}) Style {
+	s2 := s
+	for _, param := range params {
+		switch v := param.(type) {
+		case bool:
+			if v {
+				s2.ulStyle = UnderlineStyleSolid
+				s2.attrs |= AttrUnderline
+			} else {
+				s2.ulStyle = UnderlineStyleNone
+				s2.attrs &^= AttrUnderline
+			}
+		case UnderlineStyle:
+			if v == UnderlineStyleNone {
+				s2.attrs &^= AttrUnderline
+			} else {
+				s2.attrs |= AttrUnderline
+			}
+			s2.ulStyle = v
+		case Color:
+			s2.ulColor = v
+		default:
+			panic("Bad type for underline")
+		}
+	}
+	return s2
+}
+
 // Attributes returns a new style based on s, with its attributes set as
 // specified.
 func (s Style) Attributes(attrs AttrMask) Style {
-	return Style{
-		fg:    s.fg,
-		bg:    s.bg,
-		attrs: attrs,
-		url:   s.url,
-		urlId: s.urlId,
-	}
+	s2 := s
+	s2.attrs = attrs
+	return s2
 }
 
 // Url returns a style with the Url set.  If the provided Url is not empty,
 // and the terminal supports it, text will typically be marked up as a clickable
 // link to that Url.  If the Url is empty, then this mode is turned off.
 func (s Style) Url(url string) Style {
-	return Style{
-		fg:    s.fg,
-		bg:    s.bg,
-		attrs: s.attrs,
-		url:   url,
-		urlId: s.urlId,
-	}
+	s2 := s
+	s2.url = url
+	return s2
 }
 
 // UrlId returns a style with the UrlId set. If the provided UrlId is not empty,
@@ -166,11 +186,7 @@ func (s Style) Url(url string) Style {
 // terminal supports it, any text with the same UrlId will be grouped as if it
 // were one Url, even if it spans multiple lines.
 func (s Style) UrlId(id string) Style {
-	return Style{
-		fg:    s.fg,
-		bg:    s.bg,
-		attrs: s.attrs,
-		url:   s.url,
-		urlId: "id=" + id,
-	}
+	s2 := s
+	s2.urlId = "id=" + id
+	return s2
 }
diff --git a/vendor/github.com/gdamore/tcell/v2/terminfo/a/alacritty/term.go b/vendor/github.com/gdamore/tcell/v2/terminfo/a/alacritty/term.go
index 010136372ae..a82d6dbef62 100644
--- a/vendor/github.com/gdamore/tcell/v2/terminfo/a/alacritty/term.go
+++ b/vendor/github.com/gdamore/tcell/v2/terminfo/a/alacritty/term.go
@@ -67,5 +67,10 @@ func init() {
 		KeyBacktab:        "\x1b[Z",
 		Modifiers:         1,
 		AutoMargin:        true,
+		DoubleUnderline:   "\x1b[4:2m",
+		CurlyUnderline:    "\x1b[4:3m",
+		DottedUnderline:   "\x1b[4:4m",
+		DashedUnderline:   "\x1b[4:5m",
+		XTermLike:         true,
 	})
 }
diff --git a/vendor/github.com/gdamore/tcell/v2/terminfo/base/base.go b/vendor/github.com/gdamore/tcell/v2/terminfo/base/base.go
index fbecdfa93e9..d54a381fd4d 100644
--- a/vendor/github.com/gdamore/tcell/v2/terminfo/base/base.go
+++ b/vendor/github.com/gdamore/tcell/v2/terminfo/base/base.go
@@ -23,7 +23,7 @@ package base
 
 import (
 	// The following imports just register themselves --
-	// thse are the terminal types we aggregate in this package.
+	// these are the terminal types we aggregate in this package.
 	_ "github.com/gdamore/tcell/v2/terminfo/a/ansi"
 	_ "github.com/gdamore/tcell/v2/terminfo/v/vt100"
 	_ "github.com/gdamore/tcell/v2/terminfo/v/vt102"
diff --git a/vendor/github.com/gdamore/tcell/v2/terminfo/extended/extended.go b/vendor/github.com/gdamore/tcell/v2/terminfo/extended/extended.go
index 7459cf32b77..6e5c2e6c897 100644
--- a/vendor/github.com/gdamore/tcell/v2/terminfo/extended/extended.go
+++ b/vendor/github.com/gdamore/tcell/v2/terminfo/extended/extended.go
@@ -52,5 +52,6 @@ import (
 	_ "github.com/gdamore/tcell/v2/terminfo/w/wy99_ansi"
 	_ "github.com/gdamore/tcell/v2/terminfo/x/xfce"
 	_ "github.com/gdamore/tcell/v2/terminfo/x/xterm"
+	_ "github.com/gdamore/tcell/v2/terminfo/x/xterm_ghostty"
 	_ "github.com/gdamore/tcell/v2/terminfo/x/xterm_kitty"
 )
diff --git a/vendor/github.com/gdamore/tcell/v2/terminfo/g/gnome/term.go b/vendor/github.com/gdamore/tcell/v2/terminfo/g/gnome/term.go
index a7af10c45ec..4a81122ac1a 100644
--- a/vendor/github.com/gdamore/tcell/v2/terminfo/g/gnome/term.go
+++ b/vendor/github.com/gdamore/tcell/v2/terminfo/g/gnome/term.go
@@ -67,6 +67,7 @@ func init() {
 		KeyBacktab:        "\x1b[Z",
 		Modifiers:         1,
 		AutoMargin:        true,
+		XTermLike:         true,
 	})
 
 	// GNOME Terminal with xterm 256-colors
@@ -130,5 +131,6 @@ func init() {
 		KeyBacktab:        "\x1b[Z",
 		Modifiers:         1,
 		AutoMargin:        true,
+		XTermLike:         true,
 	})
 }
diff --git a/vendor/github.com/gdamore/tcell/v2/terminfo/k/konsole/term.go b/vendor/github.com/gdamore/tcell/v2/terminfo/k/konsole/term.go
index c32de96343e..36c9423e8f5 100644
--- a/vendor/github.com/gdamore/tcell/v2/terminfo/k/konsole/term.go
+++ b/vendor/github.com/gdamore/tcell/v2/terminfo/k/konsole/term.go
@@ -68,6 +68,7 @@ func init() {
 		KeyBacktab:        "\x1b[Z",
 		Modifiers:         1,
 		AutoMargin:        true,
+		XTermLike:         true,
 	})
 
 	// KDE console window with xterm 256-colors
@@ -132,5 +133,6 @@ func init() {
 		KeyBacktab:        "\x1b[Z",
 		Modifiers:         1,
 		AutoMargin:        true,
+		XTermLike:         true,
 	})
 }
diff --git a/vendor/github.com/gdamore/tcell/v2/terminfo/k/kterm/term.go b/vendor/github.com/gdamore/tcell/v2/terminfo/k/kterm/term.go
index 34306809557..e1a0d8d129c 100644
--- a/vendor/github.com/gdamore/tcell/v2/terminfo/k/kterm/term.go
+++ b/vendor/github.com/gdamore/tcell/v2/terminfo/k/kterm/term.go
@@ -66,5 +66,6 @@ func init() {
 		KeyF19:            "\x1b[33~",
 		KeyF20:            "\x1b[34~",
 		AutoMargin:        true,
+		XTermLike:         true,
 	})
 }
diff --git a/vendor/github.com/gdamore/tcell/v2/terminfo/models.txt b/vendor/github.com/gdamore/tcell/v2/terminfo/models.txt
index feea5e2e1f5..1c709f474ee 100644
--- a/vendor/github.com/gdamore/tcell/v2/terminfo/models.txt
+++ b/vendor/github.com/gdamore/tcell/v2/terminfo/models.txt
@@ -14,7 +14,7 @@ pcansi
 rxvt,rxvt-256color,rxvt-88color,rxvt-unicode,rxvt-unicode-256color
 screen,screen-256color
 st,st-256color|simpleterm
-tmux
+tmux,tmux-256color
 vt52
 vt100
 vt102
@@ -27,4 +27,5 @@ wy60
 wy99-ansi,wy99a-ansi
 xfce
 xterm,xterm-88color,xterm-256color
+xterm-ghostty
 xterm-kitty
diff --git a/vendor/github.com/gdamore/tcell/v2/terminfo/r/rxvt/term.go b/vendor/github.com/gdamore/tcell/v2/terminfo/r/rxvt/term.go
index 94169e795db..979074aa3f1 100644
--- a/vendor/github.com/gdamore/tcell/v2/terminfo/r/rxvt/term.go
+++ b/vendor/github.com/gdamore/tcell/v2/terminfo/r/rxvt/term.go
@@ -110,6 +110,7 @@ func init() {
 		KeyCtrlHome:  "\x1b[7^",
 		KeyCtrlEnd:   "\x1b[8^",
 		AutoMargin:   true,
+		XTermLike:    true,
 	})
 
 	// rxvt 2.7.9 with xterm 256-colors
@@ -215,6 +216,7 @@ func init() {
 		KeyCtrlHome:  "\x1b[7^",
 		KeyCtrlEnd:   "\x1b[8^",
 		AutoMargin:   true,
+		XTermLike:    true,
 	})
 
 	// rxvt 2.7.9 with xterm 88-colors
@@ -320,6 +322,7 @@ func init() {
 		KeyCtrlHome:  "\x1b[7^",
 		KeyCtrlEnd:   "\x1b[8^",
 		AutoMargin:   true,
+		XTermLike:    true,
 	})
 
 	// rxvt-unicode terminal (X Window System)
diff --git a/vendor/github.com/gdamore/tcell/v2/terminfo/s/simpleterm/term.go b/vendor/github.com/gdamore/tcell/v2/terminfo/s/simpleterm/term.go
index e14b265a5a6..9257637cee6 100644
--- a/vendor/github.com/gdamore/tcell/v2/terminfo/s/simpleterm/term.go
+++ b/vendor/github.com/gdamore/tcell/v2/terminfo/s/simpleterm/term.go
@@ -67,6 +67,7 @@ func init() {
 		KeyClear:      "\x1b[3;5~",
 		Modifiers:     1,
 		AutoMargin:    true,
+		XTermLike:     true,
 	})
 
 	// simpleterm with 256 colors
@@ -130,5 +131,6 @@ func init() {
 		KeyClear:      "\x1b[3;5~",
 		Modifiers:     1,
 		AutoMargin:    true,
+		XTermLike:     true,
 	})
 }
diff --git a/vendor/github.com/gdamore/tcell/v2/terminfo/t/tmux/term.go b/vendor/github.com/gdamore/tcell/v2/terminfo/t/tmux/term.go
index 5ecac38e8e4..8aa76a06bcd 100644
--- a/vendor/github.com/gdamore/tcell/v2/terminfo/t/tmux/term.go
+++ b/vendor/github.com/gdamore/tcell/v2/terminfo/t/tmux/term.go
@@ -8,64 +8,135 @@ func init() {
 
 	// tmux terminal multiplexer
 	terminfo.AddTerminfo(&terminfo.Terminfo{
-		Name:          "tmux",
-		Columns:       80,
-		Lines:         24,
-		Colors:        8,
-		Bell:          "\a",
-		Clear:         "\x1b[H\x1b[J",
-		EnterCA:       "\x1b[?1049h",
-		ExitCA:        "\x1b[?1049l",
-		ShowCursor:    "\x1b[34h\x1b[?25h",
-		HideCursor:    "\x1b[?25l",
-		AttrOff:       "\x1b[m\x0f",
-		Underline:     "\x1b[4m",
-		Bold:          "\x1b[1m",
-		Dim:           "\x1b[2m",
-		Italic:        "\x1b[3m",
-		Blink:         "\x1b[5m",
-		Reverse:       "\x1b[7m",
-		EnterKeypad:   "\x1b[?1h\x1b=",
-		ExitKeypad:    "\x1b[?1l\x1b>",
-		SetFg:         "\x1b[3%p1%dm",
-		SetBg:         "\x1b[4%p1%dm",
-		SetFgBg:       "\x1b[3%p1%d;4%p2%dm",
-		ResetFgBg:     "\x1b[39;49m",
-		PadChar:       "\x00",
-		AltChars:      "++,,--..00``aaffgghhiijjkkllmmnnooppqqrrssttuuvvwwxxyyzz{{||}}~~",
-		EnterAcs:      "\x0e",
-		ExitAcs:       "\x0f",
-		EnableAcs:     "\x1b(B\x1b)0",
-		StrikeThrough: "\x1b[9m",
-		Mouse:         "\x1b[M",
-		SetCursor:     "\x1b[%i%p1%d;%p2%dH",
-		CursorBack1:   "\b",
-		CursorUp1:     "\x1bM",
-		KeyUp:         "\x1bOA",
-		KeyDown:       "\x1bOB",
-		KeyRight:      "\x1bOC",
-		KeyLeft:       "\x1bOD",
-		KeyInsert:     "\x1b[2~",
-		KeyDelete:     "\x1b[3~",
-		KeyBackspace:  "\x7f",
-		KeyHome:       "\x1b[1~",
-		KeyEnd:        "\x1b[4~",
-		KeyPgUp:       "\x1b[5~",
-		KeyPgDn:       "\x1b[6~",
-		KeyF1:         "\x1bOP",
-		KeyF2:         "\x1bOQ",
-		KeyF3:         "\x1bOR",
-		KeyF4:         "\x1bOS",
-		KeyF5:         "\x1b[15~",
-		KeyF6:         "\x1b[17~",
-		KeyF7:         "\x1b[18~",
-		KeyF8:         "\x1b[19~",
-		KeyF9:         "\x1b[20~",
-		KeyF10:        "\x1b[21~",
-		KeyF11:        "\x1b[23~",
-		KeyF12:        "\x1b[24~",
-		KeyBacktab:    "\x1b[Z",
-		Modifiers:     1,
-		AutoMargin:    true,
+		Name:            "tmux",
+		Columns:         80,
+		Lines:           24,
+		Colors:          8,
+		Bell:            "\a",
+		Clear:           "\x1b[H\x1b[J",
+		EnterCA:         "\x1b[?1049h",
+		ExitCA:          "\x1b[?1049l",
+		ShowCursor:      "\x1b[34h\x1b[?25h",
+		HideCursor:      "\x1b[?25l",
+		AttrOff:         "\x1b[m\x0f",
+		Underline:       "\x1b[4m",
+		Bold:            "\x1b[1m",
+		Dim:             "\x1b[2m",
+		Italic:          "\x1b[3m",
+		Blink:           "\x1b[5m",
+		Reverse:         "\x1b[7m",
+		EnterKeypad:     "\x1b[?1h\x1b=",
+		ExitKeypad:      "\x1b[?1l\x1b>",
+		SetFg:           "\x1b[3%p1%dm",
+		SetBg:           "\x1b[4%p1%dm",
+		SetFgBg:         "\x1b[3%p1%d;4%p2%dm",
+		ResetFgBg:       "\x1b[39;49m",
+		PadChar:         "\x00",
+		AltChars:        "++,,--..00``aaffgghhiijjkkllmmnnooppqqrrssttuuvvwwxxyyzz{{||}}~~",
+		EnterAcs:        "\x0e",
+		ExitAcs:         "\x0f",
+		EnableAcs:       "\x1b(B\x1b)0",
+		StrikeThrough:   "\x1b[9m",
+		Mouse:           "\x1b[M",
+		SetCursor:       "\x1b[%i%p1%d;%p2%dH",
+		CursorBack1:     "\b",
+		CursorUp1:       "\x1bM",
+		KeyUp:           "\x1bOA",
+		KeyDown:         "\x1bOB",
+		KeyRight:        "\x1bOC",
+		KeyLeft:         "\x1bOD",
+		KeyInsert:       "\x1b[2~",
+		KeyDelete:       "\x1b[3~",
+		KeyBackspace:    "\x7f",
+		KeyHome:         "\x1b[1~",
+		KeyEnd:          "\x1b[4~",
+		KeyPgUp:         "\x1b[5~",
+		KeyPgDn:         "\x1b[6~",
+		KeyF1:           "\x1bOP",
+		KeyF2:           "\x1bOQ",
+		KeyF3:           "\x1bOR",
+		KeyF4:           "\x1bOS",
+		KeyF5:           "\x1b[15~",
+		KeyF6:           "\x1b[17~",
+		KeyF7:           "\x1b[18~",
+		KeyF8:           "\x1b[19~",
+		KeyF9:           "\x1b[20~",
+		KeyF10:          "\x1b[21~",
+		KeyF11:          "\x1b[23~",
+		KeyF12:          "\x1b[24~",
+		KeyBacktab:      "\x1b[Z",
+		Modifiers:       1,
+		AutoMargin:      true,
+		DoubleUnderline: "\x1b[4:2m",
+		CurlyUnderline:  "\x1b[4:3m",
+		DottedUnderline: "\x1b[4:4m",
+		DashedUnderline: "\x1b[4:5m",
+	})
+
+	// tmux with 256 colors
+	terminfo.AddTerminfo(&terminfo.Terminfo{
+		Name:            "tmux-256color",
+		Columns:         80,
+		Lines:           24,
+		Colors:          256,
+		Bell:            "\a",
+		Clear:           "\x1b[H\x1b[J",
+		EnterCA:         "\x1b[?1049h",
+		ExitCA:          "\x1b[?1049l",
+		ShowCursor:      "\x1b[34h\x1b[?25h",
+		HideCursor:      "\x1b[?25l",
+		AttrOff:         "\x1b[m\x0f",
+		Underline:       "\x1b[4m",
+		Bold:            "\x1b[1m",
+		Dim:             "\x1b[2m",
+		Italic:          "\x1b[3m",
+		Blink:           "\x1b[5m",
+		Reverse:         "\x1b[7m",
+		EnterKeypad:     "\x1b[?1h\x1b=",
+		ExitKeypad:      "\x1b[?1l\x1b>",
+		SetFg:           "\x1b[%?%p1%{8}%<%t3%p1%d%e%p1%{16}%<%t9%p1%{8}%-%d%e38;5;%p1%d%;m",
+		SetBg:           "\x1b[%?%p1%{8}%<%t4%p1%d%e%p1%{16}%<%t10%p1%{8}%-%d%e48;5;%p1%d%;m",
+		SetFgBg:         "\x1b[%?%p1%{8}%<%t3%p1%d%e%p1%{16}%<%t9%p1%{8}%-%d%e38;5;%p1%d%;;%?%p2%{8}%<%t4%p2%d%e%p2%{16}%<%t10%p2%{8}%-%d%e48;5;%p2%d%;m",
+		ResetFgBg:       "\x1b[39;49m",
+		PadChar:         "\x00",
+		AltChars:        "++,,--..00``aaffgghhiijjkkllmmnnooppqqrrssttuuvvwwxxyyzz{{||}}~~",
+		EnterAcs:        "\x0e",
+		ExitAcs:         "\x0f",
+		EnableAcs:       "\x1b(B\x1b)0",
+		StrikeThrough:   "\x1b[9m",
+		Mouse:           "\x1b[M",
+		SetCursor:       "\x1b[%i%p1%d;%p2%dH",
+		CursorBack1:     "\b",
+		CursorUp1:       "\x1bM",
+		KeyUp:           "\x1bOA",
+		KeyDown:         "\x1bOB",
+		KeyRight:        "\x1bOC",
+		KeyLeft:         "\x1bOD",
+		KeyInsert:       "\x1b[2~",
+		KeyDelete:       "\x1b[3~",
+		KeyBackspace:    "\x7f",
+		KeyHome:         "\x1b[1~",
+		KeyEnd:          "\x1b[4~",
+		KeyPgUp:         "\x1b[5~",
+		KeyPgDn:         "\x1b[6~",
+		KeyF1:           "\x1bOP",
+		KeyF2:           "\x1bOQ",
+		KeyF3:           "\x1bOR",
+		KeyF4:           "\x1bOS",
+		KeyF5:           "\x1b[15~",
+		KeyF6:           "\x1b[17~",
+		KeyF7:           "\x1b[18~",
+		KeyF8:           "\x1b[19~",
+		KeyF9:           "\x1b[20~",
+		KeyF10:          "\x1b[21~",
+		KeyF11:          "\x1b[23~",
+		KeyF12:          "\x1b[24~",
+		KeyBacktab:      "\x1b[Z",
+		Modifiers:       1,
+		AutoMargin:      true,
+		DoubleUnderline: "\x1b[4:2m",
+		CurlyUnderline:  "\x1b[4:3m",
+		DottedUnderline: "\x1b[4:4m",
+		DashedUnderline: "\x1b[4:5m",
 	})
 }
diff --git a/vendor/github.com/gdamore/tcell/v2/terminfo/terminfo.go b/vendor/github.com/gdamore/tcell/v2/terminfo/terminfo.go
index 34c0eeffaf1..44fefc51ddd 100644
--- a/vendor/github.com/gdamore/tcell/v2/terminfo/terminfo.go
+++ b/vendor/github.com/gdamore/tcell/v2/terminfo/terminfo.go
@@ -227,13 +227,25 @@ type Terminfo struct {
 	CursorSteadyUnderline   string
 	CursorBlinkingBar       string
 	CursorSteadyBar         string
+	CursorColor             string // nothing uses it yet
+	CursorColorRGB          string // Cs (but not really because Cs uses X11 color string)
+	CursorColorReset        string // Cr
 	EnterUrl                string
 	ExitUrl                 string
 	SetWindowSize           string
+	SetWindowTitle          string // no terminfo extension
 	EnableFocusReporting    string
 	DisableFocusReporting   string
 	DisableAutoMargin       string // smam
 	EnableAutoMargin        string // rmam
+	DoubleUnderline         string // Smulx with param 2
+	CurlyUnderline          string // Smulx with param 3
+	DottedUnderline         string // Smulx with param 4
+	DashedUnderline         string // Smulx with param 5
+	UnderlineColor          string // Setuc1
+	UnderlineColorRGB       string // Setulc
+	UnderlineColorReset     string // ol
+	XTermLike               bool   // (XT) has XTerm extensions
 }
 
 const (
diff --git a/vendor/github.com/gdamore/tcell/v2/terminfo/x/xfce/term.go b/vendor/github.com/gdamore/tcell/v2/terminfo/x/xfce/term.go
index 4f7e825ef9b..b9999a1c59d 100644
--- a/vendor/github.com/gdamore/tcell/v2/terminfo/x/xfce/term.go
+++ b/vendor/github.com/gdamore/tcell/v2/terminfo/x/xfce/term.go
@@ -65,5 +65,6 @@ func init() {
 		KeyBacktab:        "\x1b[Z",
 		Modifiers:         1,
 		AutoMargin:        true,
+		XTermLike:         true,
 	})
 }
diff --git a/vendor/github.com/gdamore/tcell/v2/terminfo/x/xterm/term.go b/vendor/github.com/gdamore/tcell/v2/terminfo/x/xterm/term.go
index fb9c75899e5..faf7d8acbbe 100644
--- a/vendor/github.com/gdamore/tcell/v2/terminfo/x/xterm/term.go
+++ b/vendor/github.com/gdamore/tcell/v2/terminfo/x/xterm/term.go
@@ -68,6 +68,7 @@ func init() {
 		KeyBacktab:        "\x1b[Z",
 		Modifiers:         1,
 		AutoMargin:        true,
+		XTermLike:         true,
 	})
 
 	// xterm with 88 colors
@@ -131,6 +132,7 @@ func init() {
 		KeyBacktab:        "\x1b[Z",
 		Modifiers:         1,
 		AutoMargin:        true,
+		XTermLike:         true,
 	})
 
 	// xterm with 256 colors
@@ -194,5 +196,6 @@ func init() {
 		KeyBacktab:        "\x1b[Z",
 		Modifiers:         1,
 		AutoMargin:        true,
+		XTermLike:         true,
 	})
 }
diff --git a/vendor/github.com/gdamore/tcell/v2/terminfo/x/xterm_ghostty/term.go b/vendor/github.com/gdamore/tcell/v2/terminfo/x/xterm_ghostty/term.go
new file mode 100644
index 00000000000..54d88db92db
--- /dev/null
+++ b/vendor/github.com/gdamore/tcell/v2/terminfo/x/xterm_ghostty/term.go
@@ -0,0 +1,79 @@
+// Generated automatically.  DO NOT HAND-EDIT.
+
+package xterm_ghostty
+
+import "github.com/gdamore/tcell/v2/terminfo"
+
+func init() {
+
+	// Ghostty
+	terminfo.AddTerminfo(&terminfo.Terminfo{
+		Name:              "xterm-ghostty",
+		Aliases:           []string{"ghostty"},
+		Columns:           80,
+		Lines:             24,
+		Colors:            256,
+		Bell:              "\a",
+		Clear:             "\x1b[H\x1b[2J",
+		EnterCA:           "\x1b[?1049h",
+		ExitCA:            "\x1b[?1049l",
+		ShowCursor:        "\x1b[?12l\x1b[?25h",
+		HideCursor:        "\x1b[?25l",
+		AttrOff:           "\x1b(B\x1b[m",
+		Underline:         "\x1b[4m",
+		Bold:              "\x1b[1m",
+		Dim:               "\x1b[2m",
+		Italic:            "\x1b[3m",
+		Blink:             "\x1b[5m",
+		Reverse:           "\x1b[7m",
+		EnterKeypad:       "\x1b[?1h\x1b=",
+		ExitKeypad:        "\x1b[?1l\x1b>",
+		SetFg:             "\x1b[%?%p1%{8}%<%t3%p1%d%e%p1%{16}%<%t9%p1%{8}%-%d%e38;5;%p1%d%;m",
+		SetBg:             "\x1b[%?%p1%{8}%<%t4%p1%d%e%p1%{16}%<%t10%p1%{8}%-%d%e48;5;%p1%d%;m",
+		SetFgBg:           "\x1b[%?%p1%{8}%<%t3%p1%d%e%p1%{16}%<%t9%p1%{8}%-%d%e38;5;%p1%d%;;%?%p2%{8}%<%t4%p2%d%e%p2%{16}%<%t10%p2%{8}%-%d%e48;5;%p2%d%;m",
+		ResetFgBg:         "\x1b[39;49m",
+		AltChars:          "++,,--..00``aaffgghhiijjkkllmmnnooppqqrrssttuuvvwwxxyyzz{{||}}~~",
+		EnterAcs:          "\x1b(0",
+		ExitAcs:           "\x1b(B",
+		EnableAutoMargin:  "\x1b[?7h",
+		DisableAutoMargin: "\x1b[?7l",
+		StrikeThrough:     "\x1b[9m",
+		Mouse:             "\x1b[<",
+		SetCursor:         "\x1b[%i%p1%d;%p2%dH",
+		CursorBack1:       "\b",
+		CursorUp1:         "\x1b[A",
+		KeyUp:             "\x1bOA",
+		KeyDown:           "\x1bOB",
+		KeyRight:          "\x1bOC",
+		KeyLeft:           "\x1bOD",
+		KeyInsert:         "\x1b[2~",
+		KeyDelete:         "\x1b[3~",
+		KeyBackspace:      "\x7f",
+		KeyHome:           "\x1bOH",
+		KeyEnd:            "\x1bOF",
+		KeyPgUp:           "\x1b[5~",
+		KeyPgDn:           "\x1b[6~",
+		KeyF1:             "\x1bOP",
+		KeyF2:             "\x1bOQ",
+		KeyF3:             "\x1bOR",
+		KeyF4:             "\x1bOS",
+		KeyF5:             "\x1b[15~",
+		KeyF6:             "\x1b[17~",
+		KeyF7:             "\x1b[18~",
+		KeyF8:             "\x1b[19~",
+		KeyF9:             "\x1b[20~",
+		KeyF10:            "\x1b[21~",
+		KeyF11:            "\x1b[23~",
+		KeyF12:            "\x1b[24~",
+		KeyBacktab:        "\x1b[Z",
+		Modifiers:         1,
+		TrueColor:         true,
+		AutoMargin:        true,
+		InsertChar:        "\x1b[@",
+		DoubleUnderline:   "\x1b[4:2m",
+		CurlyUnderline:    "\x1b[4:3m",
+		DottedUnderline:   "\x1b[4:4m",
+		DashedUnderline:   "\x1b[4:5m",
+		XTermLike:         true,
+	})
+}
diff --git a/vendor/github.com/gdamore/tcell/v2/terminfo/x/xterm_kitty/term.go b/vendor/github.com/gdamore/tcell/v2/terminfo/x/xterm_kitty/term.go
index ac815a11dcb..8ee597760e4 100644
--- a/vendor/github.com/gdamore/tcell/v2/terminfo/x/xterm_kitty/term.go
+++ b/vendor/github.com/gdamore/tcell/v2/terminfo/x/xterm_kitty/term.go
@@ -67,5 +67,9 @@ func init() {
 		Modifiers:         1,
 		TrueColor:         true,
 		AutoMargin:        true,
+		DoubleUnderline:   "\x1b[4:2m",
+		CurlyUnderline:    "\x1b[4:3m",
+		DottedUnderline:   "\x1b[4:4m",
+		DashedUnderline:   "\x1b[4:5m",
 	})
 }
diff --git a/vendor/github.com/gdamore/tcell/v2/terms_dynamic.go b/vendor/github.com/gdamore/tcell/v2/terms_dynamic.go
index f552b0e8e22..9e549449886 100644
--- a/vendor/github.com/gdamore/tcell/v2/terms_dynamic.go
+++ b/vendor/github.com/gdamore/tcell/v2/terms_dynamic.go
@@ -27,9 +27,14 @@ import (
 	// will be automatically included anyway.
 	"github.com/gdamore/tcell/v2/terminfo"
 	"github.com/gdamore/tcell/v2/terminfo/dynamic"
+
+	"fmt"
 )
 
 func loadDynamicTerminfo(term string) (*terminfo.Terminfo, error) {
+	if term == "" {
+		return nil, fmt.Errorf("%w: term not set", ErrTermNotFound)
+	}
 	ti, _, e := dynamic.LoadTerminfo(term)
 	if e != nil {
 		return nil, e
diff --git a/vendor/github.com/gdamore/tcell/v2/tscreen.go b/vendor/github.com/gdamore/tcell/v2/tscreen.go
index 498f744fdac..7b0f64fdcba 100644
--- a/vendor/github.com/gdamore/tcell/v2/tscreen.go
+++ b/vendor/github.com/gdamore/tcell/v2/tscreen.go
@@ -19,6 +19,7 @@ package tcell
 
 import (
 	"bytes"
+	"encoding/base64"
 	"errors"
 	"io"
 	"os"
@@ -32,9 +33,6 @@ import (
 	"golang.org/x/text/transform"
 
 	"github.com/gdamore/tcell/v2/terminfo"
-
-	// import the stock terminals
-	_ "github.com/gdamore/tcell/v2/terminfo/base"
 )
 
 // NewTerminfoScreen returns a Screen that uses the stock TTY interface
@@ -154,8 +152,18 @@ type tScreen struct {
 	setWinSize   string
 	enableFocus  string
 	disableFocus string
+	doubleUnder  string
+	curlyUnder   string
+	dottedUnder  string
+	dashedUnder  string
+	underColor   string
+	underRGB     string
+	underFg      string
 	cursorStyles map[CursorStyle]string
 	cursorStyle  CursorStyle
+	cursorColor  Color
+	cursorRGB    string
+	cursorFg     string
 	saved        *term.State
 	stopQ        chan struct{}
 	eventQ       chan Event
@@ -164,6 +172,11 @@ type tScreen struct {
 	mouseFlags   MouseFlags
 	pasteEnabled bool
 	focusEnabled bool
+	setTitle     string
+	saveTitle    string
+	restoreTitle string
+	title        string
+	setClipboard string
 
 	sync.Mutex
 }
@@ -338,7 +351,7 @@ func (t *tScreen) prepareBracketedPaste() {
 		t.disablePaste = t.ti.DisablePaste
 		t.prepareKey(keyPasteStart, t.ti.PasteStart)
 		t.prepareKey(keyPasteEnd, t.ti.PasteEnd)
-	} else if t.ti.Mouse != "" {
+	} else if t.ti.Mouse != "" || t.ti.XTermLike {
 		t.enablePaste = "\x1b[?2004h"
 		t.disablePaste = "\x1b[?2004l"
 		t.prepareKey(keyPasteStart, "\x1b[200~")
@@ -346,6 +359,54 @@ func (t *tScreen) prepareBracketedPaste() {
 	}
 }
 
+func (t *tScreen) prepareUnderlines() {
+	if t.ti.DoubleUnderline != "" {
+		t.doubleUnder = t.ti.DoubleUnderline
+	} else if t.ti.XTermLike {
+		t.doubleUnder = "\x1b[4:2m"
+	}
+	if t.ti.CurlyUnderline != "" {
+		t.curlyUnder = t.ti.CurlyUnderline
+	} else if t.ti.XTermLike {
+		t.curlyUnder = "\x1b[4:3m"
+	}
+	if t.ti.DottedUnderline != "" {
+		t.dottedUnder = t.ti.DottedUnderline
+	} else if t.ti.XTermLike {
+		t.dottedUnder = "\x1b[4:4m"
+	}
+	if t.ti.DashedUnderline != "" {
+		t.dashedUnder = t.ti.DashedUnderline
+	} else if t.ti.XTermLike {
+		t.dashedUnder = "\x1b[4:5m"
+	}
+
+	// Underline colors.  We're not going to rely upon terminfo for this
+	// Essentially all terminals that support the curly underlines are
+	// expected to also support coloring them too - which reflects actual
+	// practice since these were introduced at about the same time.
+	if t.ti.UnderlineColor != "" {
+		t.underColor = t.ti.UnderlineColor
+	} else if t.ti.CurlyUnderline != "" {
+		t.underColor = "\x1b[58:5:%p1%dm"
+	}
+	if t.ti.UnderlineColorRGB != "" {
+		// An interesting wart here is that in order to facilitate
+		// using just a single parameter, the Setulc parameter takes
+		// the 24-bit color as an integer rather than separate bytes.
+		// This matches the "new" style direct color approach that
+		// ncurses took, even though everyone else when another way.
+		t.underRGB = t.ti.UnderlineColorRGB
+	} else if t.ti.CurlyUnderline != "" {
+		t.underRGB = "\x1b[58:2::%p1%d:%p2%d:%p3%dm"
+	}
+	if t.ti.UnderlineColorReset != "" {
+		t.underFg = t.ti.UnderlineColorReset
+	} else if t.ti.CurlyUnderline != "" {
+		t.underFg = "\x1b[59m"
+	}
+}
+
 func (t *tScreen) prepareExtendedOSC() {
 	// Linux is a special beast - because it has a mouse entry, but does
 	// not swallow these OSC commands properly.
@@ -359,27 +420,43 @@ func (t *tScreen) prepareExtendedOSC() {
 	if t.ti.EnterUrl != "" {
 		t.enterUrl = t.ti.EnterUrl
 		t.exitUrl = t.ti.ExitUrl
-	} else if t.ti.Mouse != "" {
+	} else if t.ti.Mouse != "" || t.ti.XTermLike {
 		t.enterUrl = "\x1b]8;%p2%s;%p1%s\x1b\\"
 		t.exitUrl = "\x1b]8;;\x1b\\"
 	}
 
 	if t.ti.SetWindowSize != "" {
 		t.setWinSize = t.ti.SetWindowSize
-	} else if t.ti.Mouse != "" {
+	} else if t.ti.Mouse != "" || t.ti.XTermLike {
 		t.setWinSize = "\x1b[8;%p1%p2%d;%dt"
 	}
 
 	if t.ti.EnableFocusReporting != "" {
 		t.enableFocus = t.ti.EnableFocusReporting
-	} else if t.ti.Mouse != "" {
+	} else if t.ti.Mouse != "" || t.ti.XTermLike {
 		t.enableFocus = "\x1b[?1004h"
 	}
 	if t.ti.DisableFocusReporting != "" {
 		t.disableFocus = t.ti.DisableFocusReporting
-	} else if t.ti.Mouse != "" {
+	} else if t.ti.Mouse != "" || t.ti.XTermLike {
 		t.disableFocus = "\x1b[?1004l"
 	}
+
+	if t.ti.SetWindowTitle != "" {
+		t.setTitle = t.ti.SetWindowTitle
+	} else if t.ti.XTermLike {
+		t.saveTitle = "\x1b[22;2t"
+		t.restoreTitle = "\x1b[23;2t"
+		// this also tries to request that UTF-8 is allowed in the title
+		t.setTitle = "\x1b[>2t\x1b]2;%p1%s\x1b\\"
+	}
+
+	if t.setClipboard == "" && t.ti.XTermLike {
+		// this string takes a base64 string and sends it to the clipboard.
+		// it will also be able to retrieve the clipboard using "?" as the
+		// sent string, when we support that.
+		t.setClipboard = "\x1b]52;c;%p1%s\x1b\\"
+	}
 }
 
 func (t *tScreen) prepareCursorStyles() {
@@ -397,7 +474,7 @@ func (t *tScreen) prepareCursorStyles() {
 			CursorStyleBlinkingBar:       t.ti.CursorBlinkingBar,
 			CursorStyleSteadyBar:         t.ti.CursorSteadyBar,
 		}
-	} else if t.ti.Mouse != "" {
+	} else if t.ti.Mouse != "" || t.ti.XTermLike {
 		t.cursorStyles = map[CursorStyle]string{
 			CursorStyleDefault:           "\x1b[0 q",
 			CursorStyleBlinkingBlock:     "\x1b[1 q",
@@ -408,6 +485,20 @@ func (t *tScreen) prepareCursorStyles() {
 			CursorStyleSteadyBar:         "\x1b[6 q",
 		}
 	}
+	if t.ti.CursorColorRGB != "" {
+		// if it was X11 style with just a single %p1%s, then convert
+		t.cursorRGB = t.ti.CursorColorRGB
+	}
+	if t.ti.CursorColorReset != "" {
+		t.cursorFg = t.ti.CursorColorReset
+	}
+	if t.cursorRGB == "" {
+		t.cursorRGB = "\x1b]12;%p1%s\007"
+		t.cursorFg = "\x1b]112\007"
+	}
+
+	// convert XTERM style color names to RGB color code.  We have no way to do palette colors
+	t.cursorRGB = strings.Replace(t.cursorRGB, "%p1%s", "#%p1%02x%p2%02x%p3%02x", 1)
 }
 
 func (t *tScreen) prepareKey(key Key, val string) {
@@ -416,6 +507,11 @@ func (t *tScreen) prepareKey(key Key, val string) {
 
 func (t *tScreen) prepareKeys() {
 	ti := t.ti
+	if strings.HasPrefix(ti.Name, "xterm") {
+		// assume its some form of XTerm clone
+		t.ti.XTermLike = true
+		ti.XTermLike = true
+	}
 	t.prepareKey(KeyBackspace, ti.KeyBackspace)
 	t.prepareKey(KeyF1, ti.KeyF1)
 	t.prepareKey(KeyF2, ti.KeyF2)
@@ -550,6 +646,7 @@ func (t *tScreen) prepareKeys() {
 	t.prepareXtermModifiers()
 	t.prepareBracketedPaste()
 	t.prepareCursorStyles()
+	t.prepareUnderlines()
 	t.prepareExtendedOSC()
 
 outer:
@@ -742,7 +839,7 @@ func (t *tScreen) drawCell(x, y int) int {
 		style = t.style
 	}
 	if style != t.curstyle {
-		fg, bg, attrs := style.Decompose()
+		fg, bg, attrs := style.fg, style.bg, style.attrs
 
 		t.TPuts(ti.AttrOff)
 
@@ -750,8 +847,39 @@ func (t *tScreen) drawCell(x, y int) int {
 		if attrs&AttrBold != 0 {
 			t.TPuts(ti.Bold)
 		}
-		if attrs&AttrUnderline != 0 {
-			t.TPuts(ti.Underline)
+		if us, uc := style.ulStyle, style.ulColor; us != UnderlineStyleNone {
+			if t.underColor != "" || t.underRGB != "" {
+				if uc == ColorReset {
+					t.TPuts(t.underFg)
+				} else if uc.IsRGB() {
+					if t.underRGB != "" {
+						r, g, b := uc.RGB()
+						t.TPuts(ti.TParm(t.underRGB, int(r), int(g), int(b)))
+					} else {
+						if v, ok := t.colors[uc]; ok {
+							uc = v
+						} else {
+							v = FindColor(uc, t.palette)
+							t.colors[uc] = v
+							uc = v
+						}
+						t.TPuts(ti.TParm(t.underColor, int(uc&0xff)))
+					}
+				} else if uc.Valid() {
+					t.TPuts(ti.TParm(t.underColor, int(uc&0xff)))
+				}
+			}
+			t.TPuts(ti.Underline) // to ensure everyone gets at least a basic underline
+			switch us {
+			case UnderlineStyleDouble:
+				t.TPuts(t.doubleUnder)
+			case UnderlineStyleCurly:
+				t.TPuts(t.curlyUnder)
+			case UnderlineStyleDotted:
+				t.TPuts(t.dottedUnder)
+			case UnderlineStyleDashed:
+				t.TPuts(t.dashedUnder)
+			}
 		}
 		if attrs&AttrReverse != 0 {
 			t.TPuts(ti.Reverse)
@@ -827,9 +955,10 @@ func (t *tScreen) ShowCursor(x, y int) {
 	t.Unlock()
 }
 
-func (t *tScreen) SetCursorStyle(cs CursorStyle) {
+func (t *tScreen) SetCursor(cs CursorStyle, cc Color) {
 	t.Lock()
 	t.cursorStyle = cs
+	t.cursorColor = cc
 	t.Unlock()
 }
 
@@ -852,6 +981,14 @@ func (t *tScreen) showCursor() {
 			t.TPuts(esc)
 		}
 	}
+	if t.cursorRGB != "" {
+		if t.cursorColor == ColorReset {
+			t.TPuts(t.cursorFg)
+		} else if t.cursorColor.Valid() {
+			r, g, b := t.cursorColor.RGB()
+			t.TPuts(t.ti.TParm(t.cursorRGB, int(r), int(g), int(b)))
+		}
+	}
 	t.cx = x
 	t.cy = y
 }
@@ -890,8 +1027,7 @@ func (t *tScreen) Show() {
 func (t *tScreen) clearScreen() {
 	t.TPuts(t.ti.AttrOff)
 	t.TPuts(t.exitUrl)
-	fg, bg, _ := t.style.Decompose()
-	_ = t.sendFgBg(fg, bg, AttrNone)
+	_ = t.sendFgBg(t.style.fg, t.style.bg, AttrNone)
 	t.TPuts(t.ti.Clear)
 	t.clear = false
 }
@@ -1376,6 +1512,61 @@ func (t *tScreen) parseFocus(buf *bytes.Buffer, evs *[]Event) (bool, bool) {
 	return true, false
 }
 
+func (t *tScreen) parseClipboard(buf *bytes.Buffer, evs *[]Event) (bool, bool) {
+	b := buf.Bytes()
+	state := 0
+	prefix := []byte("\x1b]52;c;")
+
+	if len(prefix) >= len(b) {
+		if bytes.HasPrefix(prefix, b) {
+			// inconclusive so far
+			return true, false
+		}
+		// definitely not a match
+		return false, false
+	}
+	b = b[len(prefix):]
+
+	for _, c := range b {
+		// valid base64 digits
+		if (state == 0) {
+			if (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') || (c >= '0' && c <= '9') || (c == '+') || (c == '/') || (c == '=') {
+				continue
+			}
+			if (c == '\x1b') {
+				state = 1
+				continue
+			}
+			if (c == '\a') {
+				// matched with BEL instead of ST
+				b = b[:len(b)-1] // drop the trailing BEL
+				decoded := make([]byte, base64.StdEncoding.DecodedLen(len(b)))
+				if num, err := base64.StdEncoding.Decode(decoded, b); err == nil {
+					*evs = append(*evs, NewEventClipboard(decoded[:num]))
+				}
+				_, _ = buf.ReadBytes('\a')
+				return true, true
+			}
+			return false, false
+		}
+		if (state == 1)  {
+			if (c == '\\') {
+				b = b[:len(b)-2] // drop the trailing ST (\x1b\\)
+				// now decode the data
+				decoded := make([]byte, base64.StdEncoding.DecodedLen(len(b)))
+				if num, err := base64.StdEncoding.Decode(decoded, b); err == nil {
+					*evs = append(*evs, NewEventClipboard(decoded[:num]))
+				}
+				_, _ = buf.ReadBytes('\\')
+				return true, true
+			}
+			return false, false
+		}
+	}
+	// not enough data yet (not terminated)
+	return true, false
+}
+
 // parseXtermMouse is like parseSgrMouse, but it parses a legacy
 // X11 mouse record.
 func (t *tScreen) parseXtermMouse(buf *bytes.Buffer, evs *[]Event) (bool, bool) {
@@ -1579,6 +1770,14 @@ func (t *tScreen) collectEventsFromInput(buf *bytes.Buffer, expire bool) []Event
 			}
 		}
 
+		if t.setClipboard != "" {
+			if part, comp := t.parseClipboard(buf, &res); comp {
+				continue
+			} else if part {
+				partials++
+			}
+		}
+
 		if partials == 0 || expire {
 			if b[0] == '\x1b' {
 				if len(b) == 1 {
@@ -1829,12 +2028,18 @@ func (t *tScreen) engage() error {
 		// (In theory there could be terminals that don't support X,Y cursor
 		// positions without a setup command, but we don't support them.)
 		t.TPuts(ti.EnterCA)
+		if t.saveTitle != "" {
+			t.TPuts(t.saveTitle)
+		}
 	}
 	t.TPuts(ti.EnterKeypad)
 	t.TPuts(ti.HideCursor)
 	t.TPuts(ti.EnableAcs)
 	t.TPuts(ti.DisableAutoMargin)
 	t.TPuts(ti.Clear)
+	if t.title != "" && t.setTitle != "" {
+		t.TPuts(t.ti.TParm(t.setTitle, t.title))
+	}
 
 	t.wg.Add(2)
 	go t.inputLoop(stopQ)
@@ -1870,11 +2075,17 @@ func (t *tScreen) disengage() {
 	if t.cursorStyles != nil && t.cursorStyle != CursorStyleDefault {
 		t.TPuts(t.cursorStyles[CursorStyleDefault])
 	}
+	if t.cursorFg != "" && t.cursorColor.Valid() {
+		t.TPuts(t.cursorFg)
+	}
 	t.TPuts(ti.ResetFgBg)
 	t.TPuts(ti.AttrOff)
 	t.TPuts(ti.ExitKeypad)
 	t.TPuts(ti.EnableAutoMargin)
 	if os.Getenv("TCELL_ALTSCREEN") != "disable" {
+		if t.restoreTitle != "" {
+			t.TPuts(t.restoreTitle)
+		}
 		t.TPuts(ti.Clear) // only needed if ExitCA is empty
 		t.TPuts(ti.ExitCA)
 	}
@@ -1909,3 +2120,30 @@ func (t *tScreen) EventQ() chan Event {
 func (t *tScreen) GetCells() *CellBuffer {
 	return &t.cells
 }
+
+func (t *tScreen) SetTitle(title string) {
+	t.Lock()
+	t.title = title
+	if t.setTitle != "" && t.running {
+		t.TPuts(t.ti.TParm(t.setTitle, title))
+	}
+	t.Unlock()
+}
+
+func (t *tScreen) SetClipboard(data []byte) {
+	// Post binary data to the system clipboard.  It might be UTF-8, it might not be.
+	t.Lock()
+	if t.setClipboard != "" {
+		encoded := base64.StdEncoding.EncodeToString(data)
+		t.TPuts(t.ti.TParm(t.setClipboard, encoded))
+	}
+	t.Unlock()
+}
+
+func (t *tScreen) GetClipboard() {
+	t.Lock()
+	if t.setClipboard != "" {
+		t.TPuts(t.ti.TParm(t.setClipboard, "?"))
+	}
+	t.Unlock()
+}
diff --git a/vendor/github.com/gdamore/tcell/v2/tscreen_unix.go b/vendor/github.com/gdamore/tcell/v2/tscreen_unix.go
index 84727f8818a..27f4c813442 100644
--- a/vendor/github.com/gdamore/tcell/v2/tscreen_unix.go
+++ b/vendor/github.com/gdamore/tcell/v2/tscreen_unix.go
@@ -1,4 +1,4 @@
-// Copyright 2021 The TCell Authors
+// Copyright 2024 The TCell Authors
 //
 // Licensed under the Apache License, Version 2.0 (the "License");
 // you may not use file except in compliance with the License.
@@ -17,6 +17,11 @@
 
 package tcell
 
+import (
+	// import the stock terminals
+	_ "github.com/gdamore/tcell/v2/terminfo/base"
+)
+
 // initialize is used at application startup, and sets up the initial values
 // including file descriptors used for terminals and saving the initial state
 // so that it can be restored when the application terminates.
diff --git a/vendor/github.com/gdamore/tcell/v2/wscreen.go b/vendor/github.com/gdamore/tcell/v2/wscreen.go
index 137968cc479..8f66079e9e0 100644
--- a/vendor/github.com/gdamore/tcell/v2/wscreen.go
+++ b/vendor/github.com/gdamore/tcell/v2/wscreen.go
@@ -1,4 +1,4 @@
-// Copyright 2023 The TCell Authors
+// Copyright 2024 The TCell Authors
 //
 // Licensed under the Apache License, Version 2.0 (the "License");
 // you may not use file except in compliance with the License.
@@ -19,11 +19,13 @@ package tcell
 
 import (
 	"errors"
-	"github.com/gdamore/tcell/v2/terminfo"
+	"fmt"
 	"strings"
 	"sync"
 	"syscall/js"
 	"unicode/utf8"
+
+	"github.com/gdamore/tcell/v2/terminfo"
 )
 
 func NewTerminfoScreen() (Screen, error) {
@@ -66,6 +68,9 @@ func (t *wScreen) Init() error {
 	t.Unlock()
 
 	js.Global().Set("onKeyEvent", js.FuncOf(t.onKeyEvent))
+	js.Global().Set("onMouseClick", js.FuncOf(t.unset))
+	js.Global().Set("onMouseMove", js.FuncOf(t.unset))
+	js.Global().Set("onFocus", js.FuncOf(t.unset))
 
 	return nil
 }
@@ -133,14 +138,23 @@ func (t *wScreen) drawCell(x, y int) int {
 	if bg == -1 {
 		bg = 0x000000
 	}
+	us, uc := style.ulStyle, paletteColor(style.ulColor)
+	if uc == -1 {
+		uc = 0x000000
+	}
 
-	var combcarr []interface{} = make([]interface{}, len(combc))
-	for i, c := range combc {
-		combcarr[i] = c
+	s := ""
+	if len(combc) > 0 {
+		b := make([]rune, 0, 1 + len(combc))
+		b = append(b, mainc)
+		b = append(b, combc...)
+		s = string(b)
+	} else {
+		s = string(mainc)
 	}
 
 	t.cells.SetDirty(x, y, false)
-	js.Global().Call("drawCell", x, y, mainc, combcarr, fg, bg, int(style.attrs))
+	js.Global().Call("drawCell", x, y, s, fg, bg, int(style.attrs), int(us), int(uc))
 
 	return width
 }
@@ -151,9 +165,12 @@ func (t *wScreen) ShowCursor(x, y int) {
 	t.Unlock()
 }
 
-func (t *wScreen) SetCursorStyle(cs CursorStyle) {
+func (t *wScreen) SetCursor(cs CursorStyle, cc Color) {
+	if !cc.Valid() {
+		cc = ColorLightGray
+	}
 	t.Lock()
-	js.Global().Call("setCursorStyle", curStyleClasses[cs])
+	js.Global().Call("setCursorStyle", curStyleClasses[cs], fmt.Sprintf("#%06x", cc.Hex()))
 	t.Unlock()
 }
 
@@ -511,6 +528,10 @@ func (t *wScreen) StopQ() <-chan struct{} {
 	return t.quit
 }
 
+func (t *wScreen) SetTitle(title string) {
+	js.Global().Call("setTitle", title)
+}
+
 // WebKeyNames maps string names reported from HTML
 // (KeyboardEvent.key) to tcell accepted keys.
 var WebKeyNames = map[string]Key{
diff --git a/vendor/modules.txt b/vendor/modules.txt
index 19ea922ebbd..221160478c5 100644
--- a/vendor/modules.txt
+++ b/vendor/modules.txt
@@ -37,7 +37,7 @@ github.com/fatih/color
 # github.com/gdamore/encoding v1.0.1
 ## explicit; go 1.9
 github.com/gdamore/encoding
-# github.com/gdamore/tcell/v2 v2.7.4
+# github.com/gdamore/tcell/v2 v2.8.0
 ## explicit; go 1.12
 github.com/gdamore/tcell/v2
 github.com/gdamore/tcell/v2/terminfo
@@ -75,6 +75,7 @@ github.com/gdamore/tcell/v2/terminfo/w/wy60
 github.com/gdamore/tcell/v2/terminfo/w/wy99_ansi
 github.com/gdamore/tcell/v2/terminfo/x/xfce
 github.com/gdamore/tcell/v2/terminfo/x/xterm
+github.com/gdamore/tcell/v2/terminfo/x/xterm_ghostty
 github.com/gdamore/tcell/v2/terminfo/x/xterm_kitty
 # github.com/go-errors/errors v1.5.1
 ## explicit; go 1.14
@@ -105,8 +106,6 @@ github.com/gobwas/glob/syntax/ast
 github.com/gobwas/glob/syntax/lexer
 github.com/gobwas/glob/util/runes
 github.com/gobwas/glob/util/strings
-# github.com/google/go-cmp v0.5.6
-## explicit; go 1.8
 # github.com/gookit/color v1.4.2
 ## explicit; go 1.12
 github.com/gookit/color
@@ -172,7 +171,7 @@ github.com/jesseduffield/go-git/v5/utils/merkletrie/filesystem
 github.com/jesseduffield/go-git/v5/utils/merkletrie/index
 github.com/jesseduffield/go-git/v5/utils/merkletrie/internal/frame
 github.com/jesseduffield/go-git/v5/utils/merkletrie/noder
-# github.com/jesseduffield/gocui v0.3.1-0.20250107151125-716b1eb82fb4
+# github.com/jesseduffield/gocui v0.3.1-0.20250111205211-82d518436b5a
 ## explicit; go 1.12
 github.com/jesseduffield/gocui
 # github.com/jesseduffield/kill v0.0.0-20250101124109-e216ddbe133a


Test patch: