@ecmaos/kernel 0.1.0 → 0.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE CHANGED
@@ -1,21 +1,7 @@
1
- # MIT License
1
+ # Dual MIT/Apache-2.0 License
2
2
 
3
3
  Copyright (c) 2024-2025 Jay Mathis <code@mathis.network>
4
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:
5
+ Except as otherwise noted in individual files, this software is licensed under the MIT license (<http://opensource.org/licenses/MIT>), or the Apache License, Version 2.0 (<http://www.apache.org/licenses/LICENSE-2.0>).
11
6
 
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.
7
+ Downstream projects and end users may choose either license individually, or both together, at their discretion. The motivation for this dual-licensing is the additional software patent assurance provided by Apache 2.0.
package/README.md CHANGED
@@ -4,24 +4,40 @@
4
4
 
5
5
  [ecmaOS](https://ecmaos.sh) is a [browser-based operating system kernel](https://global.discourse-cdn.com/spiceworks/original/4X/8/7/b/87b7be8e7e2cd932affe5449dba69dc16e30d721.gif) and suite of applications written in TypeScript. It's the successor of [web3os](https://github.com/web3os-org/kernel).
6
6
 
7
- The goal is to create a kernel and supporting apps that tie together modern web technologies and utilities to form an "operating system" that can run on modern browsers, not just to create a "desktop experience". Its main use case is to provide a consistent environment for running web apps, but it has features that allow for more powerful custom scenarios. The kernel could also be used as a platform for custom applications, games, and more.
7
+ The goal is to create a kernel and supporting apps that tie together modern web technologies and utilities to form an "operating system" that can run on modern browsers, not just to create a "desktop experience". Its main use case is to provide a consistent environment for running web apps, but it has features that allow for more powerful custom scenarios. The kernel could also be repurposed as a platform for custom applications, games, and more.
8
+
9
+ > *"The computer can be used as a tool to liberate and protect people, rather than to control them."*
10
+ > — Hal Finney
8
11
 
9
12
  [![API Reference](https://img.shields.io/badge/API-Reference-success)](https://docs.ecmaos.sh)
10
13
  [![Version](https://img.shields.io/github/package-json/v/ecmaos/ecmaos?color=success)](https://ecmaos.sh)
11
14
  [![Site Status](https://img.shields.io/website?url=https%3A%2F%2Fecmaos.sh)](https://ecmaos.sh)
15
+ [![Created](https://img.shields.io/github/created-at/ecmaos/ecmaos?style=flat&label=created&color=success)](https://github.com/ecmaos/ecmaos/pulse)
12
16
  [![Last Commit](https://img.shields.io/github/last-commit/ecmaos/ecmaos.svg)](https://github.com/ecmaos/ecmaos/commit/main)
17
+
13
18
  [![Open issues](https://img.shields.io/github/issues/ecmaos/ecmaos.svg)](https://github.com/ecmaos/ecmaos/issues)
14
19
  [![Closed issues](https://img.shields.io/github/issues-closed/ecmaos/ecmaos.svg)](https://github.com/ecmaos/ecmaos/issues?q=is%3Aissue+is%3Aclosed)
20
+ [![Open PRs](https://img.shields.io/github/issues-pr-raw/ecmaos/ecmaos.svg?label=PRs)](https://github.com/ecmaos/ecmaos/pulls)
21
+ [![Closed PRs](https://img.shields.io/github/issues-pr-closed/ecmaos/ecmaos.svg?label=PRs)](https://github.com/ecmaos/ecmaos/pulls?q=is%3Apr+is%3Aclosed)
15
22
 
23
+ [![Star on GitHub](https://img.shields.io/github/stars/ecmaos/ecmaos?style=flat&logo=github&label=⭐️)](https://github.com/ecmaos/ecmaos/stargazers)
16
24
  [![Sponsors](https://img.shields.io/github/sponsors/mathiscode?color=red)](https://github.com/sponsors/mathiscode)
17
25
  [![Contributors](https://img.shields.io/github/contributors/ecmaos/ecmaos?color=yellow)](https://github.com/ecmaos/ecmaos/graphs/contributors)
18
- [![GitHub license](https://img.shields.io/badge/license-MIT-blue)](https://github.com/ecmaos/ecmaos/blob/main/LICENSE)
19
- [![PRs Welcome](https://img.shields.io/badge/PRs-welcome-blue.svg)](https://github.com/ecmaos/ecmaos/compare)
26
+ [![GitHub license](https://img.shields.io/badge/license-MIT+Apache2.0-blue)](https://github.com/ecmaos/ecmaos/blob/main/LICENSE)
27
+
28
+ [![Discord](https://img.shields.io/discord/1311804229127508081?label=discord&logo=discord&logoColor=white)](https://discord.gg/ZJYGkbVsCh)
29
+ [![Matrix](https://img.shields.io/matrix/ecmaos:matrix.org.svg?label=%23ecmaos%3Amatrix.org&logo=matrix&logoColor=white)](https://matrix.to/#/#ecmaos:matrix.org)
30
+ [![Bluesky](https://img.shields.io/badge/follow-on%20Bluesky-blue?logo=bluesky&logoColor=white)](https://ecmaos.bsky.social)
31
+ [![Reddit](https://img.shields.io/reddit/subreddit-subscribers/ecmaos?style=flat&logo=reddit&logoColor=white&label=r/ecmaos)](https://www.reddit.com/r/ecmaos)
32
+
33
+ > Made with ❤️ by [Jay Mathis](https://jaymath.is)
34
+ >
35
+ > [![Stars](https://img.shields.io/github/stars/mathiscode?style=flat&logo=github&label=⭐️)](https://github.com/mathiscode) [![Followers](https://img.shields.io/github/followers/mathiscode?style=flat&logo=github&label=follow)](https://github.com/mathiscode)
20
36
 
21
37
  ## Features
22
38
 
23
39
  - TypeScript, WebAssembly
24
- - Filesystem supporting multiple backends powered by [@zenfs/core](https://github.com/zen-fs/core)
40
+ - Filesystem supporting multiple backends powered by [zenfs](https://github.com/zen-fs/core)
25
41
  - Terminal interface powered by [xterm.js](https://xtermjs.org)
26
42
  - Pseudo-streams, allowing redirection and piping
27
43
  - Device framework with a common interface for working with hardware: WebBluetooth, WebSerial, WebHID, WebUSB, etc.
@@ -57,20 +73,31 @@ The goal is to create a kernel and supporting apps that tie together modern web
57
73
  - Storage (IndexedDB, localStorage, sessionStorage, etc.)
58
74
  - Terminal (xterm.js)
59
75
  - User Manager
76
+ - WASM Loader
60
77
  - Window Manager (WinBox)
61
78
  - Workers (Web Workers)
62
79
 
80
+ - `BIOS`
81
+ - The BIOS is a C++ module compiled to WebAssembly with [Emscripten](https://emscripten.org) providing performance-critical functionality
82
+ - The BIOS has its own filesystem, located at `/bios`
83
+ - The main idea is that data and custom code can be loaded into it from the OS for WASM-native performance, as well as providing various utilities
84
+ - Confusingly, the Kernel loads the BIOS - not the other way around
85
+
63
86
  - `Apps`
64
87
  - These are full applications that are developed to work with ecmaOS
88
+
65
89
  - `Core`
66
90
  - Core modules provide the system's essential functionality; this includes the kernel itself
91
+
67
92
  - `Commands`
68
93
  - Commands are small utilities that aren't quite full Apps, provided by the shell
94
+
69
95
  - `Devices`
70
96
  - Devices get loaded on boot, e.g. /dev/bluetooth, /dev/random, /dev/battery, etc.
71
97
  - A device can support being "run" by a user, e.g. `# /dev/battery status`
72
98
  - Devices may also be directly read/written, and will behave accordingly
73
99
  - An individual device module can provide multiple device drivers, e.g. `/dev/usb` provides `/dev/usb-mydevice-0001-0002`
100
+
74
101
  - `Utils`
75
102
  - Utilities used during development
76
103
 
@@ -142,6 +169,7 @@ The kernel is currently in active development. It is not considered stable and t
142
169
 
143
170
  Things to keep in mind:
144
171
 
172
+ - Things have changed a lot since the tests were written, so they need to be updated and fixed
145
173
  - The kernel is designed to be run in an environment with a DOM (i.e. a browser)
146
174
  - Many features are only available on Chromium-based browsers, and many more behind feature flags
147
175
  - Command interfaces won't match what you might be used to from a traditional Linux environment; not all commands and options are supported. Over time, Linuxish commands will be fleshed out and made to behave in a more familiar way.
@@ -181,3 +209,7 @@ turbo gen device # generate a new device template
181
209
  ```
182
210
 
183
211
  Also see [turbo.json](./turbo.json) and [CONTRIBUTING.md](./CONTRIBUTING.md) for more information.
212
+
213
+ ## Security Vulnerabilities
214
+
215
+ If you find a serious security vulnerability, please submit a new [Draft Security Advisory](https://github.com/ecmaos/ecmaos/security) or contact the project maintainer directly at [code@mathis.network](mailto:code@mathis.network).
Binary file
@@ -0,0 +1,23 @@
1
+ import { g as getDefaultExportFromCjs } from "./index-xODqy1dm.js";
2
+ var browser$2;
3
+ var hasRequiredBrowser;
4
+ function requireBrowser() {
5
+ if (hasRequiredBrowser) return browser$2;
6
+ hasRequiredBrowser = 1;
7
+ browser$2 = function() {
8
+ throw new Error(
9
+ "ws does not work in the browser. Browser clients must use the native WebSocket object"
10
+ );
11
+ };
12
+ return browser$2;
13
+ }
14
+ var browserExports = requireBrowser();
15
+ const browser = /* @__PURE__ */ getDefaultExportFromCjs(browserExports);
16
+ const browser$1 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
17
+ __proto__: null,
18
+ default: browser
19
+ }, Symbol.toStringTag, { value: "Module" }));
20
+ export {
21
+ browser$1 as b
22
+ };
23
+ //# sourceMappingURL=browser-DwS0anQc.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"browser-DwS0anQc.js","sources":["../../node_modules/.pnpm/ws@8.18.0/node_modules/ws/browser.js"],"sourcesContent":["'use strict';\n\nmodule.exports = function () {\n throw new Error(\n 'ws does not work in the browser. Browser clients must use the native ' +\n 'WebSocket object'\n );\n};\n"],"names":["browser"],"mappings":";;;;;;AAEAA,cAAiB,WAAY;AAC3B,UAAM,IAAI;AAAA,MACR;AAAA,IAED;AAAA,EACF;;;;;;;;;","x_google_ignoreList":[0]}
@@ -0,0 +1,428 @@
1
+ @import url('https://fonts.googleapis.com/css2?family=Fira+Code:wght@300..700&display=swap');:root {
2
+ --figlet-font: Poison;
3
+ --figlet-color: green;
4
+ }
5
+
6
+ .winbox.ecmaos-window {
7
+ background: linear-gradient(90deg, #243D25, #357C3C);
8
+ border-radius: 12px 12px 0 0;
9
+ }
10
+
11
+ .winbox.ecmaos-window:not(.min):not(.focus) {
12
+ background: #333;
13
+ }
14
+
15
+ @media (hover: hover) {
16
+ .winbox.ecmaos-globalThis.min:not(:hover) {
17
+ background: #333;
18
+ }
19
+ .winbox.ecmaos-window .wb-icon * {
20
+ opacity: 0.65;
21
+ }
22
+ .winbox.ecmaos-window .wb-icon *:hover {
23
+ opacity: 1;
24
+ }
25
+ }
26
+ .winbox.ecmaos-window .wb-title {
27
+ font-size: 13px;
28
+ text-transform: uppercase;
29
+ font-weight: 600;
30
+ }
31
+
32
+ .winbox.ecmaos-window .wb-body {
33
+ margin: 4px;
34
+ color: #fff;
35
+ background: #121212;
36
+ padding: 1rem;
37
+ }
38
+
39
+ .winbox.ecmaos-window .wb-body::-webkit-scrollbar {
40
+ width: 12px;
41
+ height: 12px;
42
+ }
43
+
44
+ .winbox.ecmaos-window .wb-body::-webkit-scrollbar-track {
45
+ background: transparent;
46
+ }
47
+
48
+ .winbox.ecmaos-window .wb-body::-webkit-scrollbar-thumb {
49
+ border-radius: 10px;
50
+ background: #263040;
51
+ }
52
+
53
+ .winbox.ecmaos-window .wb-body::-webkit-scrollbar-thumb:window-inactive {
54
+ background: #181f2a;
55
+ }
56
+
57
+ button {
58
+ background: #263040;
59
+ border: 1px solid #263040;
60
+ border-radius: 4px;
61
+ color: #fff;
62
+ cursor: pointer;
63
+ font-size: 13px;
64
+ font-weight: 600;
65
+ padding: 6px 12px;
66
+ width: 100%;
67
+ margin-top: 1rem;
68
+ }
69
+ button.btn-success {
70
+ background: #16a34a;
71
+ }
72
+ button.btn-cancel {
73
+ background: #8a1c1c;
74
+ }
75
+
76
+ button:hover {
77
+ background: #333;
78
+ border-color: #333;
79
+ }
80
+
81
+ button:active {
82
+ background: #263040;
83
+ }@-webkit-keyframes notyf-fadeinup{0%{opacity:0;transform:translateY(25%)}to{opacity:1;transform:translateY(0)}}@keyframes notyf-fadeinup{0%{opacity:0;transform:translateY(25%)}to{opacity:1;transform:translateY(0)}}@-webkit-keyframes notyf-fadeinleft{0%{opacity:0;transform:translateX(25%)}to{opacity:1;transform:translateX(0)}}@keyframes notyf-fadeinleft{0%{opacity:0;transform:translateX(25%)}to{opacity:1;transform:translateX(0)}}@-webkit-keyframes notyf-fadeoutright{0%{opacity:1;transform:translateX(0)}to{opacity:0;transform:translateX(25%)}}@keyframes notyf-fadeoutright{0%{opacity:1;transform:translateX(0)}to{opacity:0;transform:translateX(25%)}}@-webkit-keyframes notyf-fadeoutdown{0%{opacity:1;transform:translateY(0)}to{opacity:0;transform:translateY(25%)}}@keyframes notyf-fadeoutdown{0%{opacity:1;transform:translateY(0)}to{opacity:0;transform:translateY(25%)}}@-webkit-keyframes ripple{0%{transform:scale(0) translateY(-45%) translateX(13%)}to{transform:scale(1) translateY(-45%) translateX(13%)}}@keyframes ripple{0%{transform:scale(0) translateY(-45%) translateX(13%)}to{transform:scale(1) translateY(-45%) translateX(13%)}}.notyf{position:fixed;top:0;left:0;height:100%;width:100%;color:#fff;z-index:9999;display:flex;flex-direction:column;align-items:flex-end;justify-content:flex-end;pointer-events:none;box-sizing:border-box;padding:20px}.notyf__icon--error,.notyf__icon--success{height:21px;width:21px;background:#fff;border-radius:50%;display:block;margin:0 auto;position:relative}.notyf__icon--error:after,.notyf__icon--error:before{content:"";background:currentColor;display:block;position:absolute;width:3px;border-radius:3px;left:9px;height:12px;top:5px}.notyf__icon--error:after{transform:rotate(-45deg)}.notyf__icon--error:before{transform:rotate(45deg)}.notyf__icon--success:after,.notyf__icon--success:before{content:"";background:currentColor;display:block;position:absolute;width:3px;border-radius:3px}.notyf__icon--success:after{height:6px;transform:rotate(-45deg);top:9px;left:6px}.notyf__icon--success:before{height:11px;transform:rotate(45deg);top:5px;left:10px}.notyf__toast{display:block;overflow:hidden;pointer-events:auto;-webkit-animation:notyf-fadeinup .3s ease-in forwards;animation:notyf-fadeinup .3s ease-in forwards;box-shadow:0 3px 7px 0 rgba(0,0,0,.25);position:relative;padding:0 15px;border-radius:2px;max-width:300px;transform:translateY(25%);box-sizing:border-box;flex-shrink:0}.notyf__toast--disappear{transform:translateY(0);-webkit-animation:notyf-fadeoutdown .3s forwards;animation:notyf-fadeoutdown .3s forwards;-webkit-animation-delay:.25s;animation-delay:.25s}.notyf__toast--disappear .notyf__icon,.notyf__toast--disappear .notyf__message{-webkit-animation:notyf-fadeoutdown .3s forwards;animation:notyf-fadeoutdown .3s forwards;opacity:1;transform:translateY(0)}.notyf__toast--disappear .notyf__dismiss{-webkit-animation:notyf-fadeoutright .3s forwards;animation:notyf-fadeoutright .3s forwards;opacity:1;transform:translateX(0)}.notyf__toast--disappear .notyf__message{-webkit-animation-delay:.05s;animation-delay:.05s}.notyf__toast--upper{margin-bottom:20px}.notyf__toast--lower{margin-top:20px}.notyf__toast--dismissible .notyf__wrapper{padding-right:30px}.notyf__ripple{height:400px;width:400px;position:absolute;transform-origin:bottom right;right:0;top:0;border-radius:50%;transform:scale(0) translateY(-51%) translateX(13%);z-index:5;-webkit-animation:ripple .4s ease-out forwards;animation:ripple .4s ease-out forwards}.notyf__wrapper{display:flex;align-items:center;padding-top:17px;padding-bottom:17px;padding-right:15px;border-radius:3px;position:relative;z-index:10}.notyf__icon{width:22px;text-align:center;font-size:1.3em;opacity:0;-webkit-animation:notyf-fadeinup .3s forwards;animation:notyf-fadeinup .3s forwards;-webkit-animation-delay:.3s;animation-delay:.3s;margin-right:13px}.notyf__dismiss{position:absolute;top:0;right:0;height:100%;width:26px;margin-right:-15px;-webkit-animation:notyf-fadeinleft .3s forwards;animation:notyf-fadeinleft .3s forwards;-webkit-animation-delay:.35s;animation-delay:.35s;opacity:0}.notyf__dismiss-btn{background-color:rgba(0,0,0,.25);border:none;cursor:pointer;transition:opacity .2s ease,background-color .2s ease;outline:none;opacity:.35;height:100%;width:100%}.notyf__dismiss-btn:after,.notyf__dismiss-btn:before{content:"";background:#fff;height:12px;width:2px;border-radius:3px;position:absolute;left:calc(50% - 1px);top:calc(50% - 5px)}.notyf__dismiss-btn:after{transform:rotate(-45deg)}.notyf__dismiss-btn:before{transform:rotate(45deg)}.notyf__dismiss-btn:hover{opacity:.7;background-color:rgba(0,0,0,.15)}.notyf__dismiss-btn:active{opacity:.8}.notyf__message{vertical-align:middle;position:relative;opacity:0;-webkit-animation:notyf-fadeinup .3s forwards;animation:notyf-fadeinup .3s forwards;-webkit-animation-delay:.25s;animation-delay:.25s;line-height:1.5em}@media only screen and (max-width:480px){.notyf{padding:0}.notyf__ripple{height:600px;width:600px;-webkit-animation-duration:.5s;animation-duration:.5s}.notyf__toast{max-width:none;border-radius:0;box-shadow:0 -2px 7px 0 rgba(0,0,0,.13);width:100%}.notyf__dismiss{width:56px}}/**
84
+ * Copyright (c) 2014 The xterm.js authors. All rights reserved.
85
+ * Copyright (c) 2012-2013, Christopher Jeffrey (MIT License)
86
+ * https://github.com/chjj/term.js
87
+ * @license MIT
88
+ *
89
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
90
+ * of this software and associated documentation files (the "Software"), to deal
91
+ * in the Software without restriction, including without limitation the rights
92
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
93
+ * copies of the Software, and to permit persons to whom the Software is
94
+ * furnished to do so, subject to the following conditions:
95
+ *
96
+ * The above copyright notice and this permission notice shall be included in
97
+ * all copies or substantial portions of the Software.
98
+ *
99
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
100
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
101
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
102
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
103
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
104
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
105
+ * THE SOFTWARE.
106
+ *
107
+ * Originally forked from (with the author's permission):
108
+ * Fabrice Bellard's javascript vt100 for jslinux:
109
+ * http://bellard.org/jslinux/
110
+ * Copyright (c) 2011 Fabrice Bellard
111
+ * The original design remains. The terminal itself
112
+ * has been extended to include xterm CSI codes, among
113
+ * other features.
114
+ */
115
+
116
+ /**
117
+ * Default styles for xterm.js
118
+ */
119
+
120
+ .xterm {
121
+ cursor: text;
122
+ position: relative;
123
+ user-select: none;
124
+ -ms-user-select: none;
125
+ -webkit-user-select: none;
126
+ }
127
+
128
+ .xterm.focus,
129
+ .xterm:focus {
130
+ outline: none;
131
+ }
132
+
133
+ .xterm .xterm-helpers {
134
+ position: absolute;
135
+ top: 0;
136
+ /**
137
+ * The z-index of the helpers must be higher than the canvases in order for
138
+ * IMEs to appear on top.
139
+ */
140
+ z-index: 5;
141
+ }
142
+
143
+ .xterm .xterm-helper-textarea {
144
+ padding: 0;
145
+ border: 0;
146
+ margin: 0;
147
+ /* Move textarea out of the screen to the far left, so that the cursor is not visible */
148
+ position: absolute;
149
+ opacity: 0;
150
+ left: -9999em;
151
+ top: 0;
152
+ width: 0;
153
+ height: 0;
154
+ z-index: -5;
155
+ /** Prevent wrapping so the IME appears against the textarea at the correct position */
156
+ white-space: nowrap;
157
+ overflow: hidden;
158
+ resize: none;
159
+ }
160
+
161
+ .xterm .composition-view {
162
+ /* TODO: Composition position got messed up somewhere */
163
+ background: #000;
164
+ color: #FFF;
165
+ display: none;
166
+ position: absolute;
167
+ white-space: nowrap;
168
+ z-index: 1;
169
+ }
170
+
171
+ .xterm .composition-view.active {
172
+ display: block;
173
+ }
174
+
175
+ .xterm .xterm-viewport {
176
+ /* On OS X this is required in order for the scroll bar to appear fully opaque */
177
+ background-color: #000;
178
+ overflow-y: scroll;
179
+ cursor: default;
180
+ position: absolute;
181
+ right: 0;
182
+ left: 0;
183
+ top: 0;
184
+ bottom: 0;
185
+ }
186
+
187
+ .xterm .xterm-screen {
188
+ position: relative;
189
+ }
190
+
191
+ .xterm .xterm-screen canvas {
192
+ position: absolute;
193
+ left: 0;
194
+ top: 0;
195
+ }
196
+
197
+ .xterm .xterm-scroll-area {
198
+ visibility: hidden;
199
+ }
200
+
201
+ .xterm-char-measure-element {
202
+ display: inline-block;
203
+ visibility: hidden;
204
+ position: absolute;
205
+ top: 0;
206
+ left: -9999em;
207
+ line-height: normal;
208
+ }
209
+
210
+ .xterm.enable-mouse-events {
211
+ /* When mouse events are enabled (eg. tmux), revert to the standard pointer cursor */
212
+ cursor: default;
213
+ }
214
+
215
+ .xterm.xterm-cursor-pointer,
216
+ .xterm .xterm-cursor-pointer {
217
+ cursor: pointer;
218
+ }
219
+
220
+ .xterm.column-select.focus {
221
+ /* Column selection mode */
222
+ cursor: crosshair;
223
+ }
224
+
225
+ .xterm .xterm-accessibility:not(.debug),
226
+ .xterm .xterm-message {
227
+ position: absolute;
228
+ left: 0;
229
+ top: 0;
230
+ bottom: 0;
231
+ right: 0;
232
+ z-index: 10;
233
+ color: transparent;
234
+ pointer-events: none;
235
+ }
236
+
237
+ .xterm .xterm-accessibility-tree:not(.debug) *::selection {
238
+ color: transparent;
239
+ }
240
+
241
+ .xterm .xterm-accessibility-tree {
242
+ user-select: text;
243
+ white-space: pre;
244
+ }
245
+
246
+ .xterm .live-region {
247
+ position: absolute;
248
+ left: -9999px;
249
+ width: 1px;
250
+ height: 1px;
251
+ overflow: hidden;
252
+ }
253
+
254
+ .xterm-dim {
255
+ /* Dim should not apply to background, so the opacity of the foreground color is applied
256
+ * explicitly in the generated class and reset to 1 here */
257
+ opacity: 1 !important;
258
+ }
259
+
260
+ .xterm-underline-1 { text-decoration: underline; }
261
+ .xterm-underline-2 { text-decoration: double underline; }
262
+ .xterm-underline-3 { text-decoration: wavy underline; }
263
+ .xterm-underline-4 { text-decoration: dotted underline; }
264
+ .xterm-underline-5 { text-decoration: dashed underline; }
265
+
266
+ .xterm-overline {
267
+ text-decoration: overline;
268
+ }
269
+
270
+ .xterm-overline.xterm-underline-1 { text-decoration: overline underline; }
271
+ .xterm-overline.xterm-underline-2 { text-decoration: overline double underline; }
272
+ .xterm-overline.xterm-underline-3 { text-decoration: overline wavy underline; }
273
+ .xterm-overline.xterm-underline-4 { text-decoration: overline dotted underline; }
274
+ .xterm-overline.xterm-underline-5 { text-decoration: overline dashed underline; }
275
+
276
+ .xterm-strikethrough {
277
+ text-decoration: line-through;
278
+ }
279
+
280
+ .xterm-screen .xterm-decoration-container .xterm-decoration {
281
+ z-index: 6;
282
+ position: absolute;
283
+ }
284
+
285
+ .xterm-screen .xterm-decoration-container .xterm-decoration.xterm-decoration-top-layer {
286
+ z-index: 7;
287
+ }
288
+
289
+ .xterm-decoration-overview-ruler {
290
+ z-index: 8;
291
+ position: absolute;
292
+ top: 0;
293
+ right: 0;
294
+ pointer-events: none;
295
+ }
296
+
297
+ .xterm-decoration-top {
298
+ z-index: 2;
299
+ position: relative;
300
+ }
301
+ @keyframes wb-fade-in{0%{opacity:0}to{opacity:.85}}.winbox{position:fixed;left:0;top:0;background:#0050ff;box-shadow:0 14px 28px rgba(0,0,0,.25),0 10px 10px rgba(0,0,0,.22);transition:width .3s,height .3s,left .3s,top .3s;transition-timing-function:cubic-bezier(.3,1,.3,1);contain:layout size;text-align:left;touch-action:none}.wb-body,.wb-header{position:absolute;left:0}.wb-header{top:0;width:100%;height:35px;line-height:35px;color:#fff;overflow:hidden;z-index:1}.wb-body{top:35px;right:0;bottom:0;overflow:auto;-webkit-overflow-scrolling:touch;overflow-scrolling:touch;will-change:contents;background:#fff;margin-top:0!important;contain:strict;z-index:0}.wb-control *,.wb-icon{background-repeat:no-repeat}.wb-drag{height:100%;padding-left:10px;cursor:move}.wb-title{font-family:Arial,sans-serif;font-size:14px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.wb-icon{display:none;width:20px;height:100%;margin:-1px 8px 0-3px;float:left;background-size:100%;background-position:center}.wb-e,.wb-w{width:10px;top:0}.wb-n,.wb-s{left:0;height:10px;position:absolute}.wb-n{top:-5px;right:0;cursor:n-resize;z-index:2}.wb-e{position:absolute;right:-5px;bottom:0;cursor:w-resize;z-index:2}.wb-s{bottom:-5px;right:0;cursor:n-resize;z-index:2}.wb-nw,.wb-sw,.wb-w{left:-5px}.wb-w{position:absolute;bottom:0;cursor:w-resize;z-index:2}.wb-ne,.wb-nw,.wb-sw{width:15px;height:15px;z-index:2;position:absolute}.wb-nw{top:-5px;cursor:nw-resize}.wb-ne,.wb-sw{cursor:ne-resize}.wb-ne{top:-5px;right:-5px}.wb-se,.wb-sw{bottom:-5px}.wb-se{position:absolute;right:-5px;width:15px;height:15px;cursor:nw-resize;z-index:2}.wb-control{float:right;height:100%;max-width:100%;text-align:center}.wb-control *{display:inline-block;width:30px;height:100%;max-width:100%;background-position:center;cursor:pointer}.no-close .wb-close,.no-full .wb-full,.no-header .wb-header,.no-max .wb-max,.no-min .wb-min,.no-resize .wb-body~div,.wb-body .wb-hide,.wb-show,.winbox.hide,.winbox.min .wb-body>*,.winbox.min .wb-full,.winbox.min .wb-min,.winbox.modal .wb-full,.winbox.modal .wb-max,.winbox.modal .wb-min{display:none}.winbox.max .wb-drag,.winbox.min .wb-drag{cursor:default}.wb-min{background-image:url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAxNiAyIj48cGF0aCBmaWxsPSIjZmZmIiBkPSJNOCAwaDdhMSAxIDAgMCAxIDAgMkgxYTEgMSAwIDAgMSAwLTJoN3oiLz48L3N2Zz4=);background-size:14px auto;background-position:center calc(50% + 6px)}.wb-max{background-image:url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGZpbGw9IiNmZmYiIHZpZXdCb3g9IjAgMCA5NiA5NiI+PHBhdGggZD0iTTIwIDcxLjMxMUMxNS4zNCA2OS42NyAxMiA2NS4yMyAxMiA2MFYyMGMwLTYuNjMgNS4zNy0xMiAxMi0xMmg0MGM1LjIzIDAgOS42NyAzLjM0IDExLjMxMSA4SDI0Yy0yLjIxIDAtNCAxLjc5LTQgNHY1MS4zMTF6Ii8+PHBhdGggZD0iTTkyIDc2VjM2YzAtNi42My01LjM3LTEyLTEyLTEySDQwYy02LjYzIDAtMTIgNS4zNy0xMiAxMnY0MGMwIDYuNjMgNS4zNyAxMiAxMiAxMmg0MGM2LjYzIDAgMTItNS4zNyAxMi0xMnptLTUyIDRjLTIuMjEgMC00LTEuNzktNC00VjM2YzAtMi4yMSAxLjc5LTQgNC00aDQwYzIuMjEgMCA0IDEuNzkgNCA0djQwYzAgMi4yMS0xLjc5IDQtNCA0SDQweiIvPjwvc3ZnPg==);background-size:17px auto}.wb-close{background-image:url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9Ii0xIC0xIDE4IDE4Ij48cGF0aCBmaWxsPSIjZmZmIiBkPSJtMS42MTMuMjEuMDk0LjA4M0w4IDYuNTg1IDE0LjI5My4yOTNsLjA5NC0uMDgzYTEgMSAwIDAgMSAxLjQwMyAxLjQwM2wtLjA4My4wOTRMOS40MTUgOGw2LjI5MiA2LjI5M2ExIDEgMCAwIDEtMS4zMiAxLjQ5N2wtLjA5NC0uMDgzTDggOS40MTVsLTYuMjkzIDYuMjkyLS4wOTQuMDgzQTEgMSAwIDAgMSAuMjEgMTQuMzg3bC4wODMtLjA5NEw2LjU4NSA4IC4yOTMgMS43MDdBMSAxIDAgMCAxIDEuNjEzLjIxeiIvPjwvc3ZnPg==);background-size:15px auto;background-position:5px center}.wb-full{background-image:url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGZpbGw9Im5vbmUiIHN0cm9rZT0iI2ZmZiIgc3Ryb2tlLWxpbmVjYXA9InJvdW5kIiBzdHJva2Utd2lkdGg9IjIuNSIgdmlld0JveD0iMCAwIDI0IDI0Ij48cGF0aCBkPSJNOCAzSDVhMiAyIDAgMCAwLTIgMnYzbTE4IDBWNWEyIDIgMCAwIDAtMi0yaC0zbTAgMThoM2EyIDIgMCAwIDAgMi0ydi0zTTMgMTZ2M2EyIDIgMCAwIDAgMiAyaDMiLz48L3N2Zz4=);background-size:16px auto}.winbox.max .wb-body~div,.winbox.min .wb-body~div,.winbox.modal .wb-body~div,.winbox.modal .wb-drag,body.wb-lock iframe{pointer-events:none}.winbox.max{box-shadow:none}.winbox.max .wb-body{margin:0!important}.winbox iframe{position:absolute;width:100%;height:100%;border:0}body.wb-lock .winbox{will-change:left,top,width,height;transition:none}.winbox.modal:before{content:"";position:absolute;top:0;left:0;right:0;bottom:0;background:inherit;border-radius:inherit}.winbox.modal:after{content:"";position:absolute;top:-50vh;left:-50vw;right:-50vw;bottom:-50vh;background:#0d1117;animation:wb-fade-in .2s ease-out forwards;z-index:-1}.no-animation{transition:none}.no-shadow{box-shadow:none}.no-header .wb-body{top:0}.no-move:not(.min) .wb-title{pointer-events:none}.wb-body .wb-show{display:revert}
302
+
303
+ :root {
304
+ font-family: 'Fira Code', system-ui, Avenir, Helvetica, Arial, sans-serif;
305
+ line-height: 1.5;
306
+ font-weight: 400;
307
+ font-synthesis: none;
308
+ text-rendering: optimizeLegibility;
309
+ -webkit-font-smoothing: antialiased;
310
+ -moz-osx-font-smoothing: grayscale;
311
+
312
+ --color-background: black;
313
+ }
314
+
315
+ * {
316
+ touch-action: none;
317
+ }
318
+
319
+ html, body {
320
+ margin: 0;
321
+ padding: 0;
322
+ width: 100%;
323
+ height: 100%;
324
+ background-color: var(--color-background);
325
+ }
326
+
327
+ body {
328
+ overflow: hidden;
329
+ margin: 0;
330
+ position: relative;
331
+ }
332
+
333
+ body::before {
334
+ z-index: 1000;
335
+ pointer-events: none;
336
+ content: '';
337
+ position: absolute;
338
+ top: 0;
339
+ left: 0;
340
+ right: 0;
341
+ bottom: 0;
342
+ border: 2px solid transparent;
343
+ border-image: linear-gradient(
344
+ 45deg,
345
+ #ff0000,
346
+ #ff8000,
347
+ #ffff00,
348
+ #00ff00,
349
+ #00ffff,
350
+ #0000ff,
351
+ #8000ff,
352
+ #ff0080
353
+ ) 1;
354
+ filter: blur(3px);
355
+ animation: borderRotate 4s linear infinite, borderPulse 6s ease-in-out infinite;
356
+ }
357
+
358
+ @keyframes borderPulse {
359
+ 0% { transform: scale(1) }
360
+ 20% { transform: scale(1.003) }
361
+ 35% { transform: scale(1) }
362
+ 50% { transform: scale(1.006) }
363
+ 65% { transform: scale(1.002) }
364
+ 85% { transform: scale(1.004) }
365
+ 100% { transform: scale(1) }
366
+ }
367
+
368
+ @keyframes borderRotate {
369
+ from { border-image-source: linear-gradient(
370
+ 45deg,
371
+ #ff0000,
372
+ #ff8000,
373
+ #ffff00,
374
+ #00ff00,
375
+ #00ffff,
376
+ #0000ff,
377
+ #8000ff,
378
+ #ff0080
379
+ ) }
380
+ to { border-image-source: linear-gradient(
381
+ 405deg,
382
+ #ff0000,
383
+ #ff8000,
384
+ #ffff00,
385
+ #00ff00,
386
+ #00ffff,
387
+ #0000ff,
388
+ #8000ff,
389
+ #ff0080
390
+ ) }
391
+ }
392
+
393
+ #terminal {
394
+ width: 100%;
395
+ height: 100%;
396
+ overflow: hidden;
397
+ padding-inline: 5px;
398
+ }
399
+
400
+ .xterm-viewport {
401
+ overflow-y: auto !important;
402
+ }
403
+
404
+ .xterm-viewport::-webkit-scrollbar-track
405
+ {
406
+ -webkit-box-shadow: inset 0 0 6px rgba(0, 0, 0, 0.3);
407
+ box-shadow: inset 0 0 6px rgba(0, 0, 0, 0.3);
408
+ border-radius: 10px;
409
+ background-color: transparent;
410
+ }
411
+
412
+ .xterm-viewport::-webkit-scrollbar
413
+ {
414
+ width: 12px;
415
+ background-color: transparent;
416
+ }
417
+
418
+ .xterm-viewport::-webkit-scrollbar-thumb
419
+ {
420
+ border-radius: 10px;
421
+ -webkit-box-shadow: inset 0 0 6px rgba(0, 0, 0, 0.3);
422
+ box-shadow: inset 0 0 6px rgba(0, 0, 0, 0.3);
423
+ background-color: rgb(14, 105, 14);
424
+ }
425
+
426
+ .xterm-viewport::-webkit-scrollbar-thumb:hover {
427
+ background-color: rgb(14, 105, 14);
428
+ }