Luis-Filipe commited on
Commit
427ba09
·
verified ·
1 Parent(s): 249065b

when it reaches the end of the bottom of the screen moves everything written up one line to be able to write commands - Initial Deployment

Browse files
Files changed (2) hide show
  1. README.md +6 -4
  2. index.html +340 -19
README.md CHANGED
@@ -1,10 +1,12 @@
1
  ---
2
- title: Bbc Computer Frontend
3
- emoji: 🌍
4
- colorFrom: pink
5
  colorTo: yellow
6
  sdk: static
7
  pinned: false
 
 
8
  ---
9
 
10
- Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
1
  ---
2
+ title: bbc-computer-frontend
3
+ emoji: 🐳
4
+ colorFrom: gray
5
  colorTo: yellow
6
  sdk: static
7
  pinned: false
8
+ tags:
9
+ - deepsite
10
  ---
11
 
12
+ Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
index.html CHANGED
@@ -1,19 +1,340 @@
1
- <!doctype html>
2
- <html>
3
- <head>
4
- <meta charset="utf-8" />
5
- <meta name="viewport" content="width=device-width" />
6
- <title>My static Space</title>
7
- <link rel="stylesheet" href="style.css" />
8
- </head>
9
- <body>
10
- <div class="card">
11
- <h1>Welcome to your static Space!</h1>
12
- <p>You can modify this app directly by editing <i>index.html</i> in the Files and versions tab.</p>
13
- <p>
14
- Also don't forget to check the
15
- <a href="https://huggingface.co/docs/hub/spaces" target="_blank">Spaces documentation</a>.
16
- </p>
17
- </div>
18
- </body>
19
- </html>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>Acorn BBC BASIC Console</title>
7
+ <script src="https://cdn.tailwindcss.com"></script>
8
+ <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
9
+ <style>
10
+ @font-face {
11
+ font-family: 'BBC Micro';
12
+ src: url('https://style.bbc.com/fonts/bbc-micro/bbc-micro-regular.woff2') format('woff2');
13
+ }
14
+
15
+ .terminal {
16
+ font-family: 'Courier New', monospace;
17
+ line-height: 1.2;
18
+ }
19
+
20
+ .cursor-blink {
21
+ animation: blink 1s step-end infinite;
22
+ }
23
+
24
+ @keyframes blink {
25
+ from, to { opacity: 1; }
26
+ 50% { opacity: 0; }
27
+ }
28
+
29
+ .scanlines {
30
+ position: relative;
31
+ }
32
+
33
+ .scanlines::before {
34
+ content: "";
35
+ position: absolute;
36
+ top: 0;
37
+ left: 0;
38
+ right: 0;
39
+ bottom: 0;
40
+ background: linear-gradient(
41
+ rgba(18, 16, 16, 0) 50%,
42
+ rgba(0, 0, 0, 0.25) 50%
43
+ );
44
+ background-size: 100% 4px;
45
+ pointer-events: none;
46
+ z-index: 10;
47
+ }
48
+ </style>
49
+ </head>
50
+ <body class="bg-gray-900 min-h-screen flex items-center justify-center p-4">
51
+ <div class="w-full max-w-4xl">
52
+ <div class="bg-gray-800 rounded-lg overflow-hidden shadow-2xl">
53
+ <!-- Console Header -->
54
+ <div class="bg-gray-700 px-4 py-3 flex items-center justify-between">
55
+ <div class="flex items-center space-x-2">
56
+ <div class="w-3 h-3 rounded-full bg-red-500"></div>
57
+ <div class="w-3 h-3 rounded-full bg-yellow-500"></div>
58
+ <div class="w-3 h-3 rounded-full bg-green-500"></div>
59
+ </div>
60
+ <div class="text-gray-300 font-bold text-sm">Acorn BBC BASIC</div>
61
+ <div class="text-gray-400 text-xs">Model B</div>
62
+ </div>
63
+
64
+ <!-- Terminal Screen -->
65
+ <div class="scanlines bg-black text-green-400 terminal p-4 h-[32rem] overflow-y-auto" id="terminal">
66
+ <div class="mb-2">BBC Computer 32K</div>
67
+ <div class="mb-2">Acorn MOS</div>
68
+ <div class="mb-4">BASIC</div>
69
+ <div>> <span id="command-line"></span><span class="cursor-blink bg-green-400 w-2 h-5 inline-block align-middle" id="cursor"></span></div>
70
+ <div id="output" class="space-y-1"></div>
71
+ </div>
72
+
73
+ </div>
74
+
75
+ <!-- Status Bar -->
76
+ <div class="text-gray-400 text-xs mt-2 flex justify-between">
77
+ <div>READY</div>
78
+ <div>MODE 7</div>
79
+ <div>32K</div>
80
+ </div>
81
+ </div>
82
+
83
+ <script>
84
+ document.addEventListener('DOMContentLoaded', function() {
85
+ const commandLine = document.getElementById('command-line');
86
+ const output = document.getElementById('output');
87
+ const cursor = document.getElementById('cursor');
88
+ const keys = document.querySelectorAll('.key');
89
+
90
+ let currentCommand = '';
91
+ let commandHistory = [];
92
+ let historyIndex = -1;
93
+
94
+ // Focus the terminal for keyboard input
95
+ document.getElementById('terminal').focus();
96
+
97
+ // Handle keyboard input
98
+ document.addEventListener('keydown', function(e) {
99
+ e.preventDefault();
100
+
101
+ if (e.key === 'Enter') {
102
+ handleKeyPress('RETURN');
103
+ } else if (e.key === 'Backspace') {
104
+ handleKeyPress('DELETE');
105
+ } else if (e.key === 'ArrowUp') {
106
+ handleKeyPress('UP');
107
+ } else if (e.key === 'ArrowDown') {
108
+ handleKeyPress('DOWN');
109
+ } else if (e.key === 'Escape') {
110
+ handleKeyPress('ESC');
111
+ } else if (e.key === ' ') {
112
+ handleKeyPress('SPACE');
113
+ } else if (e.key.length === 1 && /[a-zA-ZÀ-ÖØ-öø-ÿ0-9\;\,\.\/\'\?\!\@\#\$\%\&\*\(\)\-\_\+\{\}\[\]\:\\\|\<\>\=]/.test(e.key)) {
114
+ // Block specific characters
115
+ if (!['~', '^', '`'].includes(e.key)) {
116
+ handleKeyPress(e.key.toUpperCase());
117
+ }
118
+ }
119
+ });
120
+
121
+ function handleKeyPress(key) {
122
+ switch(key) {
123
+ case 'RETURN':
124
+ executeCommand();
125
+ break;
126
+ case 'DELETE':
127
+ if (currentCommand.length > 0) {
128
+ currentCommand = currentCommand.slice(0, -1);
129
+ updateCommandLine();
130
+ }
131
+ break;
132
+ case 'UP':
133
+ if (commandHistory.length > 0 && historyIndex < commandHistory.length - 1) {
134
+ historyIndex++;
135
+ currentCommand = commandHistory[commandHistory.length - 1 - historyIndex];
136
+ updateCommandLine();
137
+ }
138
+ break;
139
+ case 'DOWN':
140
+ if (historyIndex > 0) {
141
+ historyIndex--;
142
+ currentCommand = commandHistory[commandHistory.length - 1 - historyIndex];
143
+ updateCommandLine();
144
+ } else if (historyIndex === 0) {
145
+ historyIndex--;
146
+ currentCommand = '';
147
+ updateCommandLine();
148
+ }
149
+ break;
150
+ case 'ESC':
151
+ currentCommand = '';
152
+ updateCommandLine();
153
+ break;
154
+ case 'SPACE':
155
+ currentCommand += ' ';
156
+ updateCommandLine();
157
+ break;
158
+ default:
159
+ if (key.length === 1) {
160
+ currentCommand += key;
161
+ updateCommandLine();
162
+ }
163
+ }
164
+ }
165
+
166
+ function updateCommandLine() {
167
+ commandLine.textContent = currentCommand;
168
+ }
169
+
170
+ function executeCommand() {
171
+ // Add to history
172
+ if (currentCommand.trim() !== '') {
173
+ commandHistory.push(currentCommand);
174
+ historyIndex = -1;
175
+ }
176
+
177
+ // Check if we need to scroll up (remove oldest line)
178
+ const terminal = document.getElementById('terminal');
179
+ if (terminal.scrollHeight > terminal.clientHeight) {
180
+ // Remove the first child that's not the initial text blocks
181
+ const initialBlocks = 4; // Number of initial text blocks (BBC Computer 32K, Acorn MOS, BASIC, prompt)
182
+ if (output.children.length > 0) {
183
+ output.removeChild(output.children[0]);
184
+ }
185
+ }
186
+
187
+ // Display command
188
+ const commandDiv = document.createElement('div');10
189
+ commandDiv.textContent = '> ' + currentCommand;
190
+ output.appendChild(commandDiv);
191
+
192
+ // Process command
193
+ const resultDiv = document.createElement('div');
194
+
195
+ try {
196
+ const result = processBasicCommand(currentCommand);
197
+ resultDiv.textContent = result;
198
+ } catch (e) {
199
+ resultDiv.textContent = e.message;
200
+ resultDiv.className = 'text-red-400';
201
+ }
202
+
203
+ output.appendChild(resultDiv);
204
+
205
+ // Reset command line
206
+ currentCommand = '';
207
+ updateCommandLine();
208
+
209
+ // Scroll to bottom
210
+ terminal.scrollTop = terminal.scrollHeight;
211
+ }
212
+
213
+ let programLines = {};
214
+ let variables = { A: 0, B: 0, C: 0 };
215
+
216
+ function processBasicCommand(command) {
217
+ const cmd = command.trim();
218
+
219
+ if (cmd === '') {
220
+ return '';
221
+ } else if (cmd.toUpperCase() === 'HELP') {
222
+ return 'BBC BASIC Commands: PRINT, LIST, RUN, NEW, CLS, HELP\nDirect commands: GOTO, REM, INPUT, LET, IF...THEN\n= ASCII decimal: 61 Unicode (hexadecimal): U+003D HTML entity: &#61; ou =';
223
+ } else if (cmd.toUpperCase() === 'CLS') {
224
+ output.innerHTML = '';
225
+ return '';
226
+ } else if (cmd.toUpperCase() === 'LIST') {
227
+ if (Object.keys(programLines).length === 0) return 'No program';
228
+ return Object.keys(programLines).sort((a,b) => a-b).map(n => n + ' ' + programLines[n]).join('\n');
229
+ } else if (cmd.toUpperCase() === 'RUN') {
230
+ return runProgram();
231
+ } else if (cmd.toUpperCase() === 'NEW') {
232
+ programLines = {};
233
+ output.innerHTML = '';
234
+ return 'Program cleared';
235
+ } else if (/^\d+ /.test(cmd)) {
236
+ // Program line entry
237
+ const spacePos = cmd.indexOf(' ');
238
+ const lineNum = cmd.substring(0, spacePos);
239
+ const lineContent = cmd.substring(spacePos + 1);
240
+
241
+ if (lineContent.trim().toUpperCase() === '') {
242
+ // Delete line if empty
243
+ delete programLines[lineNum];
244
+ return '';
245
+ } else {
246
+ programLines[lineNum] = lineContent;
247
+ return '';
248
+ }
249
+ } else if (cmd.toUpperCase().startsWith('LET ') || cmd.includes('=')) {
250
+ // Handle LET command or direct assignment (e.g. LET C=A+B or C=A+B)
251
+ let assignment = cmd;
252
+ if (cmd.toUpperCase().startsWith('LET ')) {
253
+ assignment = cmd.substring(4).trim();
254
+ }
255
+
256
+ const parts = assignment.split('=');
257
+ if (parts.length === 2) {
258
+ const varName = parts[0].trim();
259
+ const expr = parts[1].trim();
260
+
261
+ if (['A', 'B', 'C'].includes(varName)) {
262
+ variables[varName] = evaluateExpression(expr);
263
+ return '';
264
+ }
265
+ }
266
+ throw new Error('Bad assignment');
267
+ } else if (cmd.toUpperCase().startsWith('PRINT ')) {
268
+ // Immediate PRINT
269
+ const printExpr = cmd.substring(6);
270
+ // Handle printing variables or expressions directly
271
+ if (['A', 'B', 'C'].includes(printExpr.trim())) {
272
+ return variables[printExpr.trim()].toString();
273
+ }
274
+ return evaluateExpression(printExpr);
275
+ } else {
276
+ throw new Error('Syntax error');
277
+ }
278
+ }
279
+
280
+ function runProgram() {
281
+ if (Object.keys(programLines).length === 0) return 'No program';
282
+
283
+ const lines = Object.keys(programLines).sort((a,b) => a-b);
284
+ let outputText = '';
285
+
286
+ for (const lineNum of lines) {
287
+ const line = programLines[lineNum];
288
+
289
+ if (line.toUpperCase().startsWith('PRINT ')) {
290
+ outputText += evaluateExpression(line.substring(6)) + '\n';
291
+ } else if (line.toUpperCase().startsWith('LET ') || line.includes('=')) {
292
+ // Process assignments in program lines
293
+ let assignment = line;
294
+ if (line.toUpperCase().startsWith('LET ')) {
295
+ assignment = line.substring(4).trim();
296
+ }
297
+
298
+ const parts = assignment.split('=');
299
+ if (parts.length === 2) {
300
+ const varName = parts[0].trim();
301
+ const expr = parts[1].trim();
302
+
303
+ if (['A', 'B', 'C'].includes(varName)) {
304
+ variables[varName] = evaluateExpression(expr);
305
+ }
306
+ }
307
+ }
308
+ }
309
+
310
+ return outputText || '(Program run with no output)';
311
+ }
312
+
313
+ function evaluateExpression(expr) {
314
+ // Simple expression evaluator - would need expansion for full BASIC
315
+ try {
316
+ // Handle strings
317
+ if (expr.startsWith('"') && expr.endsWith('"')) {
318
+ return expr.substring(1, expr.length - 1);
319
+ }
320
+ // Handle variables in expressions
321
+ const varNames = ['A', 'B', 'C'];
322
+ let processedExpr = expr;
323
+ varNames.forEach(v => {
324
+ processedExpr = processedExpr.replace(new RegExp(v, 'g'), variables[v]);
325
+ });
326
+ // Handle simple arithmetic
327
+ return eval(processedExpr.replace(/MOD/gi, '%').replace(/DIV/gi, '/'));
328
+ } catch (e) {
329
+ return expr; // Return as-is if we can't evaluate
330
+ }
331
+ }
332
+
333
+ // Simulate cursor blink
334
+ setInterval(() => {
335
+ cursor.style.opacity = cursor.style.opacity === '0' ? '1' : '0';
336
+ }, 500);
337
+ });
338
+ </script>
339
+ <p style="border-radius: 8px; text-align: center; font-size: 12px; color: #fff; margin-top: 16px;position: fixed; left: 8px; bottom: 8px; z-index: 10; background: rgba(0, 0, 0, 0.8); padding: 4px 8px;">Made with <img src="https://enzostvs-deepsite.hf.space/logo.svg" alt="DeepSite Logo" style="width: 16px; height: 16px; vertical-align: middle;display:inline-block;margin-right:3px;filter:brightness(0) invert(1);"><a href="https://enzostvs-deepsite.hf.space" style="color: #fff;text-decoration: underline;" target="_blank" >DeepSite</a> - 🧬 <a href="https://enzostvs-deepsite.hf.space?remix=Luis-Filipe/bbc-computer-frontend" style="color: #fff;text-decoration: underline;" target="_blank" >Remix</a></p></body>
340
+ </html>