├── .gitignore ├── Dockerfile ├── LICENSE ├── Makefile.PL ├── README.md ├── Terminal ├── cpanfile ├── lib └── Terminal.pm ├── public ├── css │ ├── style.css │ └── xterm.css ├── js │ ├── addons │ │ ├── attach │ │ │ └── attach.js │ │ ├── fit │ │ │ └── fit.js │ │ ├── fullscreen │ │ │ ├── fullscreen.css │ │ │ └── fullscreen.js │ │ ├── linkify │ │ │ └── linkify.js │ │ └── terminado │ │ │ └── terminado.js │ ├── app.js │ ├── client.js │ ├── term.js │ ├── xterm.js │ └── xterm.js.map └── x1.png └── templates └── index.html.ep /.gitignore: -------------------------------------------------------------------------------- 1 | /blib/ 2 | /.build/ 3 | _build/ 4 | cover_db/ 5 | inc/ 6 | Build 7 | !Build/ 8 | Build.bat 9 | .last_cover_stats 10 | /Makefile 11 | /Makefile.old 12 | /MANIFEST.bak 13 | /META.yml 14 | /META.json 15 | /MYMETA.* 16 | nytprof.out 17 | /pm_to_blib 18 | *.o 19 | *.bs 20 | /_eumm/ 21 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM perl:5.32.0 2 | 3 | WORKDIR /app 4 | EXPOSE 8080 5 | 6 | COPY . /app/ 7 | RUN cpanm --notest --installdeps . -M https://cpan.metacpan.org && \ 8 | rm -r /root/.cpanm 9 | 10 | ENTRYPOINT ["hypnotoad", "--foreground", "/app/Terminal"] 11 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 NDZ Prajith 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /Makefile.PL: -------------------------------------------------------------------------------- 1 | use strict; 2 | use warnings; 3 | 4 | use ExtUtils::MakeMaker; 5 | 6 | WriteMakefile( 7 | VERSION => '0.01', 8 | PREREQ_PM => {'Mojolicious' => '7.26'}, 9 | test => {TESTS => 't/*.t'} 10 | ); 11 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # mojo-terminal 2 | Interactive terminal over HTTP/HTTPS served by Mojolicious & websockets. 3 | 4 | ![mojo-terminal](./public/x1.png?raw=true) 5 | 6 | 7 | ## Installation 8 | ### docker: 9 | ``` 10 | $> docker build -t mojo-terminal . 11 | $> docker run -ti --name mojo-terminal \ 12 | -p 8080:8080 mojo-terminal:latest 13 | ``` 14 | 15 | ### Install manually: 16 | Make sure you have perl version >= 5.30. 17 | ``` 18 | cpanm --installdeps . 19 | ``` 20 | start the application with hypnotoad 21 | ``` 22 | hypnotoad -f Terminal 23 | ``` 24 | 25 | 26 | :heart: This project is highly inspired by https://github.com/vti/showmetheshell/ & https://github.com/takluyver/terminado :heart: 27 | -------------------------------------------------------------------------------- /Terminal: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env perl 2 | use lib './lib'; 3 | 4 | use Mojolicious::Lite; 5 | use Terminal; 6 | use IO::File; 7 | 8 | get '/' => sub { 9 | my $self = shift; 10 | $self->render( template => 'index' ); 11 | }; 12 | 13 | websocket '/socket' => sub { 14 | my $self = shift; 15 | 16 | Mojo::IOLoop->stream( $self->tx->connection )->timeout(0); 17 | 18 | my $terminal = Terminal->new( cmd => '/bin/bash', app => $self->app ); 19 | 20 | $terminal->on( 21 | row_changed => sub { 22 | my ( $event, $message ) = @_; 23 | 24 | $self->send( 25 | { json => { stdout => $message, type => 'terminal' } } ); 26 | } 27 | ); 28 | 29 | $self->on( 30 | json => sub { 31 | my ( $self, $message ) = @_; 32 | 33 | if ( exists $message->{'screen'} ) { 34 | my $screen = $message->{'screen'}; 35 | 36 | $self->app->log->debug( 37 | "setting screen size to $screen->{'rows'} X $screen->{'cols'}" 38 | ); 39 | $terminal->resize( $screen->{'rows'}, $screen->{'cols'} ); 40 | } 41 | 42 | $terminal->write( $message->{'stdin'} ) 43 | if exists $message->{'stdin'}; 44 | } 45 | ); 46 | 47 | $self->on( 48 | finish => sub { 49 | $self->app->log->debug('Client disconnected'); 50 | $terminal->cleanup(); 51 | } 52 | ); 53 | 54 | $terminal->start() unless $terminal->is_spawned; 55 | }; 56 | 57 | app->start; 58 | -------------------------------------------------------------------------------- /cpanfile: -------------------------------------------------------------------------------- 1 | requires 'Mojolicious'; 2 | requires 'IO::Pty'; 3 | requires 'IO::Tty'; 4 | requires 'IO::Handle'; 5 | -------------------------------------------------------------------------------- /lib/Terminal.pm: -------------------------------------------------------------------------------- 1 | package Terminal; 2 | 3 | use strict; 4 | use warnings; 5 | 6 | use Mojo::Base 'Mojo::EventEmitter'; 7 | 8 | use IO::Pty; 9 | use IO::Tty::Constant; 10 | use IO::Handle; 11 | use POSIX qw(:sys_wait_h); 12 | use Encode (); 13 | 14 | sub new { 15 | my $self = shift->SUPER::new(@_); 16 | 17 | $self->{created} = time; 18 | 19 | $self->{cmd} ||= '/bin/bash'; 20 | $self->{app} ||= sub { }; 21 | 22 | $self->init; 23 | } 24 | 25 | sub init { 26 | my $self = shift; 27 | 28 | $self->app->log->debug("Creating IO::Pty"); 29 | 30 | my $pty = IO::Pty->new; 31 | 32 | my $tty_name = $pty->ttyname; 33 | if (not defined $tty_name) { 34 | die "Could not assign a pty"; 35 | } 36 | $pty->autoflush; 37 | 38 | $self->{pty} = $pty; 39 | 40 | return $self; 41 | } 42 | 43 | sub start { 44 | my $self = shift; 45 | 46 | $self->app->log->debug("Starting a new process"); 47 | 48 | $self->_spawn_shell; 49 | 50 | $self->{handle} = $self->_build_handle; 51 | 52 | $self->{spawned} = 1; 53 | 54 | return $self; 55 | } 56 | 57 | sub resize { 58 | my ($self, $rows, $cols) = @_; 59 | 60 | my $winsize = pack('SSSS', $rows, $cols, 0, 0); 61 | ioctl($self->pty->slave, &IO::Tty::Constant::TIOCSWINSZ, $winsize); 62 | 63 | return; 64 | } 65 | 66 | sub read { 67 | my $self = shift; 68 | my ($chunk) = @_; 69 | 70 | $self->app->log->debug("got chunk from fd"); 71 | $chunk = Encode::decode('UTF-8', $chunk); 72 | $self->emit('row_changed', $chunk); 73 | } 74 | 75 | sub write { 76 | my $self = shift; 77 | 78 | $self->{handle}->write(@_); 79 | 80 | return $self; 81 | } 82 | 83 | sub _build_handle { 84 | my $self = shift; 85 | 86 | my $fh = IO::Handle->new_from_fd($self->pty->fileno, 'w+'); 87 | my $stream = Mojo::IOLoop::Stream->new($fh)->timeout(0); 88 | 89 | $self->{stream_id} = Mojo::IOLoop->stream($stream); 90 | 91 | $stream->on(read => sub { 92 | my ($stream, $bytes) = @_; 93 | 94 | $self->read($bytes); 95 | }); 96 | 97 | $stream->on(close => sub { 98 | my $stream = shift; 99 | close $fh; 100 | }); 101 | 102 | $self->{handle} = $stream; 103 | 104 | } 105 | 106 | sub _spawn_shell { 107 | my $self = shift; 108 | 109 | my $pty = $self->pty; 110 | my $cmd = $self->cmd; 111 | my $pgroup = getpgrp; 112 | 113 | die "Can't fork: $!" unless defined(my $pid = fork); 114 | 115 | if ($pid) { # Parent 116 | $SIG{CHLD} = sub { 117 | while ((my $child = waitpid(-1, WNOHANG)) > 0) { 118 | $self->app->log->debug("$$: Parent waiting: $child"); 119 | $self->emit('close'); 120 | } 121 | }; 122 | return $pid; 123 | } 124 | 125 | $self->app->log->info("Slot running: Child Pid:$$, Parrent Pid:" . getppid); 126 | setpgrp($pid, $pgroup); 127 | 128 | my $tty = $pty->slave; 129 | my $tty_name = $tty->ttyname; 130 | 131 | $tty->set_raw; 132 | $pty->set_raw; 133 | 134 | $pty->make_slave_controlling_terminal; 135 | 136 | close($pty); 137 | close(STDIN); 138 | close(STDOUT); 139 | close(STDERR); 140 | 141 | open(STDIN, "<&" . $tty->fileno) || die "Couldn't reopen " . $tty_name . " for reading: $!"; 142 | open(STDOUT, ">&" . $tty->fileno) || die "Couldn't reopen " . $tty_name . " for writing: $!"; 143 | open(STDERR, ">&" . $tty->fileno) || die "Couldn't redirect STDERR: $!"; 144 | 145 | system 'stty sane'; 146 | 147 | exec $cmd; 148 | die "Cannot exec '$cmd': $!"; 149 | 150 | } 151 | 152 | sub cleanup { 153 | my $self = shift; 154 | $self->{'pty'} = undef; 155 | Mojo::IOLoop->remove($self->stream_id); 156 | } 157 | 158 | sub created { shift->{'created'} } 159 | sub pty { shift->{'pty'} } 160 | sub cmd { shift->{'cmd'} } 161 | sub app { shift->{'app'} } 162 | sub stream_id { shift->{'stream_id'} } 163 | sub is_spawned { shift->{'spawned'} } 164 | 165 | 166 | 1; 167 | -------------------------------------------------------------------------------- /public/css/style.css: -------------------------------------------------------------------------------- 1 | #tabs { 2 | position: absolute; 3 | top: 42%; 4 | } 5 | 6 | .tab { 7 | -webkit-touch-callout: none; 8 | -webkit-user-select: none; 9 | -khtml-user-select: none; 10 | -moz-user-select: none; 11 | -ms-user-select: none; 12 | user-select: none; 13 | position: initial; 14 | top: 10px; 15 | padding: 10px; 16 | height: 16px; 17 | width: 75px; 18 | font-size: 14px; 19 | font-family: "Montserrat"; 20 | } 21 | 22 | .tab:hover { 23 | -webkit-touch-callout: none; 24 | -webkit-user-select: none; 25 | -khtml-user-select: none; 26 | -moz-user-select: none; 27 | -ms-user-select: none; 28 | user-select: none; 29 | position: initial; 30 | top: 10px; 31 | padding: 10px; 32 | height: 16px; 33 | width: 75px; 34 | color: white; 35 | } 36 | 37 | .selectedtab { 38 | -webkit-user-select: none; 39 | -khtml-user-select: none; 40 | -moz-user-select: none; 41 | -ms-user-select: none; 42 | user-select: none; 43 | position: initial; 44 | background-color: rgb(37, 37, 39); 45 | padding: 5px; 46 | border-bottom: 1px; 47 | border-bottom-color: #59FF00; 48 | border-bottom-style: solid; 49 | border-top: 1px; 50 | border-top-color: #353535; 51 | border-top-style: solid; 52 | width: 75px; 53 | font-size: 14px; 54 | font-family: "Montserrat"; 55 | } 56 | 57 | .selectedtab:hover { 58 | -webkit-user-select: none; 59 | -khtml-user-select: none; 60 | -moz-user-select: none; 61 | -ms-user-select: none; 62 | user-select: none; 63 | position: initial; 64 | top: 10px; 65 | background-color: rgb(37, 37, 39); 66 | padding: 10px; 67 | border-bottom: 2px; 68 | border-bottom-color: #59FF00; 69 | border-bottom-style: solid; 70 | border-top: 1px; 71 | border-top-color: #353535; 72 | border-top-style: solid; 73 | height: 10px; 74 | width: 75px; 75 | font-size: 14px; 76 | font-family: "Montserrat"; 77 | color: white; 78 | } 79 | #top { 80 | position: fixed; 81 | color: #8cff76; 82 | top: 0; 83 | left: 0; 84 | padding: 10px; 85 | width: 100%; 86 | height: 34px; 87 | background-color: rgb(30, 30, 33); 88 | border-bottom-width: 1px; 89 | border-bottom-style: solid; 90 | border-bottom-color: rgb(20, 20, 26); 91 | z-index: 1; 92 | } 93 | #window { 94 | top: 55px; 95 | height: 100%; 96 | left: 0; 97 | position: fixed; 98 | width: 100%; 99 | } 100 | 101 | .close-btn { 102 | top: 1px; 103 | right: 1px; 104 | color: #8cff76; 105 | background-color: rgba(0, 0, 0, 0); 106 | font-size: 16px; 107 | border-style: none; 108 | padding: 10; 109 | } 110 | 111 | .close-btn:hover { 112 | top: 1px; 113 | right: 1px; 114 | color: #7f3835; 115 | background-color: rgba(0, 0, 0, 0); 116 | font-size: 16px; 117 | border-style: none; 118 | padding: 10; 119 | } 120 | 121 | #newtab { 122 | -webkit-user-select: none; 123 | -khtml-user-select: none; 124 | -moz-user-select: none; 125 | -ms-user-select: none; 126 | user-select: none; 127 | color: #3a3a3a; 128 | font-weight: bold; 129 | font-family: 'Open Sans', sans-serif; 130 | position: absolute; 131 | font-size: 28px; 132 | left: 105%; 133 | top: -8px; 134 | } 135 | 136 | #newtab:hover { 137 | -webkit-user-select: none; 138 | -khtml-user-select: none; 139 | -moz-user-select: none; 140 | -ms-user-select: none; 141 | user-select: none; 142 | color: #da6a02; 143 | font-weight: bold; 144 | font-family: 'Open Sans', sans-serif; 145 | position: absolute; 146 | font-size: 28px; 147 | left: 105%; 148 | top: -8px; 149 | } 150 | 151 | ::-webkit-scrollbar { 152 | background-color: #1d1f21; 153 | width: 7px; 154 | } 155 | 156 | ::-webkit-scrollbar-track { 157 | background-color: #1d1f21; 158 | width: 7px; 159 | } 160 | 161 | ::-webkit-scrollbar-thumb { 162 | background: #353535; 163 | width: 7px; 164 | border-color: #20201d; 165 | } 166 | 167 | .win { 168 | width: 100%; 169 | height: 100%; 170 | } 171 | 172 | .win .terminal { 173 | padding-bottom:50px; 174 | } 175 | 176 | -------------------------------------------------------------------------------- /public/css/xterm.css: -------------------------------------------------------------------------------- 1 | /** 2 | * xterm.js: xterm, in the browser 3 | * Copyright (c) 2014-2016, SourceLair Private Company (www.sourcelair.com (MIT License) 4 | * Copyright (c) 2012-2013, Christopher Jeffrey (MIT License) 5 | * https://github.com/chjj/term.js 6 | * 7 | * Permission is hereby granted, free of charge, to any person obtaining a copy 8 | * of this software and associated documentation files (the "Software"), to deal 9 | * in the Software without restriction, including without limitation the rights 10 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | * copies of the Software, and to permit persons to whom the Software is 12 | * furnished to do so, subject to the following conditions: 13 | * 14 | * The above copyright notice and this permission notice shall be included in 15 | * all copies or substantial portions of the Software. 16 | * 17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 23 | * THE SOFTWARE. 24 | * 25 | * Originally forked from (with the author's permission): 26 | * Fabrice Bellard's javascript vt100 for jslinux: 27 | * http://bellard.org/jslinux/ 28 | * Copyright (c) 2011 Fabrice Bellard 29 | * The original design remains. The terminal itself 30 | * has been extended to include xterm CSI codes, among 31 | * other features. 32 | */ 33 | 34 | /* 35 | * Default style for xterm.js 36 | */ 37 | 38 | .terminal { 39 | background-color: #000; 40 | color: #fff; 41 | font-family: courier-new, courier, monospace; 42 | font-feature-settings: "liga" 0; 43 | position: relative; 44 | } 45 | 46 | .terminal.focus, 47 | .terminal:focus { 48 | outline: none; 49 | } 50 | 51 | .terminal .xterm-helpers { 52 | position: absolute; 53 | top: 0; 54 | } 55 | 56 | .terminal .xterm-helper-textarea { 57 | /* 58 | * HACK: to fix IE's blinking cursor 59 | * Move textarea out of the screen to the far left, so that the cursor is not visible. 60 | */ 61 | position: absolute; 62 | opacity: 0; 63 | left: -9999em; 64 | top: 0; 65 | width: 0; 66 | height: 0; 67 | z-index: -10; 68 | /** Prevent wrapping so the IME appears against the textarea at the correct position */ 69 | white-space: nowrap; 70 | overflow: hidden; 71 | resize: none; 72 | } 73 | 74 | .terminal a { 75 | color: inherit; 76 | text-decoration: none; 77 | } 78 | 79 | .terminal a:hover { 80 | cursor: pointer; 81 | text-decoration: underline; 82 | } 83 | 84 | .terminal a.xterm-invalid-link:hover { 85 | cursor: text; 86 | text-decoration: none; 87 | } 88 | 89 | .terminal.focus:not(.xterm-cursor-style-underline):not(.xterm-cursor-style-bar) .terminal-cursor { 90 | background-color: #fff; 91 | color: #000; 92 | } 93 | 94 | .terminal:not(.focus) .terminal-cursor { 95 | outline: 1px solid #fff; 96 | outline-offset: -1px; 97 | background-color: transparent; 98 | } 99 | 100 | .terminal:not(.xterm-cursor-style-underline):not(.xterm-cursor-style-bar).focus.xterm-cursor-blink-on .terminal-cursor { 101 | background-color: transparent; 102 | color: inherit; 103 | } 104 | 105 | .terminal.xterm-cursor-style-bar .terminal-cursor, 106 | .terminal.xterm-cursor-style-underline .terminal-cursor { 107 | position: relative; 108 | } 109 | .terminal.xterm-cursor-style-bar .terminal-cursor::before, 110 | .terminal.xterm-cursor-style-underline .terminal-cursor::before { 111 | content: ""; 112 | display: block; 113 | position: absolute; 114 | background-color: #fff; 115 | } 116 | .terminal.xterm-cursor-style-bar .terminal-cursor::before { 117 | top: 0; 118 | bottom: 0; 119 | left: 0; 120 | width: 1px; 121 | } 122 | .terminal.xterm-cursor-style-underline .terminal-cursor::before { 123 | bottom: 0; 124 | left: 0; 125 | right: 0; 126 | height: 1px; 127 | } 128 | .terminal.xterm-cursor-style-bar.focus.xterm-cursor-blink.xterm-cursor-blink-on .terminal-cursor::before, 129 | .terminal.xterm-cursor-style-underline.focus.xterm-cursor-blink.xterm-cursor-blink-on .terminal-cursor::before { 130 | background-color: transparent; 131 | } 132 | .terminal.xterm-cursor-style-bar.focus.xterm-cursor-blink .terminal-cursor::before, 133 | .terminal.xterm-cursor-style-underline.focus.xterm-cursor-blink .terminal-cursor::before { 134 | background-color: #fff; 135 | } 136 | 137 | .terminal .composition-view { 138 | background: #000; 139 | color: #FFF; 140 | display: none; 141 | position: absolute; 142 | white-space: nowrap; 143 | z-index: 1; 144 | } 145 | 146 | .terminal .composition-view.active { 147 | display: block; 148 | } 149 | 150 | .terminal .xterm-viewport { 151 | /* On OS X this is required in order for the scroll bar to appear fully opaque */ 152 | background-color: #000; 153 | overflow-y: scroll; 154 | } 155 | 156 | .terminal .xterm-wide-char { 157 | display: inline-block; 158 | } 159 | 160 | .terminal .xterm-rows { 161 | position: absolute; 162 | left: 0; 163 | top: 0; 164 | } 165 | 166 | .terminal .xterm-rows > div { 167 | /* Lines containing spans and text nodes ocassionally wrap despite being the same width (#327) */ 168 | white-space: nowrap; 169 | } 170 | 171 | .terminal .xterm-scroll-area { 172 | visibility: hidden; 173 | } 174 | 175 | .terminal .xterm-char-measure-element { 176 | display: inline-block; 177 | visibility: hidden; 178 | position: absolute; 179 | left: -9999em; 180 | } 181 | 182 | /* 183 | * Determine default colors for xterm.js 184 | */ 185 | .terminal .xterm-bold { 186 | font-weight: bold; 187 | } 188 | 189 | .terminal .xterm-underline { 190 | text-decoration: underline; 191 | } 192 | 193 | .terminal .xterm-blink { 194 | text-decoration: blink; 195 | } 196 | 197 | .terminal .xterm-hidden { 198 | visibility: hidden; 199 | } 200 | 201 | .terminal .xterm-color-0 { 202 | color: #2e3436; 203 | } 204 | 205 | .terminal .xterm-bg-color-0 { 206 | background-color: #2e3436; 207 | } 208 | 209 | .terminal .xterm-color-1 { 210 | color: #cc0000; 211 | } 212 | 213 | .terminal .xterm-bg-color-1 { 214 | background-color: #cc0000; 215 | } 216 | 217 | .terminal .xterm-color-2 { 218 | color: #4e9a06; 219 | } 220 | 221 | .terminal .xterm-bg-color-2 { 222 | background-color: #4e9a06; 223 | } 224 | 225 | .terminal .xterm-color-3 { 226 | color: #c4a000; 227 | } 228 | 229 | .terminal .xterm-bg-color-3 { 230 | background-color: #c4a000; 231 | } 232 | 233 | .terminal .xterm-color-4 { 234 | color: #3465a4; 235 | } 236 | 237 | .terminal .xterm-bg-color-4 { 238 | background-color: #3465a4; 239 | } 240 | 241 | .terminal .xterm-color-5 { 242 | color: #75507b; 243 | } 244 | 245 | .terminal .xterm-bg-color-5 { 246 | background-color: #75507b; 247 | } 248 | 249 | .terminal .xterm-color-6 { 250 | color: #06989a; 251 | } 252 | 253 | .terminal .xterm-bg-color-6 { 254 | background-color: #06989a; 255 | } 256 | 257 | .terminal .xterm-color-7 { 258 | color: #d3d7cf; 259 | } 260 | 261 | .terminal .xterm-bg-color-7 { 262 | background-color: #d3d7cf; 263 | } 264 | 265 | .terminal .xterm-color-8 { 266 | color: #555753; 267 | } 268 | 269 | .terminal .xterm-bg-color-8 { 270 | background-color: #555753; 271 | } 272 | 273 | .terminal .xterm-color-9 { 274 | color: #ef2929; 275 | } 276 | 277 | .terminal .xterm-bg-color-9 { 278 | background-color: #ef2929; 279 | } 280 | 281 | .terminal .xterm-color-10 { 282 | color: #8ae234; 283 | } 284 | 285 | .terminal .xterm-bg-color-10 { 286 | background-color: #8ae234; 287 | } 288 | 289 | .terminal .xterm-color-11 { 290 | color: #fce94f; 291 | } 292 | 293 | .terminal .xterm-bg-color-11 { 294 | background-color: #fce94f; 295 | } 296 | 297 | .terminal .xterm-color-12 { 298 | color: #729fcf; 299 | } 300 | 301 | .terminal .xterm-bg-color-12 { 302 | background-color: #729fcf; 303 | } 304 | 305 | .terminal .xterm-color-13 { 306 | color: #ad7fa8; 307 | } 308 | 309 | .terminal .xterm-bg-color-13 { 310 | background-color: #ad7fa8; 311 | } 312 | 313 | .terminal .xterm-color-14 { 314 | color: #34e2e2; 315 | } 316 | 317 | .terminal .xterm-bg-color-14 { 318 | background-color: #34e2e2; 319 | } 320 | 321 | .terminal .xterm-color-15 { 322 | color: #eeeeec; 323 | } 324 | 325 | .terminal .xterm-bg-color-15 { 326 | background-color: #eeeeec; 327 | } 328 | 329 | .terminal .xterm-color-16 { 330 | color: #000000; 331 | } 332 | 333 | .terminal .xterm-bg-color-16 { 334 | background-color: #000000; 335 | } 336 | 337 | .terminal .xterm-color-17 { 338 | color: #00005f; 339 | } 340 | 341 | .terminal .xterm-bg-color-17 { 342 | background-color: #00005f; 343 | } 344 | 345 | .terminal .xterm-color-18 { 346 | color: #000087; 347 | } 348 | 349 | .terminal .xterm-bg-color-18 { 350 | background-color: #000087; 351 | } 352 | 353 | .terminal .xterm-color-19 { 354 | color: #0000af; 355 | } 356 | 357 | .terminal .xterm-bg-color-19 { 358 | background-color: #0000af; 359 | } 360 | 361 | .terminal .xterm-color-20 { 362 | color: #0000d7; 363 | } 364 | 365 | .terminal .xterm-bg-color-20 { 366 | background-color: #0000d7; 367 | } 368 | 369 | .terminal .xterm-color-21 { 370 | color: #0000ff; 371 | } 372 | 373 | .terminal .xterm-bg-color-21 { 374 | background-color: #0000ff; 375 | } 376 | 377 | .terminal .xterm-color-22 { 378 | color: #005f00; 379 | } 380 | 381 | .terminal .xterm-bg-color-22 { 382 | background-color: #005f00; 383 | } 384 | 385 | .terminal .xterm-color-23 { 386 | color: #005f5f; 387 | } 388 | 389 | .terminal .xterm-bg-color-23 { 390 | background-color: #005f5f; 391 | } 392 | 393 | .terminal .xterm-color-24 { 394 | color: #005f87; 395 | } 396 | 397 | .terminal .xterm-bg-color-24 { 398 | background-color: #005f87; 399 | } 400 | 401 | .terminal .xterm-color-25 { 402 | color: #005faf; 403 | } 404 | 405 | .terminal .xterm-bg-color-25 { 406 | background-color: #005faf; 407 | } 408 | 409 | .terminal .xterm-color-26 { 410 | color: #005fd7; 411 | } 412 | 413 | .terminal .xterm-bg-color-26 { 414 | background-color: #005fd7; 415 | } 416 | 417 | .terminal .xterm-color-27 { 418 | color: #005fff; 419 | } 420 | 421 | .terminal .xterm-bg-color-27 { 422 | background-color: #005fff; 423 | } 424 | 425 | .terminal .xterm-color-28 { 426 | color: #008700; 427 | } 428 | 429 | .terminal .xterm-bg-color-28 { 430 | background-color: #008700; 431 | } 432 | 433 | .terminal .xterm-color-29 { 434 | color: #00875f; 435 | } 436 | 437 | .terminal .xterm-bg-color-29 { 438 | background-color: #00875f; 439 | } 440 | 441 | .terminal .xterm-color-30 { 442 | color: #008787; 443 | } 444 | 445 | .terminal .xterm-bg-color-30 { 446 | background-color: #008787; 447 | } 448 | 449 | .terminal .xterm-color-31 { 450 | color: #0087af; 451 | } 452 | 453 | .terminal .xterm-bg-color-31 { 454 | background-color: #0087af; 455 | } 456 | 457 | .terminal .xterm-color-32 { 458 | color: #0087d7; 459 | } 460 | 461 | .terminal .xterm-bg-color-32 { 462 | background-color: #0087d7; 463 | } 464 | 465 | .terminal .xterm-color-33 { 466 | color: #0087ff; 467 | } 468 | 469 | .terminal .xterm-bg-color-33 { 470 | background-color: #0087ff; 471 | } 472 | 473 | .terminal .xterm-color-34 { 474 | color: #00af00; 475 | } 476 | 477 | .terminal .xterm-bg-color-34 { 478 | background-color: #00af00; 479 | } 480 | 481 | .terminal .xterm-color-35 { 482 | color: #00af5f; 483 | } 484 | 485 | .terminal .xterm-bg-color-35 { 486 | background-color: #00af5f; 487 | } 488 | 489 | .terminal .xterm-color-36 { 490 | color: #00af87; 491 | } 492 | 493 | .terminal .xterm-bg-color-36 { 494 | background-color: #00af87; 495 | } 496 | 497 | .terminal .xterm-color-37 { 498 | color: #00afaf; 499 | } 500 | 501 | .terminal .xterm-bg-color-37 { 502 | background-color: #00afaf; 503 | } 504 | 505 | .terminal .xterm-color-38 { 506 | color: #00afd7; 507 | } 508 | 509 | .terminal .xterm-bg-color-38 { 510 | background-color: #00afd7; 511 | } 512 | 513 | .terminal .xterm-color-39 { 514 | color: #00afff; 515 | } 516 | 517 | .terminal .xterm-bg-color-39 { 518 | background-color: #00afff; 519 | } 520 | 521 | .terminal .xterm-color-40 { 522 | color: #00d700; 523 | } 524 | 525 | .terminal .xterm-bg-color-40 { 526 | background-color: #00d700; 527 | } 528 | 529 | .terminal .xterm-color-41 { 530 | color: #00d75f; 531 | } 532 | 533 | .terminal .xterm-bg-color-41 { 534 | background-color: #00d75f; 535 | } 536 | 537 | .terminal .xterm-color-42 { 538 | color: #00d787; 539 | } 540 | 541 | .terminal .xterm-bg-color-42 { 542 | background-color: #00d787; 543 | } 544 | 545 | .terminal .xterm-color-43 { 546 | color: #00d7af; 547 | } 548 | 549 | .terminal .xterm-bg-color-43 { 550 | background-color: #00d7af; 551 | } 552 | 553 | .terminal .xterm-color-44 { 554 | color: #00d7d7; 555 | } 556 | 557 | .terminal .xterm-bg-color-44 { 558 | background-color: #00d7d7; 559 | } 560 | 561 | .terminal .xterm-color-45 { 562 | color: #00d7ff; 563 | } 564 | 565 | .terminal .xterm-bg-color-45 { 566 | background-color: #00d7ff; 567 | } 568 | 569 | .terminal .xterm-color-46 { 570 | color: #00ff00; 571 | } 572 | 573 | .terminal .xterm-bg-color-46 { 574 | background-color: #00ff00; 575 | } 576 | 577 | .terminal .xterm-color-47 { 578 | color: #00ff5f; 579 | } 580 | 581 | .terminal .xterm-bg-color-47 { 582 | background-color: #00ff5f; 583 | } 584 | 585 | .terminal .xterm-color-48 { 586 | color: #00ff87; 587 | } 588 | 589 | .terminal .xterm-bg-color-48 { 590 | background-color: #00ff87; 591 | } 592 | 593 | .terminal .xterm-color-49 { 594 | color: #00ffaf; 595 | } 596 | 597 | .terminal .xterm-bg-color-49 { 598 | background-color: #00ffaf; 599 | } 600 | 601 | .terminal .xterm-color-50 { 602 | color: #00ffd7; 603 | } 604 | 605 | .terminal .xterm-bg-color-50 { 606 | background-color: #00ffd7; 607 | } 608 | 609 | .terminal .xterm-color-51 { 610 | color: #00ffff; 611 | } 612 | 613 | .terminal .xterm-bg-color-51 { 614 | background-color: #00ffff; 615 | } 616 | 617 | .terminal .xterm-color-52 { 618 | color: #5f0000; 619 | } 620 | 621 | .terminal .xterm-bg-color-52 { 622 | background-color: #5f0000; 623 | } 624 | 625 | .terminal .xterm-color-53 { 626 | color: #5f005f; 627 | } 628 | 629 | .terminal .xterm-bg-color-53 { 630 | background-color: #5f005f; 631 | } 632 | 633 | .terminal .xterm-color-54 { 634 | color: #5f0087; 635 | } 636 | 637 | .terminal .xterm-bg-color-54 { 638 | background-color: #5f0087; 639 | } 640 | 641 | .terminal .xterm-color-55 { 642 | color: #5f00af; 643 | } 644 | 645 | .terminal .xterm-bg-color-55 { 646 | background-color: #5f00af; 647 | } 648 | 649 | .terminal .xterm-color-56 { 650 | color: #5f00d7; 651 | } 652 | 653 | .terminal .xterm-bg-color-56 { 654 | background-color: #5f00d7; 655 | } 656 | 657 | .terminal .xterm-color-57 { 658 | color: #5f00ff; 659 | } 660 | 661 | .terminal .xterm-bg-color-57 { 662 | background-color: #5f00ff; 663 | } 664 | 665 | .terminal .xterm-color-58 { 666 | color: #5f5f00; 667 | } 668 | 669 | .terminal .xterm-bg-color-58 { 670 | background-color: #5f5f00; 671 | } 672 | 673 | .terminal .xterm-color-59 { 674 | color: #5f5f5f; 675 | } 676 | 677 | .terminal .xterm-bg-color-59 { 678 | background-color: #5f5f5f; 679 | } 680 | 681 | .terminal .xterm-color-60 { 682 | color: #5f5f87; 683 | } 684 | 685 | .terminal .xterm-bg-color-60 { 686 | background-color: #5f5f87; 687 | } 688 | 689 | .terminal .xterm-color-61 { 690 | color: #5f5faf; 691 | } 692 | 693 | .terminal .xterm-bg-color-61 { 694 | background-color: #5f5faf; 695 | } 696 | 697 | .terminal .xterm-color-62 { 698 | color: #5f5fd7; 699 | } 700 | 701 | .terminal .xterm-bg-color-62 { 702 | background-color: #5f5fd7; 703 | } 704 | 705 | .terminal .xterm-color-63 { 706 | color: #5f5fff; 707 | } 708 | 709 | .terminal .xterm-bg-color-63 { 710 | background-color: #5f5fff; 711 | } 712 | 713 | .terminal .xterm-color-64 { 714 | color: #5f8700; 715 | } 716 | 717 | .terminal .xterm-bg-color-64 { 718 | background-color: #5f8700; 719 | } 720 | 721 | .terminal .xterm-color-65 { 722 | color: #5f875f; 723 | } 724 | 725 | .terminal .xterm-bg-color-65 { 726 | background-color: #5f875f; 727 | } 728 | 729 | .terminal .xterm-color-66 { 730 | color: #5f8787; 731 | } 732 | 733 | .terminal .xterm-bg-color-66 { 734 | background-color: #5f8787; 735 | } 736 | 737 | .terminal .xterm-color-67 { 738 | color: #5f87af; 739 | } 740 | 741 | .terminal .xterm-bg-color-67 { 742 | background-color: #5f87af; 743 | } 744 | 745 | .terminal .xterm-color-68 { 746 | color: #5f87d7; 747 | } 748 | 749 | .terminal .xterm-bg-color-68 { 750 | background-color: #5f87d7; 751 | } 752 | 753 | .terminal .xterm-color-69 { 754 | color: #5f87ff; 755 | } 756 | 757 | .terminal .xterm-bg-color-69 { 758 | background-color: #5f87ff; 759 | } 760 | 761 | .terminal .xterm-color-70 { 762 | color: #5faf00; 763 | } 764 | 765 | .terminal .xterm-bg-color-70 { 766 | background-color: #5faf00; 767 | } 768 | 769 | .terminal .xterm-color-71 { 770 | color: #5faf5f; 771 | } 772 | 773 | .terminal .xterm-bg-color-71 { 774 | background-color: #5faf5f; 775 | } 776 | 777 | .terminal .xterm-color-72 { 778 | color: #5faf87; 779 | } 780 | 781 | .terminal .xterm-bg-color-72 { 782 | background-color: #5faf87; 783 | } 784 | 785 | .terminal .xterm-color-73 { 786 | color: #5fafaf; 787 | } 788 | 789 | .terminal .xterm-bg-color-73 { 790 | background-color: #5fafaf; 791 | } 792 | 793 | .terminal .xterm-color-74 { 794 | color: #5fafd7; 795 | } 796 | 797 | .terminal .xterm-bg-color-74 { 798 | background-color: #5fafd7; 799 | } 800 | 801 | .terminal .xterm-color-75 { 802 | color: #5fafff; 803 | } 804 | 805 | .terminal .xterm-bg-color-75 { 806 | background-color: #5fafff; 807 | } 808 | 809 | .terminal .xterm-color-76 { 810 | color: #5fd700; 811 | } 812 | 813 | .terminal .xterm-bg-color-76 { 814 | background-color: #5fd700; 815 | } 816 | 817 | .terminal .xterm-color-77 { 818 | color: #5fd75f; 819 | } 820 | 821 | .terminal .xterm-bg-color-77 { 822 | background-color: #5fd75f; 823 | } 824 | 825 | .terminal .xterm-color-78 { 826 | color: #5fd787; 827 | } 828 | 829 | .terminal .xterm-bg-color-78 { 830 | background-color: #5fd787; 831 | } 832 | 833 | .terminal .xterm-color-79 { 834 | color: #5fd7af; 835 | } 836 | 837 | .terminal .xterm-bg-color-79 { 838 | background-color: #5fd7af; 839 | } 840 | 841 | .terminal .xterm-color-80 { 842 | color: #5fd7d7; 843 | } 844 | 845 | .terminal .xterm-bg-color-80 { 846 | background-color: #5fd7d7; 847 | } 848 | 849 | .terminal .xterm-color-81 { 850 | color: #5fd7ff; 851 | } 852 | 853 | .terminal .xterm-bg-color-81 { 854 | background-color: #5fd7ff; 855 | } 856 | 857 | .terminal .xterm-color-82 { 858 | color: #5fff00; 859 | } 860 | 861 | .terminal .xterm-bg-color-82 { 862 | background-color: #5fff00; 863 | } 864 | 865 | .terminal .xterm-color-83 { 866 | color: #5fff5f; 867 | } 868 | 869 | .terminal .xterm-bg-color-83 { 870 | background-color: #5fff5f; 871 | } 872 | 873 | .terminal .xterm-color-84 { 874 | color: #5fff87; 875 | } 876 | 877 | .terminal .xterm-bg-color-84 { 878 | background-color: #5fff87; 879 | } 880 | 881 | .terminal .xterm-color-85 { 882 | color: #5fffaf; 883 | } 884 | 885 | .terminal .xterm-bg-color-85 { 886 | background-color: #5fffaf; 887 | } 888 | 889 | .terminal .xterm-color-86 { 890 | color: #5fffd7; 891 | } 892 | 893 | .terminal .xterm-bg-color-86 { 894 | background-color: #5fffd7; 895 | } 896 | 897 | .terminal .xterm-color-87 { 898 | color: #5fffff; 899 | } 900 | 901 | .terminal .xterm-bg-color-87 { 902 | background-color: #5fffff; 903 | } 904 | 905 | .terminal .xterm-color-88 { 906 | color: #870000; 907 | } 908 | 909 | .terminal .xterm-bg-color-88 { 910 | background-color: #870000; 911 | } 912 | 913 | .terminal .xterm-color-89 { 914 | color: #87005f; 915 | } 916 | 917 | .terminal .xterm-bg-color-89 { 918 | background-color: #87005f; 919 | } 920 | 921 | .terminal .xterm-color-90 { 922 | color: #870087; 923 | } 924 | 925 | .terminal .xterm-bg-color-90 { 926 | background-color: #870087; 927 | } 928 | 929 | .terminal .xterm-color-91 { 930 | color: #8700af; 931 | } 932 | 933 | .terminal .xterm-bg-color-91 { 934 | background-color: #8700af; 935 | } 936 | 937 | .terminal .xterm-color-92 { 938 | color: #8700d7; 939 | } 940 | 941 | .terminal .xterm-bg-color-92 { 942 | background-color: #8700d7; 943 | } 944 | 945 | .terminal .xterm-color-93 { 946 | color: #8700ff; 947 | } 948 | 949 | .terminal .xterm-bg-color-93 { 950 | background-color: #8700ff; 951 | } 952 | 953 | .terminal .xterm-color-94 { 954 | color: #875f00; 955 | } 956 | 957 | .terminal .xterm-bg-color-94 { 958 | background-color: #875f00; 959 | } 960 | 961 | .terminal .xterm-color-95 { 962 | color: #875f5f; 963 | } 964 | 965 | .terminal .xterm-bg-color-95 { 966 | background-color: #875f5f; 967 | } 968 | 969 | .terminal .xterm-color-96 { 970 | color: #875f87; 971 | } 972 | 973 | .terminal .xterm-bg-color-96 { 974 | background-color: #875f87; 975 | } 976 | 977 | .terminal .xterm-color-97 { 978 | color: #875faf; 979 | } 980 | 981 | .terminal .xterm-bg-color-97 { 982 | background-color: #875faf; 983 | } 984 | 985 | .terminal .xterm-color-98 { 986 | color: #875fd7; 987 | } 988 | 989 | .terminal .xterm-bg-color-98 { 990 | background-color: #875fd7; 991 | } 992 | 993 | .terminal .xterm-color-99 { 994 | color: #875fff; 995 | } 996 | 997 | .terminal .xterm-bg-color-99 { 998 | background-color: #875fff; 999 | } 1000 | 1001 | .terminal .xterm-color-100 { 1002 | color: #878700; 1003 | } 1004 | 1005 | .terminal .xterm-bg-color-100 { 1006 | background-color: #878700; 1007 | } 1008 | 1009 | .terminal .xterm-color-101 { 1010 | color: #87875f; 1011 | } 1012 | 1013 | .terminal .xterm-bg-color-101 { 1014 | background-color: #87875f; 1015 | } 1016 | 1017 | .terminal .xterm-color-102 { 1018 | color: #878787; 1019 | } 1020 | 1021 | .terminal .xterm-bg-color-102 { 1022 | background-color: #878787; 1023 | } 1024 | 1025 | .terminal .xterm-color-103 { 1026 | color: #8787af; 1027 | } 1028 | 1029 | .terminal .xterm-bg-color-103 { 1030 | background-color: #8787af; 1031 | } 1032 | 1033 | .terminal .xterm-color-104 { 1034 | color: #8787d7; 1035 | } 1036 | 1037 | .terminal .xterm-bg-color-104 { 1038 | background-color: #8787d7; 1039 | } 1040 | 1041 | .terminal .xterm-color-105 { 1042 | color: #8787ff; 1043 | } 1044 | 1045 | .terminal .xterm-bg-color-105 { 1046 | background-color: #8787ff; 1047 | } 1048 | 1049 | .terminal .xterm-color-106 { 1050 | color: #87af00; 1051 | } 1052 | 1053 | .terminal .xterm-bg-color-106 { 1054 | background-color: #87af00; 1055 | } 1056 | 1057 | .terminal .xterm-color-107 { 1058 | color: #87af5f; 1059 | } 1060 | 1061 | .terminal .xterm-bg-color-107 { 1062 | background-color: #87af5f; 1063 | } 1064 | 1065 | .terminal .xterm-color-108 { 1066 | color: #87af87; 1067 | } 1068 | 1069 | .terminal .xterm-bg-color-108 { 1070 | background-color: #87af87; 1071 | } 1072 | 1073 | .terminal .xterm-color-109 { 1074 | color: #87afaf; 1075 | } 1076 | 1077 | .terminal .xterm-bg-color-109 { 1078 | background-color: #87afaf; 1079 | } 1080 | 1081 | .terminal .xterm-color-110 { 1082 | color: #87afd7; 1083 | } 1084 | 1085 | .terminal .xterm-bg-color-110 { 1086 | background-color: #87afd7; 1087 | } 1088 | 1089 | .terminal .xterm-color-111 { 1090 | color: #87afff; 1091 | } 1092 | 1093 | .terminal .xterm-bg-color-111 { 1094 | background-color: #87afff; 1095 | } 1096 | 1097 | .terminal .xterm-color-112 { 1098 | color: #87d700; 1099 | } 1100 | 1101 | .terminal .xterm-bg-color-112 { 1102 | background-color: #87d700; 1103 | } 1104 | 1105 | .terminal .xterm-color-113 { 1106 | color: #87d75f; 1107 | } 1108 | 1109 | .terminal .xterm-bg-color-113 { 1110 | background-color: #87d75f; 1111 | } 1112 | 1113 | .terminal .xterm-color-114 { 1114 | color: #87d787; 1115 | } 1116 | 1117 | .terminal .xterm-bg-color-114 { 1118 | background-color: #87d787; 1119 | } 1120 | 1121 | .terminal .xterm-color-115 { 1122 | color: #87d7af; 1123 | } 1124 | 1125 | .terminal .xterm-bg-color-115 { 1126 | background-color: #87d7af; 1127 | } 1128 | 1129 | .terminal .xterm-color-116 { 1130 | color: #87d7d7; 1131 | } 1132 | 1133 | .terminal .xterm-bg-color-116 { 1134 | background-color: #87d7d7; 1135 | } 1136 | 1137 | .terminal .xterm-color-117 { 1138 | color: #87d7ff; 1139 | } 1140 | 1141 | .terminal .xterm-bg-color-117 { 1142 | background-color: #87d7ff; 1143 | } 1144 | 1145 | .terminal .xterm-color-118 { 1146 | color: #87ff00; 1147 | } 1148 | 1149 | .terminal .xterm-bg-color-118 { 1150 | background-color: #87ff00; 1151 | } 1152 | 1153 | .terminal .xterm-color-119 { 1154 | color: #87ff5f; 1155 | } 1156 | 1157 | .terminal .xterm-bg-color-119 { 1158 | background-color: #87ff5f; 1159 | } 1160 | 1161 | .terminal .xterm-color-120 { 1162 | color: #87ff87; 1163 | } 1164 | 1165 | .terminal .xterm-bg-color-120 { 1166 | background-color: #87ff87; 1167 | } 1168 | 1169 | .terminal .xterm-color-121 { 1170 | color: #87ffaf; 1171 | } 1172 | 1173 | .terminal .xterm-bg-color-121 { 1174 | background-color: #87ffaf; 1175 | } 1176 | 1177 | .terminal .xterm-color-122 { 1178 | color: #87ffd7; 1179 | } 1180 | 1181 | .terminal .xterm-bg-color-122 { 1182 | background-color: #87ffd7; 1183 | } 1184 | 1185 | .terminal .xterm-color-123 { 1186 | color: #87ffff; 1187 | } 1188 | 1189 | .terminal .xterm-bg-color-123 { 1190 | background-color: #87ffff; 1191 | } 1192 | 1193 | .terminal .xterm-color-124 { 1194 | color: #af0000; 1195 | } 1196 | 1197 | .terminal .xterm-bg-color-124 { 1198 | background-color: #af0000; 1199 | } 1200 | 1201 | .terminal .xterm-color-125 { 1202 | color: #af005f; 1203 | } 1204 | 1205 | .terminal .xterm-bg-color-125 { 1206 | background-color: #af005f; 1207 | } 1208 | 1209 | .terminal .xterm-color-126 { 1210 | color: #af0087; 1211 | } 1212 | 1213 | .terminal .xterm-bg-color-126 { 1214 | background-color: #af0087; 1215 | } 1216 | 1217 | .terminal .xterm-color-127 { 1218 | color: #af00af; 1219 | } 1220 | 1221 | .terminal .xterm-bg-color-127 { 1222 | background-color: #af00af; 1223 | } 1224 | 1225 | .terminal .xterm-color-128 { 1226 | color: #af00d7; 1227 | } 1228 | 1229 | .terminal .xterm-bg-color-128 { 1230 | background-color: #af00d7; 1231 | } 1232 | 1233 | .terminal .xterm-color-129 { 1234 | color: #af00ff; 1235 | } 1236 | 1237 | .terminal .xterm-bg-color-129 { 1238 | background-color: #af00ff; 1239 | } 1240 | 1241 | .terminal .xterm-color-130 { 1242 | color: #af5f00; 1243 | } 1244 | 1245 | .terminal .xterm-bg-color-130 { 1246 | background-color: #af5f00; 1247 | } 1248 | 1249 | .terminal .xterm-color-131 { 1250 | color: #af5f5f; 1251 | } 1252 | 1253 | .terminal .xterm-bg-color-131 { 1254 | background-color: #af5f5f; 1255 | } 1256 | 1257 | .terminal .xterm-color-132 { 1258 | color: #af5f87; 1259 | } 1260 | 1261 | .terminal .xterm-bg-color-132 { 1262 | background-color: #af5f87; 1263 | } 1264 | 1265 | .terminal .xterm-color-133 { 1266 | color: #af5faf; 1267 | } 1268 | 1269 | .terminal .xterm-bg-color-133 { 1270 | background-color: #af5faf; 1271 | } 1272 | 1273 | .terminal .xterm-color-134 { 1274 | color: #af5fd7; 1275 | } 1276 | 1277 | .terminal .xterm-bg-color-134 { 1278 | background-color: #af5fd7; 1279 | } 1280 | 1281 | .terminal .xterm-color-135 { 1282 | color: #af5fff; 1283 | } 1284 | 1285 | .terminal .xterm-bg-color-135 { 1286 | background-color: #af5fff; 1287 | } 1288 | 1289 | .terminal .xterm-color-136 { 1290 | color: #af8700; 1291 | } 1292 | 1293 | .terminal .xterm-bg-color-136 { 1294 | background-color: #af8700; 1295 | } 1296 | 1297 | .terminal .xterm-color-137 { 1298 | color: #af875f; 1299 | } 1300 | 1301 | .terminal .xterm-bg-color-137 { 1302 | background-color: #af875f; 1303 | } 1304 | 1305 | .terminal .xterm-color-138 { 1306 | color: #af8787; 1307 | } 1308 | 1309 | .terminal .xterm-bg-color-138 { 1310 | background-color: #af8787; 1311 | } 1312 | 1313 | .terminal .xterm-color-139 { 1314 | color: #af87af; 1315 | } 1316 | 1317 | .terminal .xterm-bg-color-139 { 1318 | background-color: #af87af; 1319 | } 1320 | 1321 | .terminal .xterm-color-140 { 1322 | color: #af87d7; 1323 | } 1324 | 1325 | .terminal .xterm-bg-color-140 { 1326 | background-color: #af87d7; 1327 | } 1328 | 1329 | .terminal .xterm-color-141 { 1330 | color: #af87ff; 1331 | } 1332 | 1333 | .terminal .xterm-bg-color-141 { 1334 | background-color: #af87ff; 1335 | } 1336 | 1337 | .terminal .xterm-color-142 { 1338 | color: #afaf00; 1339 | } 1340 | 1341 | .terminal .xterm-bg-color-142 { 1342 | background-color: #afaf00; 1343 | } 1344 | 1345 | .terminal .xterm-color-143 { 1346 | color: #afaf5f; 1347 | } 1348 | 1349 | .terminal .xterm-bg-color-143 { 1350 | background-color: #afaf5f; 1351 | } 1352 | 1353 | .terminal .xterm-color-144 { 1354 | color: #afaf87; 1355 | } 1356 | 1357 | .terminal .xterm-bg-color-144 { 1358 | background-color: #afaf87; 1359 | } 1360 | 1361 | .terminal .xterm-color-145 { 1362 | color: #afafaf; 1363 | } 1364 | 1365 | .terminal .xterm-bg-color-145 { 1366 | background-color: #afafaf; 1367 | } 1368 | 1369 | .terminal .xterm-color-146 { 1370 | color: #afafd7; 1371 | } 1372 | 1373 | .terminal .xterm-bg-color-146 { 1374 | background-color: #afafd7; 1375 | } 1376 | 1377 | .terminal .xterm-color-147 { 1378 | color: #afafff; 1379 | } 1380 | 1381 | .terminal .xterm-bg-color-147 { 1382 | background-color: #afafff; 1383 | } 1384 | 1385 | .terminal .xterm-color-148 { 1386 | color: #afd700; 1387 | } 1388 | 1389 | .terminal .xterm-bg-color-148 { 1390 | background-color: #afd700; 1391 | } 1392 | 1393 | .terminal .xterm-color-149 { 1394 | color: #afd75f; 1395 | } 1396 | 1397 | .terminal .xterm-bg-color-149 { 1398 | background-color: #afd75f; 1399 | } 1400 | 1401 | .terminal .xterm-color-150 { 1402 | color: #afd787; 1403 | } 1404 | 1405 | .terminal .xterm-bg-color-150 { 1406 | background-color: #afd787; 1407 | } 1408 | 1409 | .terminal .xterm-color-151 { 1410 | color: #afd7af; 1411 | } 1412 | 1413 | .terminal .xterm-bg-color-151 { 1414 | background-color: #afd7af; 1415 | } 1416 | 1417 | .terminal .xterm-color-152 { 1418 | color: #afd7d7; 1419 | } 1420 | 1421 | .terminal .xterm-bg-color-152 { 1422 | background-color: #afd7d7; 1423 | } 1424 | 1425 | .terminal .xterm-color-153 { 1426 | color: #afd7ff; 1427 | } 1428 | 1429 | .terminal .xterm-bg-color-153 { 1430 | background-color: #afd7ff; 1431 | } 1432 | 1433 | .terminal .xterm-color-154 { 1434 | color: #afff00; 1435 | } 1436 | 1437 | .terminal .xterm-bg-color-154 { 1438 | background-color: #afff00; 1439 | } 1440 | 1441 | .terminal .xterm-color-155 { 1442 | color: #afff5f; 1443 | } 1444 | 1445 | .terminal .xterm-bg-color-155 { 1446 | background-color: #afff5f; 1447 | } 1448 | 1449 | .terminal .xterm-color-156 { 1450 | color: #afff87; 1451 | } 1452 | 1453 | .terminal .xterm-bg-color-156 { 1454 | background-color: #afff87; 1455 | } 1456 | 1457 | .terminal .xterm-color-157 { 1458 | color: #afffaf; 1459 | } 1460 | 1461 | .terminal .xterm-bg-color-157 { 1462 | background-color: #afffaf; 1463 | } 1464 | 1465 | .terminal .xterm-color-158 { 1466 | color: #afffd7; 1467 | } 1468 | 1469 | .terminal .xterm-bg-color-158 { 1470 | background-color: #afffd7; 1471 | } 1472 | 1473 | .terminal .xterm-color-159 { 1474 | color: #afffff; 1475 | } 1476 | 1477 | .terminal .xterm-bg-color-159 { 1478 | background-color: #afffff; 1479 | } 1480 | 1481 | .terminal .xterm-color-160 { 1482 | color: #d70000; 1483 | } 1484 | 1485 | .terminal .xterm-bg-color-160 { 1486 | background-color: #d70000; 1487 | } 1488 | 1489 | .terminal .xterm-color-161 { 1490 | color: #d7005f; 1491 | } 1492 | 1493 | .terminal .xterm-bg-color-161 { 1494 | background-color: #d7005f; 1495 | } 1496 | 1497 | .terminal .xterm-color-162 { 1498 | color: #d70087; 1499 | } 1500 | 1501 | .terminal .xterm-bg-color-162 { 1502 | background-color: #d70087; 1503 | } 1504 | 1505 | .terminal .xterm-color-163 { 1506 | color: #d700af; 1507 | } 1508 | 1509 | .terminal .xterm-bg-color-163 { 1510 | background-color: #d700af; 1511 | } 1512 | 1513 | .terminal .xterm-color-164 { 1514 | color: #d700d7; 1515 | } 1516 | 1517 | .terminal .xterm-bg-color-164 { 1518 | background-color: #d700d7; 1519 | } 1520 | 1521 | .terminal .xterm-color-165 { 1522 | color: #d700ff; 1523 | } 1524 | 1525 | .terminal .xterm-bg-color-165 { 1526 | background-color: #d700ff; 1527 | } 1528 | 1529 | .terminal .xterm-color-166 { 1530 | color: #d75f00; 1531 | } 1532 | 1533 | .terminal .xterm-bg-color-166 { 1534 | background-color: #d75f00; 1535 | } 1536 | 1537 | .terminal .xterm-color-167 { 1538 | color: #d75f5f; 1539 | } 1540 | 1541 | .terminal .xterm-bg-color-167 { 1542 | background-color: #d75f5f; 1543 | } 1544 | 1545 | .terminal .xterm-color-168 { 1546 | color: #d75f87; 1547 | } 1548 | 1549 | .terminal .xterm-bg-color-168 { 1550 | background-color: #d75f87; 1551 | } 1552 | 1553 | .terminal .xterm-color-169 { 1554 | color: #d75faf; 1555 | } 1556 | 1557 | .terminal .xterm-bg-color-169 { 1558 | background-color: #d75faf; 1559 | } 1560 | 1561 | .terminal .xterm-color-170 { 1562 | color: #d75fd7; 1563 | } 1564 | 1565 | .terminal .xterm-bg-color-170 { 1566 | background-color: #d75fd7; 1567 | } 1568 | 1569 | .terminal .xterm-color-171 { 1570 | color: #d75fff; 1571 | } 1572 | 1573 | .terminal .xterm-bg-color-171 { 1574 | background-color: #d75fff; 1575 | } 1576 | 1577 | .terminal .xterm-color-172 { 1578 | color: #d78700; 1579 | } 1580 | 1581 | .terminal .xterm-bg-color-172 { 1582 | background-color: #d78700; 1583 | } 1584 | 1585 | .terminal .xterm-color-173 { 1586 | color: #d7875f; 1587 | } 1588 | 1589 | .terminal .xterm-bg-color-173 { 1590 | background-color: #d7875f; 1591 | } 1592 | 1593 | .terminal .xterm-color-174 { 1594 | color: #d78787; 1595 | } 1596 | 1597 | .terminal .xterm-bg-color-174 { 1598 | background-color: #d78787; 1599 | } 1600 | 1601 | .terminal .xterm-color-175 { 1602 | color: #d787af; 1603 | } 1604 | 1605 | .terminal .xterm-bg-color-175 { 1606 | background-color: #d787af; 1607 | } 1608 | 1609 | .terminal .xterm-color-176 { 1610 | color: #d787d7; 1611 | } 1612 | 1613 | .terminal .xterm-bg-color-176 { 1614 | background-color: #d787d7; 1615 | } 1616 | 1617 | .terminal .xterm-color-177 { 1618 | color: #d787ff; 1619 | } 1620 | 1621 | .terminal .xterm-bg-color-177 { 1622 | background-color: #d787ff; 1623 | } 1624 | 1625 | .terminal .xterm-color-178 { 1626 | color: #d7af00; 1627 | } 1628 | 1629 | .terminal .xterm-bg-color-178 { 1630 | background-color: #d7af00; 1631 | } 1632 | 1633 | .terminal .xterm-color-179 { 1634 | color: #d7af5f; 1635 | } 1636 | 1637 | .terminal .xterm-bg-color-179 { 1638 | background-color: #d7af5f; 1639 | } 1640 | 1641 | .terminal .xterm-color-180 { 1642 | color: #d7af87; 1643 | } 1644 | 1645 | .terminal .xterm-bg-color-180 { 1646 | background-color: #d7af87; 1647 | } 1648 | 1649 | .terminal .xterm-color-181 { 1650 | color: #d7afaf; 1651 | } 1652 | 1653 | .terminal .xterm-bg-color-181 { 1654 | background-color: #d7afaf; 1655 | } 1656 | 1657 | .terminal .xterm-color-182 { 1658 | color: #d7afd7; 1659 | } 1660 | 1661 | .terminal .xterm-bg-color-182 { 1662 | background-color: #d7afd7; 1663 | } 1664 | 1665 | .terminal .xterm-color-183 { 1666 | color: #d7afff; 1667 | } 1668 | 1669 | .terminal .xterm-bg-color-183 { 1670 | background-color: #d7afff; 1671 | } 1672 | 1673 | .terminal .xterm-color-184 { 1674 | color: #d7d700; 1675 | } 1676 | 1677 | .terminal .xterm-bg-color-184 { 1678 | background-color: #d7d700; 1679 | } 1680 | 1681 | .terminal .xterm-color-185 { 1682 | color: #d7d75f; 1683 | } 1684 | 1685 | .terminal .xterm-bg-color-185 { 1686 | background-color: #d7d75f; 1687 | } 1688 | 1689 | .terminal .xterm-color-186 { 1690 | color: #d7d787; 1691 | } 1692 | 1693 | .terminal .xterm-bg-color-186 { 1694 | background-color: #d7d787; 1695 | } 1696 | 1697 | .terminal .xterm-color-187 { 1698 | color: #d7d7af; 1699 | } 1700 | 1701 | .terminal .xterm-bg-color-187 { 1702 | background-color: #d7d7af; 1703 | } 1704 | 1705 | .terminal .xterm-color-188 { 1706 | color: #d7d7d7; 1707 | } 1708 | 1709 | .terminal .xterm-bg-color-188 { 1710 | background-color: #d7d7d7; 1711 | } 1712 | 1713 | .terminal .xterm-color-189 { 1714 | color: #d7d7ff; 1715 | } 1716 | 1717 | .terminal .xterm-bg-color-189 { 1718 | background-color: #d7d7ff; 1719 | } 1720 | 1721 | .terminal .xterm-color-190 { 1722 | color: #d7ff00; 1723 | } 1724 | 1725 | .terminal .xterm-bg-color-190 { 1726 | background-color: #d7ff00; 1727 | } 1728 | 1729 | .terminal .xterm-color-191 { 1730 | color: #d7ff5f; 1731 | } 1732 | 1733 | .terminal .xterm-bg-color-191 { 1734 | background-color: #d7ff5f; 1735 | } 1736 | 1737 | .terminal .xterm-color-192 { 1738 | color: #d7ff87; 1739 | } 1740 | 1741 | .terminal .xterm-bg-color-192 { 1742 | background-color: #d7ff87; 1743 | } 1744 | 1745 | .terminal .xterm-color-193 { 1746 | color: #d7ffaf; 1747 | } 1748 | 1749 | .terminal .xterm-bg-color-193 { 1750 | background-color: #d7ffaf; 1751 | } 1752 | 1753 | .terminal .xterm-color-194 { 1754 | color: #d7ffd7; 1755 | } 1756 | 1757 | .terminal .xterm-bg-color-194 { 1758 | background-color: #d7ffd7; 1759 | } 1760 | 1761 | .terminal .xterm-color-195 { 1762 | color: #d7ffff; 1763 | } 1764 | 1765 | .terminal .xterm-bg-color-195 { 1766 | background-color: #d7ffff; 1767 | } 1768 | 1769 | .terminal .xterm-color-196 { 1770 | color: #ff0000; 1771 | } 1772 | 1773 | .terminal .xterm-bg-color-196 { 1774 | background-color: #ff0000; 1775 | } 1776 | 1777 | .terminal .xterm-color-197 { 1778 | color: #ff005f; 1779 | } 1780 | 1781 | .terminal .xterm-bg-color-197 { 1782 | background-color: #ff005f; 1783 | } 1784 | 1785 | .terminal .xterm-color-198 { 1786 | color: #ff0087; 1787 | } 1788 | 1789 | .terminal .xterm-bg-color-198 { 1790 | background-color: #ff0087; 1791 | } 1792 | 1793 | .terminal .xterm-color-199 { 1794 | color: #ff00af; 1795 | } 1796 | 1797 | .terminal .xterm-bg-color-199 { 1798 | background-color: #ff00af; 1799 | } 1800 | 1801 | .terminal .xterm-color-200 { 1802 | color: #ff00d7; 1803 | } 1804 | 1805 | .terminal .xterm-bg-color-200 { 1806 | background-color: #ff00d7; 1807 | } 1808 | 1809 | .terminal .xterm-color-201 { 1810 | color: #ff00ff; 1811 | } 1812 | 1813 | .terminal .xterm-bg-color-201 { 1814 | background-color: #ff00ff; 1815 | } 1816 | 1817 | .terminal .xterm-color-202 { 1818 | color: #ff5f00; 1819 | } 1820 | 1821 | .terminal .xterm-bg-color-202 { 1822 | background-color: #ff5f00; 1823 | } 1824 | 1825 | .terminal .xterm-color-203 { 1826 | color: #ff5f5f; 1827 | } 1828 | 1829 | .terminal .xterm-bg-color-203 { 1830 | background-color: #ff5f5f; 1831 | } 1832 | 1833 | .terminal .xterm-color-204 { 1834 | color: #ff5f87; 1835 | } 1836 | 1837 | .terminal .xterm-bg-color-204 { 1838 | background-color: #ff5f87; 1839 | } 1840 | 1841 | .terminal .xterm-color-205 { 1842 | color: #ff5faf; 1843 | } 1844 | 1845 | .terminal .xterm-bg-color-205 { 1846 | background-color: #ff5faf; 1847 | } 1848 | 1849 | .terminal .xterm-color-206 { 1850 | color: #ff5fd7; 1851 | } 1852 | 1853 | .terminal .xterm-bg-color-206 { 1854 | background-color: #ff5fd7; 1855 | } 1856 | 1857 | .terminal .xterm-color-207 { 1858 | color: #ff5fff; 1859 | } 1860 | 1861 | .terminal .xterm-bg-color-207 { 1862 | background-color: #ff5fff; 1863 | } 1864 | 1865 | .terminal .xterm-color-208 { 1866 | color: #ff8700; 1867 | } 1868 | 1869 | .terminal .xterm-bg-color-208 { 1870 | background-color: #ff8700; 1871 | } 1872 | 1873 | .terminal .xterm-color-209 { 1874 | color: #ff875f; 1875 | } 1876 | 1877 | .terminal .xterm-bg-color-209 { 1878 | background-color: #ff875f; 1879 | } 1880 | 1881 | .terminal .xterm-color-210 { 1882 | color: #ff8787; 1883 | } 1884 | 1885 | .terminal .xterm-bg-color-210 { 1886 | background-color: #ff8787; 1887 | } 1888 | 1889 | .terminal .xterm-color-211 { 1890 | color: #ff87af; 1891 | } 1892 | 1893 | .terminal .xterm-bg-color-211 { 1894 | background-color: #ff87af; 1895 | } 1896 | 1897 | .terminal .xterm-color-212 { 1898 | color: #ff87d7; 1899 | } 1900 | 1901 | .terminal .xterm-bg-color-212 { 1902 | background-color: #ff87d7; 1903 | } 1904 | 1905 | .terminal .xterm-color-213 { 1906 | color: #ff87ff; 1907 | } 1908 | 1909 | .terminal .xterm-bg-color-213 { 1910 | background-color: #ff87ff; 1911 | } 1912 | 1913 | .terminal .xterm-color-214 { 1914 | color: #ffaf00; 1915 | } 1916 | 1917 | .terminal .xterm-bg-color-214 { 1918 | background-color: #ffaf00; 1919 | } 1920 | 1921 | .terminal .xterm-color-215 { 1922 | color: #ffaf5f; 1923 | } 1924 | 1925 | .terminal .xterm-bg-color-215 { 1926 | background-color: #ffaf5f; 1927 | } 1928 | 1929 | .terminal .xterm-color-216 { 1930 | color: #ffaf87; 1931 | } 1932 | 1933 | .terminal .xterm-bg-color-216 { 1934 | background-color: #ffaf87; 1935 | } 1936 | 1937 | .terminal .xterm-color-217 { 1938 | color: #ffafaf; 1939 | } 1940 | 1941 | .terminal .xterm-bg-color-217 { 1942 | background-color: #ffafaf; 1943 | } 1944 | 1945 | .terminal .xterm-color-218 { 1946 | color: #ffafd7; 1947 | } 1948 | 1949 | .terminal .xterm-bg-color-218 { 1950 | background-color: #ffafd7; 1951 | } 1952 | 1953 | .terminal .xterm-color-219 { 1954 | color: #ffafff; 1955 | } 1956 | 1957 | .terminal .xterm-bg-color-219 { 1958 | background-color: #ffafff; 1959 | } 1960 | 1961 | .terminal .xterm-color-220 { 1962 | color: #ffd700; 1963 | } 1964 | 1965 | .terminal .xterm-bg-color-220 { 1966 | background-color: #ffd700; 1967 | } 1968 | 1969 | .terminal .xterm-color-221 { 1970 | color: #ffd75f; 1971 | } 1972 | 1973 | .terminal .xterm-bg-color-221 { 1974 | background-color: #ffd75f; 1975 | } 1976 | 1977 | .terminal .xterm-color-222 { 1978 | color: #ffd787; 1979 | } 1980 | 1981 | .terminal .xterm-bg-color-222 { 1982 | background-color: #ffd787; 1983 | } 1984 | 1985 | .terminal .xterm-color-223 { 1986 | color: #ffd7af; 1987 | } 1988 | 1989 | .terminal .xterm-bg-color-223 { 1990 | background-color: #ffd7af; 1991 | } 1992 | 1993 | .terminal .xterm-color-224 { 1994 | color: #ffd7d7; 1995 | } 1996 | 1997 | .terminal .xterm-bg-color-224 { 1998 | background-color: #ffd7d7; 1999 | } 2000 | 2001 | .terminal .xterm-color-225 { 2002 | color: #ffd7ff; 2003 | } 2004 | 2005 | .terminal .xterm-bg-color-225 { 2006 | background-color: #ffd7ff; 2007 | } 2008 | 2009 | .terminal .xterm-color-226 { 2010 | color: #ffff00; 2011 | } 2012 | 2013 | .terminal .xterm-bg-color-226 { 2014 | background-color: #ffff00; 2015 | } 2016 | 2017 | .terminal .xterm-color-227 { 2018 | color: #ffff5f; 2019 | } 2020 | 2021 | .terminal .xterm-bg-color-227 { 2022 | background-color: #ffff5f; 2023 | } 2024 | 2025 | .terminal .xterm-color-228 { 2026 | color: #ffff87; 2027 | } 2028 | 2029 | .terminal .xterm-bg-color-228 { 2030 | background-color: #ffff87; 2031 | } 2032 | 2033 | .terminal .xterm-color-229 { 2034 | color: #ffffaf; 2035 | } 2036 | 2037 | .terminal .xterm-bg-color-229 { 2038 | background-color: #ffffaf; 2039 | } 2040 | 2041 | .terminal .xterm-color-230 { 2042 | color: #ffffd7; 2043 | } 2044 | 2045 | .terminal .xterm-bg-color-230 { 2046 | background-color: #ffffd7; 2047 | } 2048 | 2049 | .terminal .xterm-color-231 { 2050 | color: #ffffff; 2051 | } 2052 | 2053 | .terminal .xterm-bg-color-231 { 2054 | background-color: #ffffff; 2055 | } 2056 | 2057 | .terminal .xterm-color-232 { 2058 | color: #080808; 2059 | } 2060 | 2061 | .terminal .xterm-bg-color-232 { 2062 | background-color: #080808; 2063 | } 2064 | 2065 | .terminal .xterm-color-233 { 2066 | color: #121212; 2067 | } 2068 | 2069 | .terminal .xterm-bg-color-233 { 2070 | background-color: #121212; 2071 | } 2072 | 2073 | .terminal .xterm-color-234 { 2074 | color: #1c1c1c; 2075 | } 2076 | 2077 | .terminal .xterm-bg-color-234 { 2078 | background-color: #1c1c1c; 2079 | } 2080 | 2081 | .terminal .xterm-color-235 { 2082 | color: #262626; 2083 | } 2084 | 2085 | .terminal .xterm-bg-color-235 { 2086 | background-color: #262626; 2087 | } 2088 | 2089 | .terminal .xterm-color-236 { 2090 | color: #303030; 2091 | } 2092 | 2093 | .terminal .xterm-bg-color-236 { 2094 | background-color: #303030; 2095 | } 2096 | 2097 | .terminal .xterm-color-237 { 2098 | color: #3a3a3a; 2099 | } 2100 | 2101 | .terminal .xterm-bg-color-237 { 2102 | background-color: #3a3a3a; 2103 | } 2104 | 2105 | .terminal .xterm-color-238 { 2106 | color: #444444; 2107 | } 2108 | 2109 | .terminal .xterm-bg-color-238 { 2110 | background-color: #444444; 2111 | } 2112 | 2113 | .terminal .xterm-color-239 { 2114 | color: #4e4e4e; 2115 | } 2116 | 2117 | .terminal .xterm-bg-color-239 { 2118 | background-color: #4e4e4e; 2119 | } 2120 | 2121 | .terminal .xterm-color-240 { 2122 | color: #585858; 2123 | } 2124 | 2125 | .terminal .xterm-bg-color-240 { 2126 | background-color: #585858; 2127 | } 2128 | 2129 | .terminal .xterm-color-241 { 2130 | color: #626262; 2131 | } 2132 | 2133 | .terminal .xterm-bg-color-241 { 2134 | background-color: #626262; 2135 | } 2136 | 2137 | .terminal .xterm-color-242 { 2138 | color: #6c6c6c; 2139 | } 2140 | 2141 | .terminal .xterm-bg-color-242 { 2142 | background-color: #6c6c6c; 2143 | } 2144 | 2145 | .terminal .xterm-color-243 { 2146 | color: #767676; 2147 | } 2148 | 2149 | .terminal .xterm-bg-color-243 { 2150 | background-color: #767676; 2151 | } 2152 | 2153 | .terminal .xterm-color-244 { 2154 | color: #808080; 2155 | } 2156 | 2157 | .terminal .xterm-bg-color-244 { 2158 | background-color: #808080; 2159 | } 2160 | 2161 | .terminal .xterm-color-245 { 2162 | color: #8a8a8a; 2163 | } 2164 | 2165 | .terminal .xterm-bg-color-245 { 2166 | background-color: #8a8a8a; 2167 | } 2168 | 2169 | .terminal .xterm-color-246 { 2170 | color: #949494; 2171 | } 2172 | 2173 | .terminal .xterm-bg-color-246 { 2174 | background-color: #949494; 2175 | } 2176 | 2177 | .terminal .xterm-color-247 { 2178 | color: #9e9e9e; 2179 | } 2180 | 2181 | .terminal .xterm-bg-color-247 { 2182 | background-color: #9e9e9e; 2183 | } 2184 | 2185 | .terminal .xterm-color-248 { 2186 | color: #a8a8a8; 2187 | } 2188 | 2189 | .terminal .xterm-bg-color-248 { 2190 | background-color: #a8a8a8; 2191 | } 2192 | 2193 | .terminal .xterm-color-249 { 2194 | color: #b2b2b2; 2195 | } 2196 | 2197 | .terminal .xterm-bg-color-249 { 2198 | background-color: #b2b2b2; 2199 | } 2200 | 2201 | .terminal .xterm-color-250 { 2202 | color: #bcbcbc; 2203 | } 2204 | 2205 | .terminal .xterm-bg-color-250 { 2206 | background-color: #bcbcbc; 2207 | } 2208 | 2209 | .terminal .xterm-color-251 { 2210 | color: #c6c6c6; 2211 | } 2212 | 2213 | .terminal .xterm-bg-color-251 { 2214 | background-color: #c6c6c6; 2215 | } 2216 | 2217 | .terminal .xterm-color-252 { 2218 | color: #d0d0d0; 2219 | } 2220 | 2221 | .terminal .xterm-bg-color-252 { 2222 | background-color: #d0d0d0; 2223 | } 2224 | 2225 | .terminal .xterm-color-253 { 2226 | color: #dadada; 2227 | } 2228 | 2229 | .terminal .xterm-bg-color-253 { 2230 | background-color: #dadada; 2231 | } 2232 | 2233 | .terminal .xterm-color-254 { 2234 | color: #e4e4e4; 2235 | } 2236 | 2237 | .terminal .xterm-bg-color-254 { 2238 | background-color: #e4e4e4; 2239 | } 2240 | 2241 | .terminal .xterm-color-255 { 2242 | color: #eeeeee; 2243 | } 2244 | 2245 | .terminal .xterm-bg-color-255 { 2246 | background-color: #eeeeee; 2247 | } 2248 | -------------------------------------------------------------------------------- /public/js/addons/attach/attach.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Implements the attach method, that attaches the terminal to a WebSocket stream. 3 | * @module xterm/addons/attach/attach 4 | * @license MIT 5 | */ 6 | 7 | (function (attach) { 8 | if (typeof exports === 'object' && typeof module === 'object') { 9 | /* 10 | * CommonJS environment 11 | */ 12 | module.exports = attach(require('../../xterm')); 13 | } else if (typeof define == 'function') { 14 | /* 15 | * Require.js is available 16 | */ 17 | define(['../../xterm'], attach); 18 | } else { 19 | /* 20 | * Plain browser environment 21 | */ 22 | attach(window.Terminal); 23 | } 24 | })(function (Xterm) { 25 | 'use strict'; 26 | 27 | var exports = {}; 28 | 29 | /** 30 | * Attaches the given terminal to the given socket. 31 | * 32 | * @param {Xterm} term - The terminal to be attached to the given socket. 33 | * @param {WebSocket} socket - The socket to attach the current terminal. 34 | * @param {boolean} bidirectional - Whether the terminal should send data 35 | * to the socket as well. 36 | * @param {boolean} buffered - Whether the rendering of incoming data 37 | * should happen instantly or at a maximum 38 | * frequency of 1 rendering per 10ms. 39 | */ 40 | exports.attach = function (term, socket, bidirectional, buffered) { 41 | bidirectional = (typeof bidirectional == 'undefined') ? true : bidirectional; 42 | term.socket = socket; 43 | 44 | term._flushBuffer = function () { 45 | term.write(term._attachSocketBuffer); 46 | term._attachSocketBuffer = null; 47 | clearTimeout(term._attachSocketBufferTimer); 48 | term._attachSocketBufferTimer = null; 49 | }; 50 | 51 | term._pushToBuffer = function (data) { 52 | if (term._attachSocketBuffer) { 53 | term._attachSocketBuffer += data; 54 | } else { 55 | term._attachSocketBuffer = data; 56 | setTimeout(term._flushBuffer, 10); 57 | } 58 | }; 59 | 60 | term._getMessage = function (ev) { 61 | if (buffered) { 62 | term._pushToBuffer(ev.data); 63 | } else { 64 | term.write(ev.data); 65 | } 66 | }; 67 | 68 | term._sendData = function (data) { 69 | socket.send(data); 70 | }; 71 | 72 | socket.addEventListener('message', term._getMessage); 73 | 74 | if (bidirectional) { 75 | term.on('data', term._sendData); 76 | } 77 | 78 | socket.addEventListener('close', term.detach.bind(term, socket)); 79 | socket.addEventListener('error', term.detach.bind(term, socket)); 80 | }; 81 | 82 | /** 83 | * Detaches the given terminal from the given socket 84 | * 85 | * @param {Xterm} term - The terminal to be detached from the given socket. 86 | * @param {WebSocket} socket - The socket from which to detach the current 87 | * terminal. 88 | */ 89 | exports.detach = function (term, socket) { 90 | term.off('data', term._sendData); 91 | 92 | socket = (typeof socket == 'undefined') ? term.socket : socket; 93 | 94 | if (socket) { 95 | socket.removeEventListener('message', term._getMessage); 96 | } 97 | 98 | delete term.socket; 99 | }; 100 | 101 | /** 102 | * Attaches the current terminal to the given socket 103 | * 104 | * @param {WebSocket} socket - The socket to attach the current terminal. 105 | * @param {boolean} bidirectional - Whether the terminal should send data 106 | * to the socket as well. 107 | * @param {boolean} buffered - Whether the rendering of incoming data 108 | * should happen instantly or at a maximum 109 | * frequency of 1 rendering per 10ms. 110 | */ 111 | Xterm.prototype.attach = function (socket, bidirectional, buffered) { 112 | return exports.attach(this, socket, bidirectional, buffered); 113 | }; 114 | 115 | /** 116 | * Detaches the current terminal from the given socket. 117 | * 118 | * @param {WebSocket} socket - The socket from which to detach the current 119 | * terminal. 120 | */ 121 | Xterm.prototype.detach = function (socket) { 122 | return exports.detach(this, socket); 123 | }; 124 | 125 | return exports; 126 | }); 127 | -------------------------------------------------------------------------------- /public/js/addons/fit/fit.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Fit terminal columns and rows to the dimensions of its DOM element. 3 | * 4 | * ## Approach 5 | * - Rows: Truncate the division of the terminal parent element height by the terminal row height. 6 | * 7 | * - Columns: Truncate the division of the terminal parent element width by the terminal character 8 | * width (apply display: inline at the terminal row and truncate its width with the current 9 | * number of columns). 10 | * @module xterm/addons/fit/fit 11 | * @license MIT 12 | */ 13 | 14 | (function (fit) { 15 | if (typeof exports === 'object' && typeof module === 'object') { 16 | /* 17 | * CommonJS environment 18 | */ 19 | module.exports = fit(require('../../xterm')); 20 | } else if (typeof define == 'function') { 21 | /* 22 | * Require.js is available 23 | */ 24 | define(['../../xterm'], fit); 25 | } else { 26 | /* 27 | * Plain browser environment 28 | */ 29 | fit(window.Terminal); 30 | } 31 | })(function (Xterm) { 32 | var exports = {}; 33 | 34 | exports.proposeGeometry = function (term) { 35 | if (!term.element.parentElement) { 36 | return null; 37 | } 38 | var parentElementStyle = window.getComputedStyle(term.element.parentElement), 39 | parentElementHeight = parseInt(parentElementStyle.getPropertyValue('height')), 40 | parentElementWidth = Math.max(0, parseInt(parentElementStyle.getPropertyValue('width')) - 17), 41 | elementStyle = window.getComputedStyle(term.element), 42 | elementPaddingVer = parseInt(elementStyle.getPropertyValue('padding-top')) + parseInt(elementStyle.getPropertyValue('padding-bottom')), 43 | elementPaddingHor = parseInt(elementStyle.getPropertyValue('padding-right')) + parseInt(elementStyle.getPropertyValue('padding-left')), 44 | availableHeight = parentElementHeight - elementPaddingVer, 45 | availableWidth = parentElementWidth - elementPaddingHor, 46 | container = term.rowContainer, 47 | subjectRow = term.rowContainer.firstElementChild, 48 | contentBuffer = subjectRow.innerHTML, 49 | characterHeight, 50 | rows, 51 | characterWidth, 52 | cols, 53 | geometry; 54 | 55 | subjectRow.style.display = 'inline'; 56 | subjectRow.innerHTML = 'W'; // Common character for measuring width, although on monospace 57 | characterWidth = subjectRow.getBoundingClientRect().width; 58 | subjectRow.style.display = ''; // Revert style before calculating height, since they differ. 59 | characterHeight = subjectRow.getBoundingClientRect().height; 60 | subjectRow.innerHTML = contentBuffer; 61 | 62 | rows = parseInt(availableHeight / characterHeight); 63 | cols = parseInt(availableWidth / characterWidth); 64 | 65 | geometry = {cols: cols, rows: rows}; 66 | return geometry; 67 | }; 68 | 69 | exports.fit = function (term) { 70 | var geometry = exports.proposeGeometry(term); 71 | 72 | if (geometry) { 73 | term.resize(geometry.cols, geometry.rows); 74 | } 75 | }; 76 | 77 | Xterm.prototype.proposeGeometry = function () { 78 | return exports.proposeGeometry(this); 79 | }; 80 | 81 | Xterm.prototype.fit = function () { 82 | return exports.fit(this); 83 | }; 84 | 85 | return exports; 86 | }); 87 | -------------------------------------------------------------------------------- /public/js/addons/fullscreen/fullscreen.css: -------------------------------------------------------------------------------- 1 | .xterm.fullscreen { 2 | position: fixed; 3 | top: 0; 4 | bottom: 0; 5 | left: 0; 6 | right: 0; 7 | width: auto; 8 | height: auto; 9 | z-index: 255; 10 | } 11 | -------------------------------------------------------------------------------- /public/js/addons/fullscreen/fullscreen.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Fullscreen addon for xterm.js 3 | * @module xterm/addons/fullscreen/fullscreen 4 | * @license MIT 5 | */ 6 | (function (fullscreen) { 7 | if (typeof exports === 'object' && typeof module === 'object') { 8 | /* 9 | * CommonJS environment 10 | */ 11 | module.exports = fullscreen(require('../../xterm')); 12 | } else if (typeof define == 'function') { 13 | /* 14 | * Require.js is available 15 | */ 16 | define(['../../xterm'], fullscreen); 17 | } else { 18 | /* 19 | * Plain browser environment 20 | */ 21 | fullscreen(window.Terminal); 22 | } 23 | })(function (Xterm) { 24 | var exports = {}; 25 | 26 | /** 27 | * Toggle the given terminal's fullscreen mode. 28 | * @param {Xterm} term - The terminal to toggle full screen mode 29 | * @param {boolean} fullscreen - Toggle fullscreen on (true) or off (false) 30 | */ 31 | exports.toggleFullScreen = function (term, fullscreen) { 32 | var fn; 33 | 34 | if (typeof fullscreen == 'undefined') { 35 | fn = (term.element.classList.contains('fullscreen')) ? 'remove' : 'add'; 36 | } else if (!fullscreen) { 37 | fn = 'remove'; 38 | } else { 39 | fn = 'add'; 40 | } 41 | 42 | term.element.classList[fn]('fullscreen'); 43 | }; 44 | 45 | Xterm.prototype.toggleFullscreen = function (fullscreen) { 46 | exports.toggleFullScreen(this, fullscreen); 47 | }; 48 | 49 | return exports; 50 | }); 51 | -------------------------------------------------------------------------------- /public/js/addons/linkify/linkify.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Methods for turning URL subscrings in the terminal's content into links (`a` DOM elements). 3 | * @module xterm/addons/linkify/linkify 4 | * @license MIT 5 | */ 6 | 7 | (function (linkify) { 8 | if (typeof exports === 'object' && typeof module === 'object') { 9 | /* 10 | * CommonJS environment 11 | */ 12 | module.exports = linkify(require('../../xterm')); 13 | } else if (typeof define == 'function') { 14 | /* 15 | * Require.js is available 16 | */ 17 | define(['../../xterm'], linkify); 18 | } else { 19 | /* 20 | * Plain browser environment 21 | */ 22 | linkify(window.Terminal); 23 | } 24 | })(function (Xterm) { 25 | 'use strict'; 26 | 27 | var exports = {}, 28 | protocolClause = '(https?:\\/\\/)', 29 | domainCharacterSet = '[\\da-z\\.-]+', 30 | negatedDomainCharacterSet = '[^\\da-z\\.-]+', 31 | domainBodyClause = '(' + domainCharacterSet + ')', 32 | tldClause = '([a-z\\.]{2,6})', 33 | ipClause = '((\\d{1,3}\\.){3}\\d{1,3})', 34 | portClause = '(:\\d{1,5})', 35 | hostClause = '((' + domainBodyClause + '\\.' + tldClause + ')|' + ipClause + ')' + portClause + '?', 36 | pathClause = '(\\/[\\/\\w\\.-]*)*', 37 | negatedPathCharacterSet = '[^\\/\\w\\.-]+', 38 | bodyClause = hostClause + pathClause, 39 | start = '(?:^|' + negatedDomainCharacterSet + ')(', 40 | end = ')($|' + negatedPathCharacterSet + ')', 41 | lenientUrlClause = start + protocolClause + '?' + bodyClause + end, 42 | strictUrlClause = start + protocolClause + bodyClause + end, 43 | lenientUrlRegex = new RegExp(lenientUrlClause), 44 | strictUrlRegex = new RegExp(strictUrlClause); 45 | 46 | /** 47 | * Converts all valid URLs found in the given terminal line into 48 | * hyperlinks. The terminal line can be either the HTML element itself 49 | * or the index of the termina line in the children of the terminal 50 | * rows container. 51 | * 52 | * @param {Xterm} terminal - The terminal that owns the given line. 53 | * @param {number|HTMLDivElement} line - The terminal line that should get 54 | * "linkified". 55 | * @param {boolean} lenient - The regex type that will be used to identify links. If lenient is 56 | * false, the regex requires a protocol clause. Defaults to true. 57 | * @param {string} target - Sets target="" attribute with value provided to links. 58 | * Default doesn't set target attribute 59 | * @emits linkify 60 | * @emits linkify:line 61 | */ 62 | exports.linkifyTerminalLine = function (terminal, line, lenient, target) { 63 | if (typeof line == 'number') { 64 | line = terminal.rowContainer.children[line]; 65 | } else if (! (line instanceof HTMLDivElement)) { 66 | var message = 'The "line" argument should be either a number'; 67 | message += ' or an HTMLDivElement'; 68 | 69 | throw new TypeError(message); 70 | } 71 | 72 | if (typeof target === 'undefined') { 73 | target = ''; 74 | } else { 75 | target = 'target="' + target + '"'; 76 | } 77 | 78 | var buffer = document.createElement('span'), 79 | nodes = line.childNodes; 80 | 81 | for (var j=0; j' + url + '', 112 | newHTML = nodeHTML.replace(url, link); 113 | 114 | line.innerHTML = line.innerHTML.replace(nodeHTML, newHTML); 115 | } 116 | 117 | /** 118 | * This event gets emitted when conversion of all URL susbtrings 119 | * to HTML anchor elements (links) has finished, for a specific 120 | * line of the current Xterm instance. 121 | * 122 | * @event linkify:line 123 | */ 124 | terminal.emit('linkify:line', line); 125 | }; 126 | 127 | /** 128 | * Finds a link within a block of text. 129 | * 130 | * @param {string} text - The text to search . 131 | * @param {boolean} lenient - Whether to use the lenient search. 132 | * @return {string} A URL. 133 | */ 134 | exports.findLinkMatch = function (text, lenient) { 135 | var match = text.match(lenient ? lenientUrlRegex : strictUrlRegex); 136 | if (!match || match.length === 0) { 137 | return null; 138 | } 139 | return match[1]; 140 | } 141 | 142 | /** 143 | * Converts all valid URLs found in the terminal view into hyperlinks. 144 | * 145 | * @param {Xterm} terminal - The terminal that should get "linkified". 146 | * @param {boolean} lenient - The regex type that will be used to identify links. If lenient is 147 | * false, the regex requires a protocol clause. Defaults to true. 148 | * @param {string} target - Sets target="" attribute with value provided to links. 149 | * Default doesn't set target attribute 150 | * @emits linkify 151 | * @emits linkify:line 152 | */ 153 | exports.linkify = function (terminal, lenient, target) { 154 | var rows = terminal.rowContainer.children; 155 | 156 | lenient = (typeof lenient == "boolean") ? lenient : true; 157 | for (var i=0; i { 7 | for (let i of document.getElementById('tabs').children) 8 | if (i.id.startsWith('tab')) i.className = "tab"; 9 | for (let i of document.getElementById('window').children) i.hidden = true; 10 | for (let i of document.getElementById('tabs').children) { 11 | if (i.hasAttribute('data-name') && i.getAttribute('data-name').startsWith(tabname)) { 12 | i.className = "selectedtab"; 13 | document.getElementById(`win-${i.id.slice(4)}`).hidden = false; 14 | return true; 15 | } 16 | } 17 | return false; 18 | }, 19 | Init: (name, socketUrl) => { 20 | name = name + Math.floor((Math.random() * 100) + 1); 21 | 22 | 23 | let tabid = document.getElementById('tabs').childElementCount; 24 | while (true) { 25 | if (document.getElementById('tab-' + tabid)) { 26 | tabid++; 27 | } else break; 28 | } 29 | 30 | let socket = new WebSocket(socketUrl); 31 | Session.windows[name] = { 32 | name: name, 33 | socket: socket, 34 | }; 35 | 36 | document.getElementById('tabs').insertAdjacentHTML(`beforeend`, `Terminal `); 45 | document.getElementById('window').insertAdjacentHTML('beforeend', `
`); 46 | document.getElementById(`tab-${tabid}`).addEventListener("click", () => { 47 | if (document.getElementById(`tab-${tabid}`)) Session.selectTab(name); 48 | }); 49 | 50 | var term = new Terminal({ 51 | cursorBlink: true, 52 | fontSize: 3, 53 | }); 54 | term.open(document.getElementById('window').lastChild); 55 | term.fit(); 56 | 57 | var cols = term.cols, 58 | rows = term.rows; 59 | 60 | socket.onopen = function(e) { 61 | socket.send(JSON.stringify({ 62 | "screen": { 63 | "cols": cols, 64 | "rows": rows 65 | } 66 | })); 67 | 68 | term.on('data', function(data) { 69 | socket.send(JSON.stringify({ 70 | 'stdin': data 71 | })); 72 | }); 73 | 74 | socket.onmessage = function(event) { 75 | json_msg = JSON.parse(event.data); 76 | var type = json_msg.type; 77 | switch (type) { 78 | case 'terminal': 79 | term.write(json_msg.stdout); 80 | break; 81 | } 82 | }; 83 | socket.onclose = function() { 84 | term.destroy(); 85 | }; 86 | }; 87 | Session.selectTab(name); 88 | return true; 89 | } 90 | }; -------------------------------------------------------------------------------- /public/js/client.js: -------------------------------------------------------------------------------- 1 | var client = {}; 2 | client.run = function (options) { 3 | 4 | options = options || {}; 5 | 6 | 7 | var socket = new WebSocket(options.remote); 8 | var term = new Terminal({ 9 | cursorBlink: true, 10 | }); 11 | term.open(options.target); 12 | term.fit(); 13 | var cols = term.cols, 14 | rows = term.rows; 15 | 16 | socket.onopen = function(e) { 17 | socket.send(JSON.stringify({"screen":{"cols": cols, "rows": rows}})); 18 | 19 | term.on('data', function(data) { 20 | socket.send(JSON.stringify({'stdin':data})); 21 | }); 22 | 23 | socket.onmessage = function(event) { 24 | json_msg = JSON.parse(event.data); 25 | var type = json_msg.type; 26 | switch (type) { 27 | case 'loadavg': 28 | document.getElementById('uptime').innerHTML = "loadavg: " + json_msg.stdout; 29 | break; 30 | case 'terminal': 31 | term.write(json_msg.stdout); 32 | break; 33 | } 34 | }; 35 | socket.onclose = function() { 36 | //term.destroy(); 37 | }; 38 | }; 39 | return {'socket': socket, 'term': term}; 40 | }; 41 | -------------------------------------------------------------------------------- /public/x1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Prajithp/mojo-terminal/b5644def397c2ed0e9c86d7e6fa54fd697c5dc80/public/x1.png -------------------------------------------------------------------------------- /templates/index.html.ep: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | #!/bin/bash 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 |
21 |
22 | + 23 |
24 |
25 |
26 | 27 | 33 | 34 | 35 | --------------------------------------------------------------------------------