XXXMARK commited on
Commit
4825688
·
verified ·
1 Parent(s): 1643134

Upload folder using huggingface_hub

Browse files
Files changed (1) hide show
  1. index.html +633 -19
index.html CHANGED
@@ -1,19 +1,633 @@
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>CodeFlow Studio - Live Editor</title>
7
+ <script src="https://cdn.tailwindcss.com"></script>
8
+ <link href="https://fonts.googleapis.com/css2?family=Fira+Code:wght@300;400;500;600&family=Inter:wght@300;400;600;700&display=swap" rel="stylesheet">
9
+ <style>
10
+ /* Custom Scrollbar */
11
+ ::-webkit-scrollbar {
12
+ width: 8px;
13
+ height: 8px;
14
+ }
15
+ ::-webkit-scrollbar-track {
16
+ background: #1e1e1e;
17
+ }
18
+ ::-webkit-scrollbar-thumb {
19
+ background: #4b5563;
20
+ border-radius: 4px;
21
+ }
22
+ ::-webkit-scrollbar-thumb:hover {
23
+ background: #6b7280;
24
+ }
25
+
26
+ /* Editor Styles */
27
+ .editor-container {
28
+ position: relative;
29
+ height: 100%;
30
+ width: 100%;
31
+ overflow: hidden;
32
+ font-family: 'Fira Code', monospace;
33
+ }
34
+
35
+ .line-numbers {
36
+ position: absolute;
37
+ left: 0;
38
+ top: 0;
39
+ bottom: 0;
40
+ width: 3rem;
41
+ background-color: #1e1e1e;
42
+ color: #6b7280;
43
+ text-align: right;
44
+ padding: 1rem 0.5rem;
45
+ font-size: 0.875rem;
46
+ line-height: 1.5rem;
47
+ user-select: none;
48
+ border-right: 1px solid #374151;
49
+ z-index: 10;
50
+ }
51
+
52
+ textarea.code-input {
53
+ position: absolute;
54
+ left: 3rem;
55
+ top: 0;
56
+ width: calc(100% - 3rem);
57
+ height: 100%;
58
+ background: transparent;
59
+ color: #e5e7eb;
60
+ border: none;
61
+ resize: none;
62
+ outline: none;
63
+ padding: 1rem;
64
+ font-size: 0.875rem;
65
+ line-height: 1.5rem;
66
+ white-space: pre;
67
+ overflow: auto;
68
+ z-index: 20;
69
+ caret-color: #60a5fa;
70
+ }
71
+
72
+ /* Syntax Highlighting Layer (Visual Only) */
73
+ pre.code-highlight {
74
+ position: absolute;
75
+ left: 3rem;
76
+ top: 0;
77
+ width: calc(100% - 3rem);
78
+ height: 100%;
79
+ margin: 0;
80
+ padding: 1rem;
81
+ font-size: 0.875rem;
82
+ line-height: 1.5rem;
83
+ pointer-events: none;
84
+ z-index: 15;
85
+ overflow: hidden;
86
+ white-space: pre;
87
+ }
88
+
89
+ /* Glassmorphism & Utilities */
90
+ .glass-panel {
91
+ background: rgba(30, 41, 59, 0.7);
92
+ backdrop-filter: blur(12px);
93
+ -webkit-backdrop-filter: blur(12px);
94
+ border: 1px solid rgba(255, 255, 255, 0.1);
95
+ }
96
+
97
+ .animate-fade-in {
98
+ animation: fadeIn 0.3s ease-out forwards;
99
+ }
100
+
101
+ @keyframes fadeIn {
102
+ from { opacity: 0; transform: translateY(10px); }
103
+ to { opacity: 1; transform: translateY(0); }
104
+ }
105
+
106
+ /* Range Slider Styling */
107
+ input[type=range] {
108
+ -webkit-appearance: none;
109
+ background: transparent;
110
+ }
111
+ input[type=range]::-webkit-slider-thumb {
112
+ -webkit-appearance: none;
113
+ height: 16px;
114
+ width: 16px;
115
+ border-radius: 50%;
116
+ background: #60a5fa;
117
+ cursor: pointer;
118
+ margin-top: -6px;
119
+ }
120
+ input[type=range]::-webkit-slider-runnable-track {
121
+ width: 100%;
122
+ height: 4px;
123
+ cursor: pointer;
124
+ background: #4b5563;
125
+ border-radius: 2px;
126
+ }
127
+ </style>
128
+ </head>
129
+ <body class="bg-gray-900 text-gray-100 h-screen w-screen overflow-hidden flex flex-col font-sans selection:bg-blue-500 selection:text-white">
130
+
131
+ <!-- Header -->
132
+ <header class="h-14 bg-gray-800 border-b border-gray-700 flex items-center justify-between px-4 shrink-0 z-30 shadow-lg">
133
+ <div class="flex items-center gap-3">
134
+ <div class="w-8 h-8 bg-gradient-to-br from-blue-500 to-purple-600 rounded-lg flex items-center justify-center shadow-blue-500/20 shadow-lg">
135
+ <svg class="w-5 h-5 text-white" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M10 20l4-16m4 4l4 4-4 4M6 16l-4-4 4-4"></path></svg>
136
+ </div>
137
+ <h1 class="font-bold text-lg tracking-tight">Code<span class="text-blue-400">Flow</span></h1>
138
+ <span class="text-xs bg-gray-700 px-2 py-0.5 rounded text-gray-400 border border-gray-600">v2.0</span>
139
+ </div>
140
+
141
+ <div class="flex items-center gap-4">
142
+ <!-- Built with Anycoder Link -->
143
+ <a href="https://huggingface.co/spaces/akhaliq/anycoder" target="_blank" class="hidden md:flex items-center gap-2 text-xs font-medium text-gray-400 hover:text-blue-400 transition-colors px-3 py-1.5 rounded-full bg-gray-800 border border-gray-700 hover:border-blue-500/50 group">
144
+ <span class="w-2 h-2 rounded-full bg-green-500 animate-pulse"></span>
145
+ Built with anycoder
146
+ </a>
147
+
148
+ <button id="settingsBtn" class="p-2 text-gray-400 hover:text-white hover:bg-gray-700 rounded-lg transition-all duration-200 group relative">
149
+ <svg class="w-5 h-5 group-hover:rotate-90 transition-transform duration-500" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M10.325 4.317c.426-1.756 2.924-1.756 3.35 0a1.724 1.724 0 002.573 1.066c1.543-.94 3.31.826 2.37 2.37a1.724 1.724 0 001.065 2.572c1.756.426 1.756 2.924 0 3.35a1.724 1.724 0 00-1.066 2.573c.94 1.543-.826 3.31-2.37 2.37a1.724 1.724 0 00-2.572 1.065c-.426 1.756-2.924 1.756-3.35 0a1.724 1.724 0 00-2.573-1.066c-1.543.94-3.31-.826-2.37-2.37a1.724 1.724 0 00-1.065-2.572c-1.756-.426-1.756-2.924 0-3.35a1.724 1.724 0 001.066-2.573c-.94-1.543.826-3.31 2.37-2.37.996.608 2.296.07 2.572-1.065z"></path><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 12a3 3 0 11-6 0 3 3 0 016 0z"></path></svg>
150
+ </button>
151
+ </div>
152
+ </header>
153
+
154
+ <!-- Main Workspace -->
155
+ <main class="flex-1 flex overflow-hidden relative">
156
+
157
+ <!-- Left Panel: Input -->
158
+ <section class="flex-1 flex flex-col min-w-[300px] border-r border-gray-700 bg-[#1e1e1e] relative group">
159
+ <!-- Toolbar -->
160
+ <div class="h-10 bg-[#252526] flex items-center justify-between px-4 border-b border-gray-700 select-none">
161
+ <div class="flex items-center gap-2">
162
+ <span class="text-xs font-semibold text-blue-400 uppercase tracking-wider">Input.js</span>
163
+ <span class="w-2 h-2 rounded-full bg-yellow-500" title="Unsaved changes"></span>
164
+ </div>
165
+ <div class="flex gap-2">
166
+ <button onclick="copyCode()" class="text-xs flex items-center gap-1 text-gray-400 hover:text-white px-2 py-1 rounded hover:bg-gray-700 transition-colors" title="Copy to Clipboard">
167
+ <svg class="w-3 h-3" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z"></path></svg>
168
+ Copy
169
+ </button>
170
+ <button onclick="downloadCode()" class="text-xs flex items-center gap-1 text-gray-400 hover:text-white px-2 py-1 rounded hover:bg-gray-700 transition-colors" title="Download .txt">
171
+ <svg class="w-3 h-3" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 16v1a3 3 0 003 3h10a3 3 0 003-3v-1m-4-4l-4 4m0 0l-4-4m4 4V4"></path></svg>
172
+ Save
173
+ </button>
174
+ </div>
175
+ </div>
176
+
177
+ <!-- Editor Area -->
178
+ <div class="relative flex-1 overflow-hidden">
179
+ <div class="editor-container">
180
+ <div class="line-numbers" id="lineNumbers">1</div>
181
+ <textarea id="codeEditor" class="code-input" spellcheck="false" placeholder="// Write your JavaScript code here...">// Welcome to CodeFlow Studio
182
+ // Try editing this code and see the results instantly!
183
+
184
+ function calculateFactorial(n) {
185
+ if (n === 0 || n === 1) {
186
+ return 1;
187
+ }
188
+ return n * calculateFactorial(n - 1);
189
+ }
190
+
191
+ const number = 5;
192
+ const result = calculateFactorial(number);
193
+
194
+ console.log(`The factorial of ${number} is: ${result}`);
195
+
196
+ // Create a simple visual element
197
+ const div = document.createElement('div');
198
+ div.style.padding = '20px';
199
+ div.style.background = 'linear-gradient(135deg, #6366f1, #a855f7)';
200
+ div.style.color = 'white';
201
+ div.style.borderRadius = '12px';
202
+ div.style.marginTop = '10px';
203
+ div.style.textAlign = 'center';
204
+ div.style.fontFamily = 'sans-serif';
205
+ div.innerHTML = '<h2>Hello World!</h2><p>This DOM node was created by your code.</p>';
206
+ document.body.appendChild(div);</textarea>
207
+ </div>
208
+ </div>
209
+
210
+ <!-- Status Bar -->
211
+ <div class="h-6 bg-[#007acc] text-white text-[10px] flex items-center px-3 justify-between select-none">
212
+ <div class="flex gap-4">
213
+ <span class="flex items-center gap-1"><svg class="w-3 h-3" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M10 20l4-16m4 4l4 4-4 4M6 16l-4-4 4-4"></path></svg> master*</span>
214
+ <span id="cursorPos">Ln 1, Col 1</span>
215
+ </div>
216
+ <div class="flex gap-4">
217
+ <span>UTF-8</span>
218
+ <span>JavaScript</span>
219
+ <span id="liveIndicator" class="flex items-center gap-1"><span class="w-1.5 h-1.5 bg-green-400 rounded-full animate-pulse"></span> Live</span>
220
+ </div>
221
+ </div>
222
+ </section>
223
+
224
+ <!-- Resizer (Visual only for this demo, functional in full app) -->
225
+ <div class="w-1 bg-gray-700 hover:bg-blue-500 cursor-col-resize transition-colors z-20"></div>
226
+
227
+ <!-- Right Panel: Output -->
228
+ <section class="flex-1 flex flex-col min-w-[300px] bg-white relative">
229
+ <!-- Output Toolbar -->
230
+ <div class="h-10 bg-gray-100 flex items-center justify-between px-4 border-b border-gray-200 select-none">
231
+ <div class="flex items-center gap-2">
232
+ <svg class="w-4 h-4 text-gray-500" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9.75 17L9 20l-1 1h8l-1-1-.75-3M3 13h18M5 17h14a2 2 0 002-2V5a2 2 0 00-2-2H5a2 2 0 00-2 2v10a2 2 0 002 2z"></path></svg>
233
+ <span class="text-xs font-semibold text-gray-600 uppercase tracking-wider">Live Preview</span>
234
+ </div>
235
+ <button onclick="clearOutput()" class="text-xs text-red-500 hover:text-red-700 font-medium px-2 py-1 rounded hover:bg-red-50 transition-colors">
236
+ Clear Console
237
+ </button>
238
+ </div>
239
+
240
+ <!-- Output Content -->
241
+ <div class="flex-1 overflow-auto p-4 font-mono text-sm text-gray-800" id="outputContainer">
242
+ <!-- Dynamic content goes here -->
243
+ <div class="text-gray-400 italic text-xs mb-2 border-b border-gray-200 pb-2">Console Output:</div>
244
+ <div id="consoleLogs" class="space-y-1"></div>
245
+ <div id="visualOutput" class="mt-4"></div>
246
+ </div>
247
+ </section>
248
+
249
+ </main>
250
+
251
+ <!-- Settings Modal Overlay -->
252
+ <div id="settingsModal" class="fixed inset-0 z-50 hidden">
253
+ <!-- Backdrop -->
254
+ <div class="absolute inset-0 bg-black/60 backdrop-blur-sm transition-opacity opacity-0" id="modalBackdrop"></div>
255
+
256
+ <!-- Modal Content -->
257
+ <div class="absolute inset-0 flex items-center justify-center p-4 pointer-events-none">
258
+ <div class="bg-[#1e1e1e] w-full max-w-md rounded-xl shadow-2xl border border-gray-700 transform scale-95 opacity-0 transition-all duration-300 pointer-events-auto flex flex-col max-h-[80vh]" id="modalPanel">
259
+
260
+ <!-- Modal Header -->
261
+ <div class="flex items-center justify-between p-4 border-b border-gray-700">
262
+ <h2 class="text-lg font-semibold text-white flex items-center gap-2">
263
+ <svg class="w-5 h-5 text-gray-400" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M10.325 4.317c.426-1.756 2.924-1.756 3.35 0a1.724 1.724 0 002.573 1.066c1.543-.94 3.31.826 2.37 2.37a1.724 1.724 0 001.065 2.572c1.756.426 1.756 2.924 0 3.35a1.724 1.724 0 00-1.066 2.573c.94 1.543-.826 3.31-2.37 2.37a1.724 1.724 0 00-2.572 1.065c-.426 1.756-2.924 1.756-3.35 0a1.724 1.724 0 00-2.573-1.066c-1.543.94-3.31-.826-2.37-2.37a1.724 1.724 0 00-1.065-2.572c-1.756-.426-1.756-2.924 0-3.35a1.724 1.724 0 001.066-2.573c-.94-1.543.826-3.31 2.37-2.37.996.608 2.296.07 2.572-1.065z"></path><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 12a3 3 0 11-6 0 3 3 0 016 0z"></path></svg>
264
+ Settings
265
+ </h2>
266
+ <button id="closeSettings" class="text-gray-400 hover:text-white transition-colors">
267
+ <svg class="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12"></path></svg>
268
+ </button>
269
+ </div>
270
+
271
+ <!-- Modal Body -->
272
+ <div class="p-6 space-y-6 overflow-y-auto custom-scrollbar">
273
+
274
+ <!-- Theme Selection -->
275
+ <div class="space-y-3">
276
+ <label class="text-sm font-medium text-gray-300">Editor Theme</label>
277
+ <div class="grid grid-cols-3 gap-3">
278
+ <button class="theme-btn p-3 rounded-lg border border-gray-600 bg-[#1e1e1e] hover:border-blue-500 focus:ring-2 ring-blue-500 transition-all active-theme" data-theme="dark">
279
+ <div class="w-full h-8 bg-gray-800 rounded mb-2 border border-gray-700"></div>
280
+ <span class="text-xs text-gray-400">Dark</span>
281
+ </button>
282
+ <button class="theme-btn p-3 rounded-lg border border-gray-600 bg-[#1e1e1e] hover:border-blue-500 focus:ring-2 ring-blue-500 transition-all" data-theme="midnight">
283
+ <div class="w-full h-8 bg-[#0f172a] rounded mb-2 border border-gray-700"></div>
284
+ <span class="text-xs text-gray-400">Midnight</span>
285
+ </button>
286
+ <button class="theme-btn p-3 rounded-lg border border-gray-600 bg-[#1e1e1e] hover:border-blue-500 focus:ring-2 ring-blue-500 transition-all" data-theme="light">
287
+ <div class="w-full h-8 bg-gray-100 rounded mb-2 border border-gray-300"></div>
288
+ <span class="text-xs text-gray-400">Light</span>
289
+ </button>
290
+ </div>
291
+ </div>
292
+
293
+ <!-- Font Size -->
294
+ <div class="space-y-3">
295
+ <div class="flex justify-between">
296
+ <label class="text-sm font-medium text-gray-300">Font Size</label>
297
+ <span id="fontSizeVal" class="text-xs text-blue-400 font-mono">14px</span>
298
+ </div>
299
+ <input type="range" min="10" max="24" value="14" id="fontSizeSlider" class="w-full">
300
+ </div>
301
+
302
+ <!-- Toggles -->
303
+ <div class="space-y-3">
304
+ <label class="text-sm font-medium text-gray-300">Behavior</label>
305
+
306
+ <label class="flex items-center justify-between p-3 rounded-lg bg-gray-800/50 border border-gray-700 cursor-pointer hover:bg-gray-800 transition-colors">
307
+ <span class="text-sm text-gray-300">Word Wrap</span>
308
+ <div class="relative inline-block w-10 mr-2 align-middle select-none transition duration-200 ease-in">
309
+ <input type="checkbox" name="toggle" id="wordWrapToggle" class="toggle-checkbox absolute block w-5 h-5 rounded-full bg-white border-4 appearance-none cursor-pointer checked:right-0 checked:border-blue-500"/>
310
+ <label for="wordWrapToggle" class="toggle-label block overflow-hidden h-5 rounded-full bg-gray-600 cursor-pointer"></label>
311
+ </div>
312
+ </label>
313
+
314
+ <label class="flex items-center justify-between p-3 rounded-lg bg-gray-800/50 border border-gray-700 cursor-pointer hover:bg-gray-800 transition-colors">
315
+ <span class="text-sm text-gray-300">Auto Run on Type</span>
316
+ <div class="relative inline-block w-10 mr-2 align-middle select-none transition duration-200 ease-in">
317
+ <input type="checkbox" name="toggle" id="autoRunToggle" checked class="toggle-checkbox absolute block w-5 h-5 rounded-full bg-white border-4 appearance-none cursor-pointer checked:right-0 checked:border-blue-500"/>
318
+ <label for="autoRunToggle" class="toggle-label block overflow-hidden h-5 rounded-full bg-gray-600 cursor-pointer"></label>
319
+ </div>
320
+ </label>
321
+ </div>
322
+
323
+ </div>
324
+
325
+ <!-- Modal Footer -->
326
+ <div class="p-4 border-t border-gray-700 flex justify-end bg-[#252526] rounded-b-xl">
327
+ <button id="saveSettings" class="px-4 py-2 bg-blue-600 hover:bg-blue-500 text-white text-sm font-medium rounded-lg transition-colors shadow-lg shadow-blue-600/20">
328
+ Done
329
+ </button>
330
+ </div>
331
+ </div>
332
+ </div>
333
+ </div>
334
+
335
+ <!-- Toast Notification -->
336
+ <div id="toast" class="fixed bottom-6 right-6 bg-gray-800 text-white px-4 py-3 rounded-lg shadow-xl border border-gray-700 transform translate-y-20 opacity-0 transition-all duration-300 flex items-center gap-3 z-50">
337
+ <div id="toastIcon"></div>
338
+ <span id="toastMsg" class="text-sm font-medium">Notification</span>
339
+ </div>
340
+
341
+ <script>
342
+ // --- Elements ---
343
+ const editor = document.getElementById('codeEditor');
344
+ const lineNumbers = document.getElementById('lineNumbers');
345
+ const consoleLogs = document.getElementById('consoleLogs');
346
+ const visualOutput = document.getElementById('visualOutput');
347
+ const cursorPosDisplay = document.getElementById('cursorPos');
348
+
349
+ // Settings Elements
350
+ const settingsBtn = document.getElementById('settingsBtn');
351
+ const settingsModal = document.getElementById('settingsModal');
352
+ const modalBackdrop = document.getElementById('modalBackdrop');
353
+ const modalPanel = document.getElementById('modalPanel');
354
+ const closeSettings = document.getElementById('closeSettings');
355
+ const saveSettings = document.getElementById('saveSettings');
356
+ const fontSizeSlider = document.getElementById('fontSizeSlider');
357
+ const fontSizeVal = document.getElementById('fontSizeVal');
358
+ const wordWrapToggle = document.getElementById('wordWrapToggle');
359
+ const autoRunToggle = document.getElementById('autoRunToggle');
360
+
361
+ // State
362
+ let config = {
363
+ fontSize: 14,
364
+ wordWrap: false,
365
+ autoRun: true,
366
+ theme: 'dark'
367
+ };
368
+
369
+ // --- Initialization ---
370
+ document.addEventListener('DOMContentLoaded', () => {
371
+ updateLineNumbers();
372
+ runCode(); // Initial run
373
+ });
374
+
375
+ // --- Editor Logic ---
376
+
377
+ // Sync Line Numbers
378
+ const updateLineNumbers = () => {
379
+ const lines = editor.value.split('\n').length;
380
+ lineNumbers.innerHTML = Array(lines).fill(0).map((_, i) => `<div>${i + 1}</div>`).join('');
381
+ };
382
+
383
+ // Sync Scroll
384
+ editor.addEventListener('scroll', () => {
385
+ lineNumbers.scrollTop = editor.scrollTop;
386
+ });
387
+
388
+ // Input Handling
389
+ editor.addEventListener('input', () => {
390
+ updateLineNumbers();
391
+ if (config.autoRun) {
392
+ debouncedRun();
393
+ }
394
+ });
395
+
396
+ // Tab Support
397
+ editor.addEventListener('keydown', (e) => {
398
+ if (e.key === 'Tab') {
399
+ e.preventDefault();
400
+ const start = editor.selectionStart;
401
+ const end = editor.selectionEnd;
402
+ editor.value = editor.value.substring(0, start) + " " + editor.value.substring(end);
403
+ editor.selectionStart = editor.selectionEnd = start + 4;
404
+ }
405
+ });
406
+
407
+ // Cursor Position Update
408
+ editor.addEventListener('keyup', updateCursorPos);
409
+ editor.addEventListener('click', updateCursorPos);
410
+
411
+ function updateCursorPos() {
412
+ const val = editor.value;
413
+ const sel = editor.selectionStart;
414
+ const lines = val.substr(0, sel).split("\n");
415
+ const lineNum = lines.length;
416
+ const colNum = lines[lines.length - 1].length + 1;
417
+ cursorPosDisplay.textContent = `Ln ${lineNum}, Col ${colNum}`;
418
+ }
419
+
420
+ // --- Execution Engine ---
421
+
422
+ let debounceTimer;
423
+ const debouncedRun = () => {
424
+ clearTimeout(debounceTimer);
425
+ debounceTimer = setTimeout(runCode, 800); // 800ms delay for live typing
426
+ };
427
+
428
+ function clearOutput() {
429
+ consoleLogs.innerHTML = '';
430
+ visualOutput.innerHTML = '';
431
+ }
432
+
433
+ function runCode() {
434
+ clearOutput();
435
+ const code = editor.value;
436
+
437
+ // Capture Console
438
+ const originalLog = console.log;
439
+ const originalError = console.error;
440
+ const originalWarn = console.warn;
441
+
442
+ const createLogEntry = (type, args) => {
443
+ const div = document.createElement('div');
444
+ div.className = `font-mono text-xs p-2 rounded border-l-2 ${
445
+ type === 'error' ? 'bg-red-50 border-red-500 text-red-700' :
446
+ type === 'warn' ? 'bg-yellow-50 border-yellow-500 text-yellow-700' :
447
+ 'bg-gray-50 border-blue-500 text-gray-700'
448
+ }`;
449
+
450
+ // Format arguments
451
+ const text = args.map(arg => {
452
+ if (typeof arg === 'object') return JSON.stringify(arg, null, 2);
453
+ return String(arg);
454
+ }).join(' ');
455
+
456
+ div.textContent = `> ${text}`;
457
+ consoleLogs.appendChild(div);
458
+
459
+ // Auto scroll to bottom
460
+ const container = document.getElementById('outputContainer');
461
+ container.scrollTop = container.scrollHeight;
462
+ };
463
+
464
+ console.log = (...args) => {
465
+ createLogEntry('log', args);
466
+ originalLog(...args);
467
+ };
468
+
469
+ console.error = (...args) => {
470
+ createLogEntry('error', args);
471
+ originalError(...args);
472
+ };
473
+
474
+ console.warn = (...args) => {
475
+ createLogEntry('warn', args);
476
+ originalWarn(...args);
477
+ };
478
+
479
+ try {
480
+ // Execute Code safely-ish
481
+ // We wrap it in a function to allow returns (though ignored) and strict mode
482
+ const runUserCode = new Function(code);
483
+ runUserCode();
484
+ } catch (err) {
485
+ console.error(err.toString());
486
+ } finally {
487
+ // Restore console
488
+ console.log = originalLog;
489
+ console.error = originalError;
490
+ console.warn = originalWarn;
491
+ }
492
+ }
493
+
494
+ // --- Settings Modal Logic ---
495
+
496
+ function openModal() {
497
+ settingsModal.classList.remove('hidden');
498
+ // Trigger animations
499
+ setTimeout(() => {
500
+ modalBackdrop.classList.remove('opacity-0');
501
+ modalPanel.classList.remove('opacity-0', 'scale-95');
502
+ modalPanel.classList.add('scale-100');
503
+ }, 10);
504
+ }
505
+
506
+ function closeModal() {
507
+ modalBackdrop.classList.add('opacity-0');
508
+ modalPanel.classList.remove('scale-100');
509
+ modalPanel.classList.add('opacity-0', 'scale-95');
510
+ setTimeout(() => {
511
+ settingsModal.classList.add('hidden');
512
+ }, 300);
513
+ }
514
+
515
+ settingsBtn.addEventListener('click', openModal);
516
+ closeSettings.addEventListener('click', closeModal);
517
+ saveSettings.addEventListener('click', closeModal);
518
+ modalBackdrop.addEventListener('click', closeModal);
519
+
520
+ // --- Settings Interactions ---
521
+
522
+ // Font Size
523
+ fontSizeSlider.addEventListener('input', (e) => {
524
+ const size = e.target.value;
525
+ fontSizeVal.textContent = `${size}px`;
526
+ editor.style.fontSize = `${size}px`;
527
+ lineNumbers.style.fontSize = `${size}px`;
528
+ lineNumbers.style.lineHeight = `${parseInt(size) * 1.5}px`; // Approximate
529
+ editor.style.lineHeight = `${parseInt(size) * 1.5}px`;
530
+ });
531
+
532
+ // Word Wrap
533
+ wordWrapToggle.addEventListener('change', (e) => {
534
+ config.wordWrap = e.target.checked;
535
+ editor.style.whiteSpace = config.wordWrap ? 'pre-wrap' : 'pre';
536
+ });
537
+
538
+ // Auto Run
539
+ autoRunToggle.addEventListener('change', (e) => {
540
+ config.autoRun = e.target.checked;
541
+ const indicator = document.getElementById('liveIndicator');
542
+ if(config.autoRun) {
543
+ indicator.innerHTML = '<span class="w-1.5 h-1.5 bg-green-400 rounded-full animate-pulse"></span> Live';
544
+ runCode(); // Run immediately if turned on
545
+ } else {
546
+ indicator.innerHTML = '<span class="w-1.5 h-1.5 bg-gray-400 rounded-full"></span> Manual';
547
+ }
548
+ });
549
+
550
+ // Theme Switching (Simplified)
551
+ document.querySelectorAll('.theme-btn').forEach(btn => {
552
+ btn.addEventListener('click', () => {
553
+ // Remove active state from all
554
+ document.querySelectorAll('.theme-btn').forEach(b => {
555
+ b.classList.remove('ring-2', 'ring-blue-500', 'border-blue-500');
556
+ b.classList.add('border-gray-600');
557
+ });
558
+ // Add active state
559
+ btn.classList.remove('border-gray-600');
560
+ btn.classList.add('ring-2', 'ring-blue-500', 'border-blue-500');
561
+
562
+ const theme = btn.dataset.theme;
563
+ applyTheme(theme);
564
+ });
565
+ });
566
+
567
+ function applyTheme(theme) {
568
+ if (theme === 'light') {
569
+ editor.style.backgroundColor = '#ffffff';
570
+ editor.style.color = '#1f2937';
571
+ lineNumbers.style.backgroundColor = '#f3f4f6';
572
+ lineNumbers.style.color = '#9ca3af';
573
+ lineNumbers.style.borderRightColor = '#e5e7eb';
574
+ } else if (theme === 'midnight') {
575
+ editor.style.backgroundColor = '#0f172a';
576
+ editor.style.color = '#cbd5e1';
577
+ lineNumbers.style.backgroundColor = '#1e293b';
578
+ lineNumbers.style.color = '#64748b';
579
+ lineNumbers.style.borderRightColor = '#334155';
580
+ } else {
581
+ // Dark Default
582
+ editor.style.backgroundColor = '#1e1e1e';
583
+ editor.style.color = '#e5e7eb';
584
+ lineNumbers.style.backgroundColor = '#1e1e1e';
585
+ lineNumbers.style.color = '#6b7280';
586
+ lineNumbers.style.borderRightColor = '#374151';
587
+ }
588
+ }
589
+
590
+ // --- Utilities ---
591
+
592
+ function copyCode() {
593
+ navigator.clipboard.writeText(editor.value).then(() => {
594
+ showToast('Code copied to clipboard!', 'success');
595
+ }).catch(() => {
596
+ showToast('Failed to copy code.', 'error');
597
+ });
598
+ }
599
+
600
+ function downloadCode() {
601
+ const blob = new Blob([editor.value], { type: 'text/plain' });
602
+ const url = window.URL.createObjectURL(blob);
603
+ const a = document.createElement('a');
604
+ a.href = url;
605
+ a.download = 'script.txt'; // As requested .txt
606
+ a.click();
607
+ window.URL.revokeObjectURL(url);
608
+ showToast('File downloaded successfully!', 'success');
609
+ }
610
+
611
+ function showToast(message, type) {
612
+ const toast = document.getElementById('toast');
613
+ const msg = document.getElementById('toastMsg');
614
+ const icon = document.getElementById('toastIcon');
615
+
616
+ msg.textContent = message;
617
+
618
+ if (type === 'success') {
619
+ icon.innerHTML = `<svg class="w-5 h-5 text-green-400" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7"></path></svg>`;
620
+ } else {
621
+ icon.innerHTML = `<svg class="w-5 h-5 text-red-400" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12"></path></svg>`;
622
+ }
623
+
624
+ toast.classList.remove('translate-y-20', 'opacity-0');
625
+
626
+ setTimeout(() => {
627
+ toast.classList.add('translate-y-20', 'opacity-0');
628
+ }, 3000);
629
+ }
630
+
631
+ </script>
632
+ </body>
633
+ </html>