Wavetype commited on
Commit
b3473a1
·
verified ·
1 Parent(s): 8209836

Update index.html

Browse files
Files changed (1) hide show
  1. index.html +131 -135
index.html CHANGED
@@ -3,7 +3,7 @@
3
  <head>
4
  <meta charset="UTF-8">
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
- <title>Wavetype Frequency Grid - Pro</title>
7
  <link href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap/5.3.2/css/bootstrap.min.css" rel="stylesheet">
8
  <link href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-icons/1.11.1/font/bootstrap-icons.min.css" rel="stylesheet">
9
  <style>
@@ -12,8 +12,7 @@
12
  --border-python: #0000ff;
13
  --border-image: #00ff00;
14
  --border-video: #800080;
15
- --border-3d: #ffa500;
16
- --border-txt: #808080;
17
  --border-url: #00ffff;
18
  --bg-shade: 0.1;
19
  }
@@ -45,11 +44,7 @@
45
  #sidebar.collapsed ~ #sidebar-toggle { left: 0; }
46
 
47
  .auth-section { padding: 15px; border-bottom: 1px solid #333; background: #111; }
48
-
49
- .social-btn {
50
- width: 100%; margin-top: 8px; font-size: 12px; display: flex;
51
- align-items: center; justify-content: center; gap: 10px;
52
- }
53
 
54
  #grid-container {
55
  display: grid; width: 100vw; height: 100vh; gap: 4px; padding: 4px;
@@ -62,62 +57,44 @@
62
  position: relative; background-color: rgba(255, 255, 255, var(--bg-shade));
63
  border: 2px solid #333; display: flex; flex-direction: column;
64
  align-items: center; justify-content: center; cursor: pointer;
65
- overflow: hidden; animation: liquidPop 0.8s forwards;
66
  }
67
 
68
- @keyframes liquidPop {
69
- 0% { opacity: 0; transform: scale(0.8); }
70
- 100% { opacity: 1; transform: scale(1); }
71
- }
72
-
73
- .type-html { border-color: var(--border-html); }
74
  .type-python { border-color: var(--border-python); }
75
- .type-image { border-color: var(--border-image); }
76
- .type-video { border-color: var(--border-video); }
77
- .type-3d { border-color: var(--border-3d); }
78
- .type-txt { border-color: var(--border-txt); }
79
- .type-url { border-color: var(--border-url); }
80
 
81
  .block.active {
82
  position: fixed; top: 0; left: 0; width: 100vw !important;
83
- height: 100vh !important; z-index: 2500; background: #000; padding: 20px;
 
84
  }
85
 
86
  .close-btn {
87
  display: none; position: absolute; top: 20px; right: 20px;
88
- background: #dc3545; color: white; border: none; padding: 8px 16px;
89
  }
90
-
91
  .block.active .close-btn { display: block; }
92
 
93
- .preview-content { max-width: 90%; max-height: 80%; display: none; }
94
- .block.active .preview-content { display: block; }
95
 
96
- .type-selector-overlay {
97
- position: fixed; top: 0; left: 0; width: 100vw; height: 100vh;
98
- background: rgba(0,0,0,0.9); z-index: 3000; display: none;
99
- align-items: center; justify-content: center;
100
- }
101
-
102
- .type-options { display: grid; grid-template-columns: repeat(3, 1fr); gap: 10px; }
103
-
104
- .type-option {
105
- width: 80px; height: 80px; border: 2px solid #444; border-radius: 8px;
106
- display: flex; flex-direction: column; align-items: center;
107
- justify-content: center; cursor: pointer; font-size: 10px;
108
  }
109
 
110
  .add-block-btn {
111
- position: absolute; bottom: 5px; right: 5px; width: 24px; height: 24px;
112
  background: #00ff00; border-radius: 50%; color: #000; border: none; font-weight: bold;
113
  }
114
 
115
- .python-console {
116
- width: 100%; height: 60%; background: #000; color: #0f0;
117
- font-family: monospace; padding: 10px; border: 1px solid #333;
118
- overflow-y: auto; display: none; margin-top: 10px;
119
  }
120
- .block.active .python-console { display: block; }
 
121
  </style>
122
  </head>
123
  <body>
@@ -125,101 +102,78 @@
125
  <div id="sidebar">
126
  <div class="auth-section">
127
  <div id="user-profile" style="display: none;">
128
- <p class="small mb-2">Welcome, <span id="user-name" class="fw-bold">User</span></p>
129
- <button class="btn btn-outline-danger btn-sm w-100" onclick="handleLogout()">Sign Out</button>
 
 
 
130
  </div>
131
  <div id="login-section">
132
- <p class="small text-muted mb-2">Sign in to save layouts</p>
133
- <button class="btn btn-light social-btn" onclick="handleLogin('Google')">
134
- <i class="bi bi-google"></i> Google
135
- </button>
136
- <button class="btn btn-primary social-btn" onclick="handleLogin('GitHub')">
137
- <i class="bi bi-github"></i> GitHub
138
- </button>
139
  </div>
140
  </div>
141
 
142
  <div class="p-3">
143
  <div class="mb-4">
144
- <label class="form-label small">GRID DENSITY</label>
145
- <input type="range" class="form-range" id="blockSlider" min="1" max="64" value="4" oninput="updateGrid()">
146
- <div class="d-flex justify-content-between small">
147
- <span id="countVal">4</span> Blocks
148
- <span id="saveIcon" style="display:none; color:#0f0;">Saved!</span>
149
  </div>
150
  </div>
 
151
  <div class="mb-4">
152
- <label class="form-label small">BACKGROUND SHADE</label>
153
- <input type="range" class="form-range" id="shadeRange" min="0" max="0.5" step="0.05" value="0.1" oninput="updateShade()">
154
  </div>
155
- <button class="btn btn-success btn-sm w-100 mb-2" onclick="saveToCache()">MANUAL SAVE</button>
156
- <button class="btn btn-outline-secondary btn-sm w-100" onclick="clearGrid()">RESET ALL</button>
 
157
  </div>
158
  </div>
159
 
160
- <button id="sidebar-toggle" onclick="toggleSidebar()">
161
- <i class="bi bi-chevron-left"></i>
162
- </button>
163
 
164
  <div class="type-selector-overlay" id="typeSelectorOverlay">
165
  <div class="bg-dark p-4 rounded border border-secondary text-center">
166
- <h6>SELECT MODULE TYPE</h6>
167
- <div class="type-options">
168
- <div class="type-option" onclick="addNewBlock('html')"><i class="bi bi-code"></i>HTML</div>
169
- <div class="type-option" onclick="addNewBlock('python')"><i class="bi bi-terminal"></i>PY</div>
170
- <div class="type-option" onclick="addNewBlock('image')"><i class="bi bi-image"></i>IMG</div>
171
- <div class="type-option" onclick="addNewBlock('video')"><i class="bi bi-play-circle"></i>VID</div>
172
- <div class="type-option" onclick="addNewBlock('url')"><i class="bi bi-globe"></i>URL</div>
173
  </div>
174
- <button class="btn btn-sm btn-link text-danger mt-3" onclick="closeTypeSelector()">CANCEL</button>
175
  </div>
176
  </div>
177
 
178
- <div id="grid-container"></div>
179
-
180
- <script src="https://cdn.jsdelivr.net/pyodide/v0.27.3/full/pyodide.js"></script>
181
  <script>
182
  const container = document.getElementById("grid-container");
183
  const countDisplay = document.getElementById("countVal");
184
- const contentTypes = ["html", "python", "image", "video", "url"];
185
  let blocks = [];
186
  let currentUser = null;
187
- let pyodide = null;
188
-
189
- async function initPython() {
190
- if (!pyodide) {
191
- pyodide = await loadPyodide();
192
- await pyodide.loadPackage("micropip");
193
- }
194
- }
195
-
196
- function handleLogin(provider) {
197
- currentUser = { name: provider + " User", id: Date.now() };
198
- document.getElementById("login-section").style.display = "none";
199
- document.getElementById("user-profile").style.display = "block";
200
- document.getElementById("user-name").innerText = currentUser.name;
201
- saveToCache();
202
- }
203
-
204
- function handleLogout() {
205
- currentUser = null;
206
- document.getElementById("login-section").style.display = "block";
207
- document.getElementById("user-profile").style.display = "none";
208
- }
209
 
 
210
  function saveToCache() {
211
- const data = { blocks, shade: document.getElementById("shadeRange").value, user: currentUser };
212
- localStorage.setItem("wave_grid_cache", JSON.stringify(data));
213
- document.getElementById("saveIcon").style.display = "inline";
214
- setTimeout(() => { document.getElementById("saveIcon").style.display = "none"; }, 1500);
 
 
 
215
  }
216
 
217
  function loadFromCache() {
218
- const cache = localStorage.getItem("wave_grid_cache");
219
  if (cache) {
220
  const data = JSON.parse(cache);
221
- blocks = data.blocks;
222
- document.getElementById("shadeRange").value = data.shade;
223
  if (data.user) handleLogin(data.user.name.split(' ')[0]);
224
  renderGrid();
225
  } else {
@@ -227,64 +181,106 @@
227
  }
228
  }
229
 
230
- function toggleSidebar() { document.getElementById("sidebar").classList.toggle("collapsed"); }
231
- function openTypeSelector() { document.getElementById("typeSelectorOverlay").style.display = "flex"; }
232
- function closeTypeSelector() { document.getElementById("typeSelectorOverlay").style.display = "none"; }
233
-
234
  function updateGrid() {
235
  const count = parseInt(document.getElementById("blockSlider").value);
236
  countDisplay.innerText = count;
237
  while (blocks.length < count) {
238
- blocks.push({ id: Date.now() + Math.random(), type: contentTypes[Math.floor(Math.random() * contentTypes.length)], data: "" });
239
  }
240
  while (blocks.length > count) blocks.pop();
241
  renderGrid();
242
- saveToCache();
243
- }
244
-
245
- function addNewBlock(type) {
246
- blocks.push({ id: Date.now(), type, data: "" });
247
- closeTypeSelector();
248
- renderGrid();
249
- saveToCache();
250
  }
251
 
252
  function renderGrid() {
253
  const cols = Math.ceil(Math.sqrt(blocks.length)) || 1;
254
  container.style.gridTemplateColumns = `repeat(${cols}, 1fr)`;
255
  container.innerHTML = "";
 
256
  blocks.forEach((b, i) => {
257
  const el = document.createElement("div");
258
  el.className = `block type-${b.type}`;
259
  el.onclick = () => { if(!el.classList.contains('active')) el.classList.add('active'); };
260
 
261
- let content = `<span class="small fw-bold opacity-50">${b.type.toUpperCase()}</span>`;
262
- if(b.type === 'python') {
263
- content += `<textarea class="form-control form-control-sm m-2 w-75 bg-dark text-white" style="display:none" placeholder="print('hello')"></textarea>
264
- <button class="btn btn-sm btn-primary m-1" style="display:none" onclick="runPython(${i}, this)">RUN</button>
265
- <div class="python-console" id="console-${i}">Ready...</div>`;
266
- }
267
- content += `<button class="close-btn" onclick="event.stopPropagation(); this.parentElement.classList.remove('active')">EXIT</button>
268
- <button class="add-block-btn" onclick="event.stopPropagation(); openTypeSelector()">+</button>`;
269
- el.innerHTML = content;
 
 
 
 
270
  container.appendChild(el);
271
  });
272
  }
273
 
274
- async function runPython(index, btn) {
 
275
  event.stopPropagation();
276
- const code = btn.previousElementSibling.value;
277
- const consoleEl = document.getElementById(`console-${index}`);
278
- consoleEl.innerText = "Executing...";
 
 
 
 
 
 
 
 
 
279
  try {
280
- await initPython();
281
- let result = await pyodide.runPythonAsync(code);
282
- consoleEl.innerText = result || "Success (no output)";
 
 
 
 
 
 
 
 
 
 
283
  } catch (err) {
284
- consoleEl.innerText = "Error: " + err.message;
 
 
285
  }
286
  }
287
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
288
  window.onload = loadFromCache;
289
  </script>
290
  </body>
 
3
  <head>
4
  <meta charset="UTF-8">
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>Wavetype Frequency Grid - AI Edition</title>
7
  <link href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap/5.3.2/css/bootstrap.min.css" rel="stylesheet">
8
  <link href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-icons/1.11.1/font/bootstrap-icons.min.css" rel="stylesheet">
9
  <style>
 
12
  --border-python: #0000ff;
13
  --border-image: #00ff00;
14
  --border-video: #800080;
15
+ --border-ai: #ff00ff;
 
16
  --border-url: #00ffff;
17
  --bg-shade: 0.1;
18
  }
 
44
  #sidebar.collapsed ~ #sidebar-toggle { left: 0; }
45
 
46
  .auth-section { padding: 15px; border-bottom: 1px solid #333; background: #111; }
47
+ .social-btn { width: 100%; margin-top: 8px; font-size: 12px; display: flex; align-items: center; justify-content: center; gap: 10px; }
 
 
 
 
48
 
49
  #grid-container {
50
  display: grid; width: 100vw; height: 100vh; gap: 4px; padding: 4px;
 
57
  position: relative; background-color: rgba(255, 255, 255, var(--bg-shade));
58
  border: 2px solid #333; display: flex; flex-direction: column;
59
  align-items: center; justify-content: center; cursor: pointer;
60
+ overflow: hidden; transition: all 0.5s cubic-bezier(0.175, 0.885, 0.32, 1.275);
61
  }
62
 
63
+ .type-ai { border-color: var(--border-ai); }
 
 
 
 
 
64
  .type-python { border-color: var(--border-python); }
 
 
 
 
 
65
 
66
  .block.active {
67
  position: fixed; top: 0; left: 0; width: 100vw !important;
68
+ height: 100vh !important; z-index: 2500; background: #000; padding: 40px;
69
+ cursor: default;
70
  }
71
 
72
  .close-btn {
73
  display: none; position: absolute; top: 20px; right: 20px;
74
+ background: #dc3545; color: white; border: none; padding: 8px 16px; border-radius: 4px;
75
  }
 
76
  .block.active .close-btn { display: block; }
77
 
78
+ .ai-interface { display: none; width: 100%; max-width: 800px; flex-direction: column; gap: 15px; }
79
+ .block.active .ai-interface { display: flex; }
80
 
81
+ .gen-image-preview {
82
+ width: 100%; max-height: 50vh; object-fit: contain;
83
+ border: 2px solid var(--border-ai); display: none; background: #111;
 
 
 
 
 
 
 
 
 
84
  }
85
 
86
  .add-block-btn {
87
+ position: absolute; bottom: 8px; right: 8px; width: 28px; height: 28px;
88
  background: #00ff00; border-radius: 50%; color: #000; border: none; font-weight: bold;
89
  }
90
 
91
+ .type-selector-overlay {
92
+ position: fixed; top: 0; left: 0; width: 100vw; height: 100vh;
93
+ background: rgba(0,0,0,0.9); z-index: 3000; display: none;
94
+ align-items: center; justify-content: center;
95
  }
96
+
97
+ .status-pill { font-size: 10px; padding: 2px 8px; border-radius: 10px; background: #333; margin-top: 5px; }
98
  </style>
99
  </head>
100
  <body>
 
102
  <div id="sidebar">
103
  <div class="auth-section">
104
  <div id="user-profile" style="display: none;">
105
+ <div class="d-flex align-items-center gap-2 mb-2">
106
+ <i class="bi bi-person-circle fs-4 text-primary"></i>
107
+ <span id="user-name" class="small fw-bold">User</span>
108
+ </div>
109
+ <button class="btn btn-outline-danger btn-sm w-100" onclick="handleLogout()">Logout</button>
110
  </div>
111
  <div id="login-section">
112
+ <p class="small text-muted mb-2">Sync to Linux VPS</p>
113
+ <button class="btn btn-outline-light social-btn" onclick="handleLogin('Google')"><i class="bi bi-google"></i> Google</button>
114
+ <button class="btn btn-outline-light social-btn" onclick="handleLogin('GitHub')"><i class="bi bi-github"></i> GitHub</button>
 
 
 
 
115
  </div>
116
  </div>
117
 
118
  <div class="p-3">
119
  <div class="mb-4">
120
+ <label class="form-label small">GRID INTENSITY</label>
121
+ <input type="range" class="form-range" id="blockSlider" min="1" max="25" value="4" oninput="updateGrid()">
122
+ <div class="d-flex justify-content-between small text-muted">
123
+ <span id="countVal">4</span> Nodes
124
+ <span id="saveStatus">Synced</span>
125
  </div>
126
  </div>
127
+
128
  <div class="mb-4">
129
+ <label class="form-label small">HUGGINGFACE TOKEN</label>
130
+ <input type="password" class="form-control form-control-sm bg-dark text-white border-secondary" id="hfToken" placeholder="hf_..." onchange="saveToCache()">
131
  </div>
132
+
133
+ <button class="btn btn-primary btn-sm w-100 mb-2" onclick="saveToCache()">SAVE LAYOUT</button>
134
+ <button class="btn btn-outline-secondary btn-sm w-100" onclick="clearGrid()">RESET GRID</button>
135
  </div>
136
  </div>
137
 
138
+ <button id="sidebar-toggle" onclick="toggleSidebar()"><i class="bi bi-chevron-left"></i></button>
139
+
140
+ <div id="grid-container"></div>
141
 
142
  <div class="type-selector-overlay" id="typeSelectorOverlay">
143
  <div class="bg-dark p-4 rounded border border-secondary text-center">
144
+ <h6 class="mb-4">ADD MODULE</h6>
145
+ <div class="d-flex gap-3 justify-content-center">
146
+ <button class="btn btn-outline-info" onclick="addNewBlock('ai')"><i class="bi bi-cpu"></i><br>FLUX AI</button>
147
+ <button class="btn btn-outline-warning" onclick="addNewBlock('python')"><i class="bi bi-terminal"></i><br>PYTHON</button>
148
+ <button class="btn btn-outline-success" onclick="addNewBlock('url')"><i class="bi bi-globe"></i><br>WEB</button>
 
 
149
  </div>
150
+ <button class="btn btn-sm btn-link text-danger mt-4" onclick="closeTypeSelector()">CANCEL</button>
151
  </div>
152
  </div>
153
 
 
 
 
154
  <script>
155
  const container = document.getElementById("grid-container");
156
  const countDisplay = document.getElementById("countVal");
 
157
  let blocks = [];
158
  let currentUser = null;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
159
 
160
+ // --- Persistence ---
161
  function saveToCache() {
162
+ const data = {
163
+ blocks,
164
+ token: document.getElementById("hfToken").value,
165
+ user: currentUser
166
+ };
167
+ localStorage.setItem("wavetype_vps_cache", JSON.stringify(data));
168
+ showStatus("Saved to Cache");
169
  }
170
 
171
  function loadFromCache() {
172
+ const cache = localStorage.getItem("wavetype_vps_cache");
173
  if (cache) {
174
  const data = JSON.parse(cache);
175
+ blocks = data.blocks || [];
176
+ document.getElementById("hfToken").value = data.token || "";
177
  if (data.user) handleLogin(data.user.name.split(' ')[0]);
178
  renderGrid();
179
  } else {
 
181
  }
182
  }
183
 
184
+ // --- Grid System ---
 
 
 
185
  function updateGrid() {
186
  const count = parseInt(document.getElementById("blockSlider").value);
187
  countDisplay.innerText = count;
188
  while (blocks.length < count) {
189
+ blocks.push({ id: Date.now() + Math.random(), type: 'ai', prompt: "" });
190
  }
191
  while (blocks.length > count) blocks.pop();
192
  renderGrid();
 
 
 
 
 
 
 
 
193
  }
194
 
195
  function renderGrid() {
196
  const cols = Math.ceil(Math.sqrt(blocks.length)) || 1;
197
  container.style.gridTemplateColumns = `repeat(${cols}, 1fr)`;
198
  container.innerHTML = "";
199
+
200
  blocks.forEach((b, i) => {
201
  const el = document.createElement("div");
202
  el.className = `block type-${b.type}`;
203
  el.onclick = () => { if(!el.classList.contains('active')) el.classList.add('active'); };
204
 
205
+ el.innerHTML = `
206
+ <div class="ai-interface">
207
+ <h4 class="text-info">FLUX.1-KLEIN-9B [VPS MODE]</h4>
208
+ <textarea class="form-control bg-dark text-white border-info mb-2" id="prompt-${i}" rows="3" placeholder="Describe the image...">${b.prompt || ""}</textarea>
209
+ <button class="btn btn-info w-100" onclick="generateFlux(${i}, this)">GENERATE ON VPS</button>
210
+ <div id="loader-${i}" class="text-center mt-2" style="display:none"><div class="spinner-border spinner-border-sm text-info"></div> Processing...</div>
211
+ <img id="img-${i}" class="gen-image-preview mt-3">
212
+ </div>
213
+ <div class="small fw-bold opacity-50">${b.type.toUpperCase()} NODE</div>
214
+ <div class="status-pill">Ready</div>
215
+ <button class="close-btn" onclick="event.stopPropagation(); this.parentElement.classList.remove('active')">CLOSE NODE</button>
216
+ <button class="add-block-btn" onclick="event.stopPropagation(); openTypeSelector()">+</button>
217
+ `;
218
  container.appendChild(el);
219
  });
220
  }
221
 
222
+ // --- AI Logic (Flux2 Klein 9B) ---
223
+ async function generateFlux(index, btn) {
224
  event.stopPropagation();
225
+ const prompt = document.getElementById(`prompt-${index}`).value;
226
+ const token = document.getElementById("hfToken").value;
227
+ const imgEl = document.getElementById(`img-${index}`);
228
+ const loader = document.getElementById(`loader-${index}`);
229
+
230
+ if (!token) return alert("Please enter Hugging Face Token in sidebar.");
231
+
232
+ loader.style.display = "block";
233
+ imgEl.style.display = "none";
234
+ blocks[index].prompt = prompt;
235
+ saveToCache();
236
+
237
  try {
238
+ const response = await fetch(
239
+ "https://api-inference.huggingface.co/models/Comfy-Org/flux2-klein-9B",
240
+ {
241
+ headers: { Authorization: `Bearer ${token}` },
242
+ method: "POST",
243
+ body: JSON.stringify({ inputs: prompt }),
244
+ }
245
+ );
246
+
247
+ const blob = await response.blob();
248
+ const url = URL.createObjectURL(blob);
249
+ imgEl.src = url;
250
+ imgEl.style.display = "block";
251
  } catch (err) {
252
+ alert("Generation failed: Check token or model status");
253
+ } finally {
254
+ loader.style.display = "none";
255
  }
256
  }
257
 
258
+ // --- Auth & UI Helpers ---
259
+ function handleLogin(provider) {
260
+ currentUser = { name: provider + " Dev", id: Date.now() };
261
+ document.getElementById("login-section").style.display = "none";
262
+ document.getElementById("user-profile").style.display = "block";
263
+ document.getElementById("user-name").innerText = currentUser.name;
264
+ }
265
+
266
+ function handleLogout() {
267
+ currentUser = null;
268
+ document.getElementById("login-section").style.display = "block";
269
+ document.getElementById("user-profile").style.display = "none";
270
+ }
271
+
272
+ function showStatus(msg) {
273
+ const s = document.getElementById("saveStatus");
274
+ s.innerText = msg;
275
+ setTimeout(() => s.innerText = "Synced", 2000);
276
+ }
277
+
278
+ function toggleSidebar() { document.getElementById("sidebar").classList.toggle("collapsed"); }
279
+ function openTypeSelector() { document.getElementById("typeSelectorOverlay").style.display = "flex"; }
280
+ function closeTypeSelector() { document.getElementById("typeSelectorOverlay").style.display = "none"; }
281
+ function addNewBlock(type) { blocks.push({ id: Date.now(), type, prompt: "" }); updateGrid(); closeTypeSelector(); }
282
+ function clearGrid() { blocks = []; updateGrid(); localStorage.clear(); }
283
+
284
  window.onload = loadFromCache;
285
  </script>
286
  </body>