Compare commits

...

48 Commits
master ... main

Author SHA1 Message Date
043d121847 Fix versions numbering 2025-06-07 22:51:14 -07:00
525064596f Version Bump 2025-06-07 22:47:28 -07:00
𓍼
7beb269867 version 2025-06-08 00:44:18 -05:00
𓍼
20d49560e9 stuff 2025-06-08 00:43:31 -05:00
𓍼
396b81929a forgot the dot 2025-06-07 22:13:23 -05:00
𓍼
b2ad89c28a remove subjects 2025-06-07 17:17:38 -05:00
𓍼
ee3092a590 Smaller 2025-06-07 16:56:39 -05:00
𓍼
265de4f542 UPDATEEEE 2025-06-07 16:54:12 -05:00
𓍼
c2a6cb8639 uh 2025-06-06 19:06:46 -05:00
𓍼
6fd71fa6fa ? 2025-06-06 19:02:40 -05:00
𓍼
994cb17641 hi 2025-06-06 19:01:51 -05:00
𓍼
c265e724c9 Fix latest commit 2025-06-06 12:52:49 -05:00
𓍼
dc72461a68 Fix latest commit 2025-06-06 12:44:31 -05:00
2b1a912478 Update others/scaler.mjs 2025-06-05 21:26:40 -07:00
78fbc42a0c Add others/scaler.mjs 2025-06-05 21:25:37 -07:00
65bc526a91 Delete others/scaler.mjs 2025-06-05 21:24:46 -07:00
bc878dfb64 Add others/scaler.mjs 2025-06-05 21:23:14 -07:00
a083758325 Delete others/scaler.mjs 2025-06-05 21:22:22 -07:00
b622f3cb9b Cool Thingy 2025-06-05 21:18:57 -07:00
ff50de3064 Update index.mjs 2025-06-05 21:12:54 -07:00
c13a708584 Update others/scaler.mjs 2025-06-05 21:12:21 -07:00
8845426001 60000 2025-06-05 21:10:10 -07:00
𓍼
89279a6735 Something 2025-06-05 22:52:01 -05:00
𓍼
526ec4f236 Merge branch 'main' of https://gitea.sentt.lol/sent/waves 2025-06-05 22:50:24 -05:00
𓍼
f78a14b79c Something 2025-06-05 22:49:17 -05:00
e50b65dde1 Update public/$.html 2025-06-01 19:53:00 -07:00
f0529b100e Update public/assets/js/register.js 2025-06-01 19:49:22 -07:00
4658e475ef idk 2025-06-01 19:40:51 -07:00
𓍼
7b3737d44c Rename the API 2025-05-25 17:41:29 -05:00
𓍼
91e44ce19a Remove ads on 1v1.LOL 2025-05-25 14:43:27 -05:00
𓍼
ac7cc48119 ok 2025-05-25 14:27:15 -05:00
𓍼
d9de280d3d Last update for today 2025-05-25 14:25:58 -05:00
𓍼
1fb3876cd4 Fixes 2025-05-25 14:24:32 -05:00
𓍼
c568949e74 cool 2025-05-25 12:48:11 -05:00
𓍼
6f84c2a9e5 okay 2025-05-25 12:34:36 -05:00
𓍼
97a6a4a94a Remove lat updated label and only keep latest commit id 2025-05-25 12:27:18 -05:00
𓍼
e1b5f73c31 Whoops 2025-05-25 09:50:37 -05:00
𓍼
87f8a54656 Wrong one 2025-05-25 09:49:18 -05:00
𓍼
84b0c084de only get latest update 2025-05-25 09:47:27 -05:00
𓍼
6a269bbaae Accidentaly remove the banned ad 2025-05-25 09:36:22 -05:00
𓍼
9f9a892798 wv 2025-05-25 09:33:51 -05:00
𓍼
ff7390d3ae Top 2025-05-25 09:32:20 -05:00
𓍼
7ae9abb1ad Remove a game (it wasn't supposed to be push) and update the verification script 2025-05-25 09:30:11 -05:00
𓍼
cd4c462e62 Small Update 🤍 2025-05-25 09:20:08 -05:00
𓍼
b5a927077a Back to DuckDuckGo 2025-05-22 11:48:45 -05:00
𓍼
5996c1a6e0 Brave? 2025-05-21 23:33:19 -05:00
𓍼
ffe52a61e7 Colors Change 2025-05-21 23:30:03 -05:00
4551ab18c1 Merge pull request 'Small Little Update' (#2) from master into main
Reviewed-on: https://gitea.sentt.lol/sent/waves/pulls/2
2025-05-21 21:24:35 -07:00
33 changed files with 2807 additions and 37096 deletions

View File

@ -4,7 +4,9 @@
The following versions of this project that are currently supported and unsupported: The following versions of this project that are currently supported and unsupported:
- **Version 2.3.5** Supported ✅ - **Version 2.8.9** Supported ✅
- **Version 2.8.7** Supported ✅
- **Version 2.8.5** Supported ✅
- **Version 2.3.1** Supported ✅ - **Version 2.3.1** Supported ✅
- **Version 2.3.0** Supported ✅ - **Version 2.3.0** Supported ✅
- **Version 2.2.0** Supported ✅ - **Version 2.2.0** Supported ✅
@ -17,4 +19,4 @@ The following versions of this project that are currently supported and unsuppor
## Support ## Support
If you are experiencing an issue with Waves unrelated to security, feel free to join our [Discord](https://discord.gg/dJvdkPRheV) server and open a ticket. If you are experiencing an issue with Waves unrelated to security, feel free to join our [Discord Server](https://discord.gg/dJvdkPRheV) and open a ticket.

191
index.mjs
View File

@ -2,8 +2,8 @@ import cluster from "cluster";
import os from "os"; import os from "os";
import net from "net"; import net from "net";
import fs from "fs"; import fs from "fs";
import { spawnSync } from "child_process";
import path from "path"; import path from "path";
import { spawnSync } from "child_process";
import express from "express"; import express from "express";
import { createServer } from "http"; import { createServer } from "http";
import compression from "compression"; import compression from "compression";
@ -23,28 +23,22 @@ function applySurgeAndRestartIfNeeded() {
try { try {
const config = JSON.parse(fs.readFileSync(surgeConfigPath, "utf-8")); const config = JSON.parse(fs.readFileSync(surgeConfigPath, "utf-8"));
process.env.UV_THREADPOOL_SIZE = String(config.uvThreadpoolSize); process.env.UV_THREADPOOL_SIZE = String(config.uvThreadpoolSize);
} catch { } catch {}
}
return; return;
} }
console.log('[~] Running Surge...');
const result = spawnSync("node", ["./others/surge.mjs"], { stdio: "inherit" }); const result = spawnSync("node", ["./others/surge.mjs"], { stdio: "inherit" });
if (result.error) { if (result.error) process.exit(1);
console.error('[!] Surger failed:', result.error);
process.exit(1);
}
const config = JSON.parse(fs.readFileSync(surgeConfigPath, "utf-8")); const config = JSON.parse(fs.readFileSync(surgeConfigPath, "utf-8"));
const nodeArgs = config.nodeFlags.concat([path.resolve("index.mjs"), "--surged"]); const nodeArgs = [...config.nodeFlags, path.resolve("index.mjs"), "--surged"];
const env = { const env = {
...process.env, ...process.env,
UV_THREADPOOL_SIZE: String(config.uvThreadpoolSize), UV_THREADPOOL_SIZE: String(config.uvThreadpoolSize),
ALREADY_SURGED: "true" ALREADY_SURGED: "true"
}; };
console.log(`[~] Relaunching with Node flags: ${config.nodeFlags.join(' ')}`); const relaunch = spawnSync(process.execPath, nodeArgs, { stdio: "inherit", env });
const relaunch = spawnSync(process.execPath, nodeArgs, { stdio: 'inherit', env });
process.exit(relaunch.status || 0); process.exit(relaunch.status || 0);
} }
@ -53,39 +47,40 @@ applySurgeAndRestartIfNeeded();
if (global.gc) { if (global.gc) {
setInterval(() => { setInterval(() => {
const { heapUsed, heapTotal } = process.memoryUsage(); const { heapUsed, heapTotal } = process.memoryUsage();
if (heapTotal > 0 && heapUsed / heapTotal > 0.7) { if (heapTotal > 0 && heapUsed / heapTotal > 0.8) global.gc();
global.gc(); }, 120000);
console.info('[~] Performed GC due to high heap usage');
}
}, 60_000);
} }
import './others/scaler.mjs'; import "./others/scaler.mjs";
import './others/warmup.mjs'; import "./others/warmup.mjs";
const cache = new LRUCache({
maxSize: 1000,
ttl: 4 * 24 * 60 * 60 * 1000,
allowStale: false,
});
const port = parseInt(process.env.PORT || "3000", 10); const port = parseInt(process.env.PORT || "3000", 10);
function logInfo(msg) { console.info(`[~] ${msg}`); } function logInfo(msg) {
function logSuccess(msg) { console.info(`[+] ${msg}`); } console.info(`[~] ${msg}`);
function logError(err) { console.error(`[!] ${err instanceof Error ? err.message : err}`); } }
function logSuccess(msg) {
console.info(`[+] ${msg}`);
}
function logError(err) {
console.error(`[!] ${err instanceof Error ? err.message : err}`);
}
process.on("uncaughtException", err => logError(`Unhandled Exception: ${err}`)); process.on("uncaughtException", err => logError(`Unhandled Exception: ${err}`));
process.on("unhandledRejection", reason => logError(`Unhandled Rejection: ${reason}`)); process.on("unhandledRejection", reason => logError(`Unhandled Rejection: ${reason}`));
if (cluster.isPrimary) { if (cluster.isPrimary) {
const cpus = os.cpus().length; const workers = Math.max(1, os.cpus().length - 1);
const workers = Math.max(1, cpus - 1); logInfo(`Master: forking ${workers} workers`);
logInfo(`Master: forking ${workers} of ${cpus} cores`);
for (let i = 0; i < workers; i++) cluster.fork();
cluster.on("exit", (worker, code, signal) => { for (let i = 0; i < workers; i++) {
logError(`Worker ${worker.process.pid} exited (code=${code}, signal=${signal}). Restarting...`); cluster.fork();
}
cluster.on("exit", worker => {
logError(`Worker ${worker.process.pid} exited. Restarting...`);
cluster.fork(); cluster.fork();
}); });
@ -98,23 +93,31 @@ if (cluster.isPrimary) {
}); });
server.on("error", err => logError(`Server error: ${err}`)); server.on("error", err => logError(`Server error: ${err}`));
server.listen(port, () => logSuccess(`Server listening on port ${port}`)); server.listen(port, () => logSuccess(`Server listening on ${port}`));
} else { } else {
const __dirname = process.cwd(); const __dirname = process.cwd();
const publicPath = path.join(__dirname, "public"); const publicPath = path.join(__dirname, "public");
const app = express(); const app = express();
const cache = new LRUCache({
max: 500,
ttl: 60_000,
allowStale: false
});
const latencySamples = new Array(200);
app.use(compression({ level: 4, memLevel: 4, threshold: 1024 })); app.use(compression({ level: 4, memLevel: 4, threshold: 1024 }));
app.use((req, res, next) => { app.use((req, res, next) => {
if (req.path.startsWith("/api/")) return next();
const key = req.originalUrl; const key = req.originalUrl;
const val = cache.get(key); const val = cache.get(key);
if (val) { if (val) {
res.setHeader("X-Cache", "HIT"); res.setHeader("X-Cache", "HIT");
return res.send(val); return res.send(val);
} }
res.sendResponse = res.send.bind(res); res.sendResponse = res.send;
res.send = body => { res.send = body => {
cache.set(key, body); cache.set(key, body);
res.setHeader("X-Cache", "MISS"); res.setHeader("X-Cache", "MISS");
@ -123,67 +126,97 @@ if (cluster.isPrimary) {
next(); next();
}); });
const staticOpts = { maxAge: "7d", immutable: true }; const staticOpts = { maxAge: "7d", immutable: true, etag: false };
app.use("/baremux/", express.static(baremuxPath, staticOpts)); app.use("/baremux/", express.static(baremuxPath, staticOpts));
app.use("/epoxy/", express.static(epoxyPath, staticOpts)); app.use("/epoxy/", express.static(epoxyPath, staticOpts));
app.use("/libcurl/", express.static(libcurlPath, staticOpts)); app.use("/libcurl/", express.static(libcurlPath, staticOpts));
app.use(express.static(publicPath, staticOpts)); app.use(express.static(publicPath, staticOpts));
app.use("/wah/", express.static(uvPath, staticOpts)); app.use("/wah/", express.static(uvPath, staticOpts));
app.use(express.json()); const sendHtml = file => (_req, res) => res.sendFile(path.join(publicPath, file));
const sendHtml = file => (req, res) => res.sendFile(path.join(publicPath, file)); app.get("/", sendHtml("$.html"));
app.get('/', sendHtml('$.html')); app.get("/g", sendHtml("!.html"));
app.get('/g', sendHtml('!.html')); app.get("/s", sendHtml("!!.html"));
app.get('/a', sendHtml('!!.html')); app.get("/resent", (_req, res) => res.sendFile(path.join(publicPath, "resent", "index.html")));
app.get('/resent', (req, res) => res.sendFile(path.join(publicPath, 'resent', 'index.html')));
app.use((req, res) => res.status(404).sendFile(path.join(publicPath, '404.html')));
const server = createServer(app); app.get("/api/info", (_req, res) => {
server.keepAliveTimeout = 0; const validSamples = latencySamples.filter(s => s !== undefined);
server.headersTimeout = 0; const average = validSamples.length ? validSamples.reduce((a, b) => a + b, 0) / validSamples.length : 0;
res.json({
const pingWSS = new WebSocket.Server({ noServer: true, maxPayload: 4 * 1024 * 1024, perMessageDeflate: false }); speed: average < 200 ? "Fast" : average > 500 ? "Slow" : "Medium",
pingWSS.on("connection", (ws, req) => { averageLatency: average.toFixed(2),
const remote = req.socket.remoteAddress || 'unknown'; timestamp: Date.now()
let lat = [];
const interval = setInterval(() => {
if (ws.readyState === WebSocket.OPEN) ws.send(JSON.stringify({ type: 'ping', timestamp: Date.now() }));
}, 1000);
ws.on('message', msg => {
try {
const data = JSON.parse(msg);
if (data.type === 'pong' && data.timestamp) {
const d = Date.now() - data.timestamp;
lat.push(d);
if (lat.length > 5) lat.shift();
ws.send(JSON.stringify({ type: 'latency', latency: d }));
}
} catch(e) { logError(`Ping error: ${e}`); }
});
ws.on('close', () => {
clearInterval(interval);
const avg = lat.length ? (lat.reduce((a,b)=>a+b)/lat.length).toFixed(2) : 0;
logInfo(`WS ${remote} closed. Avg latency ${avg}ms`);
}); });
}); });
server.on('upgrade', (req, sock, head) => { app.use((_req, res) => res.status(404).sendFile(path.join(publicPath, "404.html")));
if (req.url === '/w/ping') {
pingWSS.handleUpgrade(req, sock, head, ws => pingWSS.emit('connection', ws, req)); const server = createServer(app);
} else if (req.url.startsWith('/w/')) { server.keepAliveTimeout = 5000;
server.headersTimeout = 10000;
const pingWSS = new WebSocket.Server({
noServer: true,
maxPayload: 16384,
perMessageDeflate: false
});
pingWSS.on("connection", (ws, req) => {
const remote = req.socket.remoteAddress || "unknown";
const lat = [];
let sampleIndex = 0;
const sendPing = () => {
if (ws.readyState === WebSocket.OPEN) {
ws.send(JSON.stringify({ type: "ping", timestamp: Date.now() }));
}
};
const pingInterval = setInterval(sendPing, 500);
sendPing();
ws.on("message", msg => {
try {
const data = JSON.parse(msg);
if (data.type === "pong" && data.timestamp) {
const d = Date.now() - data.timestamp;
lat.push(d);
if (lat.length > 10) lat.shift();
latencySamples[sampleIndex % latencySamples.length] = d;
sampleIndex = (sampleIndex + 1) % latencySamples.length;
ws.send(JSON.stringify({ type: "latency", latency: d }), { compress: false });
}
} catch {}
});
ws.on("close", () => {
clearInterval(pingInterval);
const avg = lat.length ? (lat.reduce((a, b) => a + b) / lat.length).toFixed(2) : 0;
logInfo(`WS ${remote} closed. Avg: ${avg}ms`);
});
});
server.on("upgrade", (req, sock, head) => {
if (req.url === "/w/ping") {
pingWSS.handleUpgrade(req, sock, head, ws =>
pingWSS.emit("connection", ws, req)
);
} else if (req.url.startsWith("/w/")) {
wisp.routeRequest(req, sock, head); wisp.routeRequest(req, sock, head);
} else { } else {
sock.end(); sock.destroy();
} }
}); });
server.on('error', err => logError(`Worker server error: ${err}`)); server.on("error", err => logError(`Worker error: ${err}`));
server.listen(0, () => logSuccess(`Worker ${process.pid} ready`)); server.listen(0, () => logSuccess(`Worker ${process.pid} ready`));
process.on('message', (msg, conn) => { process.on("message", (msg, conn) => {
if (msg === 'sticky-session:connection' && conn) { if (msg === "sticky-session:connection" && conn) {
server.emit('connection', conn); server.emit("connection", conn);
conn.resume(); conn.resume();
} }
}); });

View File

@ -6,7 +6,7 @@ let cache = makeCache(maxKeys);
function makeCache(maxEntries) { function makeCache(maxEntries) {
return new LRUCache({ return new LRUCache({
maxSize: maxEntries, maxSize: maxEntries,
ttl: 4 * 24 * 60 * 60 * 1_000, ttl: 60_000,
allowStale: false, allowStale: false,
updateAgeOnGet: false, updateAgeOnGet: false,
updateAgeOnHas: false, updateAgeOnHas: false,

3340
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -1,44 +1,41 @@
{ {
"name": "waves", "name": "waves",
"version": "2.8.5", "version": "2.8.9",
"description": "A sleek and minimalist Web Proxy.", "description": "A sleek and minimalist Web Proxy.",
"type": "module", "type": "module",
"engines": { "engines": {
"npm": ">=7.0.0", "npm": ">=7.0.0",
"node": ">=16.0.0" "node": ">=16.0.0"
}, },
"scripts": { "scripts": {
"start": "node index.mjs", "start": "node index.mjs",
"dev": "nodemon index.mjs", "dev": "nodemon index.mjs",
"lint": "eslint ." "lint": "eslint ."
}, },
"author": { "author": {
"name": "sent", "name": "sent",
"email": "sentttt@proton.me" "email": "sentttt@proton.me"
}, },
"dependencies": { "dependencies": {
"@mercuryworkshop/bare-mux": "latest", "@mercuryworkshop/bare-mux": "latest",
"@mercuryworkshop/epoxy-transport": "latest", "@mercuryworkshop/epoxy-transport": "latest",
"@mercuryworkshop/libcurl-transport": "latest", "@mercuryworkshop/libcurl-transport": "latest",
"@titaniumnetwork-dev/ultraviolet": "latest", "@titaniumnetwork-dev/ultraviolet": "latest",
"axios": "^1.8.2", "axios": "latest",
"cache": "^3.0.0", "cache": "latest",
"compression": "latest", "compression": "latest",
"cors": "^2.8.5", "cors": "latest",
"express": "latest", "express": "latest",
"express-rate-limit": "^7.5.0", "express-rate-limit": "latest",
"fs": "^0.0.1-security", "lru-cache": "latest",
"node": "^23.9.0", "wisp-server-node": "latest",
"lru-cache": "^11.1.0", "ws": "latest"
"node-fetch": "latest", },
"wisp-server-node": "latest", "devDependencies": {
"ws": "latest" "eslint": "latest",
}, "glob": "latest",
"devDependencies": { "nodemon": "latest",
"eslint": "latest", "prettier": "latest",
"glob": "latest", "rimraf": "latest"
"nodemon": "latest", }
"prettier": "latest", }
"rimraf": "latest"
}
}

View File

@ -1,110 +1,155 @@
<!DOCTYPE html> <!DOCTYPE html>
<html lang="en"> <html lang="en">
<head> <head>
<meta charset="UTF-8" /> <meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta property="og:title" content="Waves. - Apps"/> <meta property="og:title" content="Waves." />
<meta property="og:description" content="A sleek and minimalist web proxy."/> <meta property="og:description" content="A sleek and minimalist web proxy." />
<meta property="og:image" content="/assets/images/icons/favicon.ico"/> <meta property="og:image" content="/assets/images/icons/favicon.ico" />
<meta name="theme-color" content="#ffffff"/> <meta name="theme-color" content="#ffffff" />
<meta name="msapplication-TileColor" content="#ffffff"/> <meta name="msapplication-TileColor" content="#ffffff" />
<title>Waves.</title> <title>Waves.</title>
<link rel="icon" type="image/x-icon" href="/assets/images/icons/favicon.ico">
<link rel="stylesheet" href="/assets/css/$.css"> <link rel="preconnect" href="https://cdn.jsdelivr.net" crossorigin />
<link rel="stylesheet" href="/assets/css/settings.css">
<link rel="stylesheet" href="/assets/css/toast.css"> <link rel="icon" type="image/x-icon" href="/assets/images/icons/favicon.ico" />
<link rel="stylesheet" href="/assets/css/a.css">
<link href="https://cdn.jsdelivr.net/gh/aquawolf04/font-awesome-pro@5cd1511/css/all.css" rel="stylesheet"> <link rel="stylesheet" href="/assets/css/$.css" />
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/nprogress/0.2.0/nprogress.min.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/nprogress/0.2.0/nprogress.min.js"></script> <link rel="preload" href="/assets/css/settings.css" as="style" onload="this.onload=null;this.rel='stylesheet'" />
<script async src="https://www.googletagmanager.com/gtag/js?id=G-WGJ2192JZY"></script><script>window.dataLayer = window.dataLayer || []; function gtag(){dataLayer.push(arguments);} gtag('js', new Date()); gtag('config', 'G-WGJ2192JZY');</script> <link rel="preload" href="/assets/css/toast.css" as="style" onload="this.onload=null;this.rel='stylesheet'" />
<script type='text/javascript' src='//pl26200262.effectiveratecpm.com/f0/e8/15/f0e81559842363ebf19aa99900ff2d02.js'></script> <link rel="preload" href="/assets/css/nprogress.css" as="style" onload="this.onload=null;this.rel='stylesheet'" />
</head> <link rel="preload" href="/assets/css/s.css" as="style" onload="this.onload=null;this.rel='stylesheet'" />
<body> <noscript>
<script src="/baremux/index.js"></script> <link rel="stylesheet" href="/assets/css/settings.css" />
<script src="/wah/uv.bundle.js" defer></script> <link rel="stylesheet" href="/assets/css/toast.css" />
<script src="/wah/cute1.js" defer></script> <link rel="stylesheet" href="/assets/css/nprogress.css" />
<script src="/assets/js/navbar.js?v=2.8.4" defer></script> <link rel="stylesheet" href="/assets/css/s.css" />
<script src="/assets/js/load.js?v=2.8.4" defer></script> </noscript>
<script src="/assets/js/eruda.js?v=2.8.4" defer></script>
<script src="/assets/js/register.js?v=2.8.5" defer></script> <link rel="preload" as="style" href="https://cdn.jsdelivr.net/gh/aquawolf04/font-awesome-pro@5cd1511/css/all.css" onload="this.onload=null;this.rel='stylesheet'" />
<script src="/assets/js/settings.js?v=2.8.5" defer></script> <noscript>
<script src="/assets/js/greetings.js?v=2.8.5" defer></script> <link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/aquawolf04/font-awesome-pro@5cd1511/css/all.css" />
<script src="/assets/js/shortcuts.js?v=2.8.4" defer></script> </noscript>
<script src="/assets/js/$.js?v=2.8.4" defer></script>
<script src="/assets/js/a.js?v=2.8.4" defer></script> <script async src="https://www.googletagmanager.com/gtag/js?id=G-WGJ2192JZY"></script>
<div class="relative flex flex-col h-[100vh] items-center justify-center bg-black transition-bg"> <script>
<div class="absolute inset-0 overflow-hidden"> window.dataLayer = window.dataLayer || [];
<div class="god-rays absolute -inset-[10px] opacity-50"></div> function gtag() {
</div> dataLayer.push(arguments);
}
gtag("js", new Date());
gtag("config", "G-WGJ2192JZY");
</script>
</head>
<body>
<script src="/baremux/index.js" defer></script>
<script src="/assets/js/nprogress.js?v=0.2.0" defer></script>
<script src="/wah/uv.bundle.js" defer></script>
<script src="/wah/cute1.js" defer></script>
<script src="/assets/js/eruda.js?v=2.8.4" defer></script>
<script src="/assets/js/register.js?v=2.8.9" defer></script>
<script src="/assets/js/settings.js?v=2.8.9" defer></script>
<script src="/assets/js/greetings.js?v=2.8.9" defer></script>
<script src="/assets/js/shortcuts.js?v=2.8.9" defer></script>
<script src="/assets/js/$.js?v=2.8.9" defer></script>
<script src="/assets/js/s.js?v=2.8.9" defer></script>
<script src="/assets/js/wv.js?v=1.4.1" defer></script>
<div class="relative flex flex-col h-[100vh] items-center justify-center bg-black transition-bg">
<div class="absolute inset-0 overflow-hidden">
<div class="god-rays absolute -inset-[10px] opacity-50"></div>
</div> </div>
<div class="home-navbar"> </div>
<img src="/assets/images/icons/favicon.ico" class="favicon">
<span id="waves">Waves.</span> <div class="home-navbar">
<a href="/" id="home">Home</a> <img src="/assets/images/icons/favicon.ico" class="favicon" alt="favicon" />
<a href="/g" id="games">Games</a> <span id="waves">Waves.</span>
<a href="/a" id="apps" style="color: #ffffff;">Apps</a> <a href="/" id="home">Home</a>
<a href="#" id="movies">Movies</a> <a href="/g" id="games">Games</a>
<a href="#" id="ai">AI</a> <a href="/s" id="shortcuts" style="color: #ffffff;">Shortcuts</a>
<a href="#" id="settings-icon"> <a href="#" id="movies">Movies</a>
<i class="settings-icon fa-regular fa-gear"></i> <a href="#" id="ai">AI</a>
</a> <a href="#" id="settings-icon">
<i class="settings-icon fa-regular fa-gear"></i>
</a>
</div>
<div id="settings-menu" class="settings-menu"></div>
<div class="navbar">
<ul class="nav-buttons">
<li><a id="backIcon" href="#"><i class="fa-regular fa-arrow-left"></i></a></li>
<li><a id="refreshIcon" href="#"><i class="fa-regular fa-rotate-right"></i></a></li>
<li><a id="forwardIcon" href="#"><i class="fa-regular fa-arrow-right"></i></a></li>
<li><a id="fullscreenIcon" href="#"><i class="fa-regular fa-expand"></i></a></li>
<li>
<div class="small-searchbar" style="position: relative;">
<i id="lockIcon" class="fa-solid fa-lock"></i>
<input class="waves" type="text" id="searchInputt" placeholder="Search for a query or enter a URL..." autocomplete="off" style="padding-left: 40px;" />
</div>
</li>
<li><a href="/"><i class="fa-regular fa-home"></i></a></li>
<li><a href="/g"><i class="fa-regular fa-gamepad"></i></a></li>
<li><a href="/s"><i class="fa-regular fa-rocket"></i></a></li>
<li><a id="erudaIcon" href="#"><i class="fa-regular fa-code"></i></a></li>
</ul>
</div>
<div class="content shortcuts-page">
<h1>Shortcuts</h1>
<div class="shortcuts-search-bar">
<input type="text" id="shortcutSearchInput" placeholder="Search shortcuts..." autocomplete="off" />
<span class="shortcut-indicator-4">Ctrl + S</span>
</div> </div>
<div id="settings-menu" class="settings-menu"></div> <div class="shortcuts-grid"></div>
<div class="navbar"> </div>
<ul class="nav-buttons">
<li><a id="backIcon" href="#"><i class="fa-regular fa-arrow-left"></i></a></li> <div id="erudaLoadingScreen" style="display: none;">Eruda is loading...</div>
<li><a id="refreshIcon" href="#"><i class="fa-regular fa-rotate-right"></i></a></li> <div id="overlay" class="overlay"></div>
<li><a id="forwardIcon" href="#"><i class="fa-regular fa-arrow-right"></i></a></li>
<li><a id="fullscreenIcon" href="#"><i class="fa-regular fa-expand"></i></a></li> <div id="namePrompt" class="popup">
<li> <div class="input-container">
<div class="small-searchbar" style="position: relative;"> <label for="userName">Please enter a name so we know what to call you:</label>
<i id="lockIcon" class="fa-solid fa-lock"></i> <div class="input-wrapper">
<input class="waves" type="text" id="searchInputt" <input type="text" id="userName" placeholder="Your name" autocomplete="off" />
placeholder="Search for a query or enter a URL..." autocomplete="off" </div>
style="padding-left: 40px;"> <button id="doneButton" onclick="submitName()" disabled><i class="fa-regular fa-check"></i> Done</button>
<span class="shortcut-indicator-2">Ctrl + S</span>
</div>
</li>
<li><a href="/"><i class="fa-regular fa-home"></i></a></li>
<li><a href="/g"><i class="fa-regular fa-gamepad"></i></a></li>
<li><a href="/a"><i class="fa-regular fa-grid-2"></i></a></li>
<li><a id="erudaIcon" href="#"><i class="fa-regular fa-code"></i></a></li>
</ul>
</div> </div>
<div class="content apps-page"> </div>
<h1>Apps</h1>
<div class="apps-search-bar"> <iframe id="cool-iframe" class="iframe"></iframe>
<input type="text" id="appSearchInput" placeholder="Search apps..." autocomplete="off" />
<span class="shortcut-indicator-4">Ctrl + S</span> <script defer>
</div> document.addEventListener("DOMContentLoaded", function () {
<div class="apps-grid"> NProgress.configure({ showSpinner: false });
</div> NProgress.start();
</div>
<div id="overlay" class="overlay"></div> const titleElement = document.querySelector(".search-title");
<div id="namePrompt" class="popup"> if (titleElement) {
<div class="input-container"> const text = titleElement.textContent.trim();
<label for="userName">Please enter a name so we know what to call you:</label> titleElement.textContent = "";
<div class="input-wrapper"> text.split("").forEach((letter, i) => {
<input type="text" id="userName" placeholder="Your name" oninput="checkInput()" autocomplete="off" /> const span = document.createElement("span");
</div> span.textContent = letter;
<button id="doneButton" onclick="submitName()" disabled> span.style.animationDelay = `${i * 0.05}s`;
<i class="fas fa-check"></i> Done titleElement.appendChild(span);
</button> });
</div> }
</div>
<div id="erudaLoadingScreen" style="display: none;">Eruda is loading...</div> window.addEventListener("load", function () {
<iframe id="cool-iframe" class="iframe"></iframe> NProgress.done();
<script type='text/javascript' src='//pl26200346.effectiveratecpm.com/08/db/84/08db842da9b43ad3d13c14634f9fd1c8.js'></script> });
<script type="text/javascript"> });
atOptions = { </script>
'key' : '26bce7e7832b24b139944832990cf69d',
'format' : 'iframe', <script>
'height' : 300, requestIdleCallback(() => {
'width' : 160, const ad = document.createElement("script");
'params' : {} ad.src = "//pl26200346.effectiveratecpm.com/08/db/84/08db842da9b43ad3d13c14634f9fd1c8.js";
}; ad.async = true;
</script> document.body.appendChild(ad);
<script type="text/javascript" src="//spaniardinformationbookworm.com/26bce7e7832b24b139944832990cf69d/invoke.js"></script> });
</body> </script>
</body>
</html> </html>

View File

@ -1,110 +1,155 @@
<!DOCTYPE html> <!DOCTYPE html>
<html lang="en"> <html lang="en">
<head> <head>
<meta charset="UTF-8" /> <meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta property="og:title" content="Waves. - Games"/> <meta property="og:title" content="Waves." />
<meta property="og:description" content="A sleek and minimalist web proxy."/> <meta property="og:description" content="A sleek and minimalist web proxy." />
<meta property="og:image" content="/assets/images/icons/favicon.ico"/> <meta property="og:image" content="/assets/images/icons/favicon.ico" />
<meta name="theme-color" content="#ffffff"/> <meta name="theme-color" content="#ffffff" />
<meta name="msapplication-TileColor" content="#ffffff"/> <meta name="msapplication-TileColor" content="#ffffff" />
<title>Waves.</title> <title>Waves.</title>
<link rel="icon" type="image/x-icon" href="/assets/images/icons/favicon.ico">
<link rel="stylesheet" href="/assets/css/$.css"> <link rel="preconnect" href="https://cdn.jsdelivr.net" crossorigin />
<link rel="stylesheet" href="/assets/css/settings.css">
<link rel="stylesheet" href="/assets/css/toast.css"> <link rel="icon" type="image/x-icon" href="/assets/images/icons/favicon.ico" />
<link rel="stylesheet" href="/assets/css/g.css">
<link href="https://cdn.jsdelivr.net/gh/aquawolf04/font-awesome-pro@5cd1511/css/all.css" rel="stylesheet" /> <link rel="stylesheet" href="/assets/css/$.css" />
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/nprogress/0.2.0/nprogress.min.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/nprogress/0.2.0/nprogress.min.js"></script> <link rel="preload" href="/assets/css/settings.css" as="style" onload="this.onload=null;this.rel='stylesheet'" />
<script async src="https://www.googletagmanager.com/gtag/js?id=G-WGJ2192JZY"></script><script>window.dataLayer = window.dataLayer || []; function gtag(){dataLayer.push(arguments);} gtag('js', new Date()); gtag('config', 'G-WGJ2192JZY');</script> <link rel="preload" href="/assets/css/toast.css" as="style" onload="this.onload=null;this.rel='stylesheet'" />
<script type='text/javascript' src='//pl26200262.effectiveratecpm.com/f0/e8/15/f0e81559842363ebf19aa99900ff2d02.js'></script> <link rel="preload" href="/assets/css/nprogress.css" as="style" onload="this.onload=null;this.rel='stylesheet'" />
</head> <link rel="preload" href="/assets/css/g.css" as="style" onload="this.onload=null;this.rel='stylesheet'" />
<body> <noscript>
<script src="/baremux/index.js"></script> <link rel="stylesheet" href="/assets/css/settings.css" />
<script src="/wah/uv.bundle.js" defer></script> <link rel="stylesheet" href="/assets/css/toast.css" />
<script src="/wah/cute1.js" defer></script> <link rel="stylesheet" href="/assets/css/nprogress.css" />
<script src="/assets/js/navbar.js?v=2.8.4" defer></script> <link rel="stylesheet" href="/assets/css/g.css" />
<script src="/assets/js/load.js?v=2.8.4" defer></script> </noscript>
<script src="/assets/js/eruda.js?v=2.8.4" defer></script>
<script src="/assets/js/register.js?v=2.8.5" defer></script> <link rel="preload" as="style" href="https://cdn.jsdelivr.net/gh/aquawolf04/font-awesome-pro@5cd1511/css/all.css" onload="this.onload=null;this.rel='stylesheet'" />
<script src="/assets/js/settings.js?v=2.8.5" defer></script> <noscript>
<script src="/assets/js/greetings.js?v=2.8.5" defer></script> <link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/aquawolf04/font-awesome-pro@5cd1511/css/all.css" />
<script src="/assets/js/shortcuts.js?v=2.8.4" defer></script> </noscript>
<script src="/assets/js/$.js?v=2.8.4" defer></script>
<script src="/assets/js/g.js?v=2.8.4" defer></script> <script async src="https://www.googletagmanager.com/gtag/js?id=G-WGJ2192JZY"></script>
<div class="relative flex flex-col h-[100vh] items-center justify-center bg-black transition-bg"> <script>
<div class="absolute inset-0 overflow-hidden"> window.dataLayer = window.dataLayer || [];
<div class="god-rays absolute -inset-[10px] opacity-50"></div> function gtag() {
</div> dataLayer.push(arguments);
}
gtag("js", new Date());
gtag("config", "G-WGJ2192JZY");
</script>
</head>
<body>
<script src="/baremux/index.js" defer></script>
<script src="/assets/js/nprogress.js?v=0.2.0" defer></script>
<script src="/wah/uv.bundle.js" defer></script>
<script src="/wah/cute1.js" defer></script>
<script src="/assets/js/eruda.js?v=2.8.4" defer></script>
<script src="/assets/js/register.js?v=2.8.9" defer></script>
<script src="/assets/js/settings.js?v=2.8.9" defer></script>
<script src="/assets/js/greetings.js?v=2.8.9" defer></script>
<script src="/assets/js/shortcuts.js?v=2.8.9" defer></script>
<script src="/assets/js/$.js?v=2.8.9" defer></script>
<script src="/assets/js/g.js?v=2.8.9" defer></script>
<script src="/assets/js/wv.js?v=1.4.1" defer></script>
<div class="relative flex flex-col h-[100vh] items-center justify-center bg-black transition-bg">
<div class="absolute inset-0 overflow-hidden">
<div class="god-rays absolute -inset-[10px] opacity-50"></div>
</div> </div>
<div class="home-navbar"> </div>
<img src="/assets/images/icons/favicon.ico" class="favicon">
<span id="waves">Waves.</span> <div class="home-navbar">
<a href="/" id="home">Home</a> <img src="/assets/images/icons/favicon.ico" class="favicon" alt="favicon" />
<a href="/g" id="games" style="color: #ffffff;">Games</a> <span id="waves">Waves.</span>
<a href="/a" id="apps">Apps</a> <a href="/" id="home">Home</a>
<a href="#" id="movies">Movies</a> <a href="/g" id="games" style="color: #ffffff;">Games</a>
<a href="#" id="ai">AI</a> <a href="/s" id="apps">Shortcuts</a>
<a href="#" id="settings-icon"> <a href="#" id="movies">Movies</a>
<i class="settings-icon fa-regular fa-gear"></i> <a href="#" id="ai">AI</a>
</a> <a href="#" id="settings-icon">
<i class="settings-icon fa-regular fa-gear"></i>
</a>
</div>
<div id="settings-menu" class="settings-menu"></div>
<div class="navbar">
<ul class="nav-buttons">
<li><a id="backIcon" href="#"><i class="fa-regular fa-arrow-left"></i></a></li>
<li><a id="refreshIcon" href="#"><i class="fa-regular fa-rotate-right"></i></a></li>
<li><a id="forwardIcon" href="#"><i class="fa-regular fa-arrow-right"></i></a></li>
<li><a id="fullscreenIcon" href="#"><i class="fa-regular fa-expand"></i></a></li>
<li>
<div class="small-searchbar" style="position: relative;">
<i id="lockIcon" class="fa-solid fa-lock"></i>
<input class="waves" type="text" id="searchInputt" placeholder="Search for a query or enter a URL..." autocomplete="off" style="padding-left: 40px;" />
</div>
</li>
<li><a href="/"><i class="fa-regular fa-home"></i></a></li>
<li><a href="/g"><i class="fa-regular fa-gamepad"></i></a></li>
<li><a href="/s"><i class="fa-regular fa-rocket"></i></a></li>
<li><a id="erudaIcon" href="#"><i class="fa-regular fa-code"></i></a></li>
</ul>
</div>
<div class="content games-page">
<h1>Games</h1>
<div class="games-search-bar">
<input type="text" id="gameSearchInput" placeholder="Search games..." autocomplete="off" />
<span class="shortcut-indicator-3">Ctrl + S</span>
</div> </div>
<div id="settings-menu" class="settings-menu"></div> <div class="games-grid"></div>
<div class="navbar"> </div>
<ul class="nav-buttons">
<li><a id="backIcon" href="#"><i class="fa-regular fa-arrow-left"></i></a></li> <div id="erudaLoadingScreen" style="display: none;">Eruda is loading...</div>
<li><a id="refreshIcon" href="#"><i class="fa-regular fa-rotate-right"></i></a></li> <div id="overlay" class="overlay"></div>
<li><a id="forwardIcon" href="#"><i class="fa-regular fa-arrow-right"></i></a></li>
<li><a id="fullscreenIcon" href="#"><i class="fa-regular fa-expand"></i></a></li> <div id="namePrompt" class="popup">
<li> <div class="input-container">
<div class="small-searchbar" style="position: relative;"> <label for="userName">Please enter a name so we know what to call you:</label>
<i id="lockIcon" class="fa-solid fa-lock"></i> <div class="input-wrapper">
<input class="waves" type="text" id="searchInputt" <input type="text" id="userName" placeholder="Your name" autocomplete="off" />
placeholder="Search for a query or enter a URL..." autocomplete="off" </div>
style="padding-left: 40px;"> <button id="doneButton" onclick="submitName()" disabled><i class="fa-regular fa-check"></i> Done</button>
<span class="shortcut-indicator-2">Ctrl + S</span>
</div>
</li>
<li><a href="/"><i class="fa-regular fa-home"></i></a></li>
<li><a href="/g"><i class="fa-regular fa-gamepad"></i></a></li>
<li><a href="/a"><i class="fa-regular fa-grid-2"></i></a></li>
<li><a id="erudaIcon" href="#"><i class="fa-regular fa-code"></i></a></li>
</ul>
</div> </div>
<div class="content games-page"> </div>
<h1>Games</h1>
<div class="games-search-bar"> <iframe id="cool-iframe" class="iframe"></iframe>
<input type="text" id="gameSearchInput" placeholder="Search games..." autocomplete="off" />
<span class="shortcut-indicator-3">Ctrl + S</span> <script defer>
</div> document.addEventListener("DOMContentLoaded", function () {
<div class="games-grid"> NProgress.configure({ showSpinner: false });
</div> NProgress.start();
</div>
<div id="overlay" class="overlay"></div> const titleElement = document.querySelector(".search-title");
<div id="namePrompt" class="popup"> if (titleElement) {
<div class="input-container"> const text = titleElement.textContent.trim();
<label for="userName">Please enter a name so we know what to call you:</label> titleElement.textContent = "";
<div class="input-wrapper"> text.split("").forEach((letter, i) => {
<input type="text" id="userName" placeholder="Your name" oninput="checkInput()" autocomplete="off" /> const span = document.createElement("span");
</div> span.textContent = letter;
<button id="doneButton" onclick="submitName()" disabled> span.style.animationDelay = `${i * 0.05}s`;
<i class="fas fa-check"></i> Done titleElement.appendChild(span);
</button> });
</div> }
</div>
<div id="erudaLoadingScreen" style="display: none;">Eruda is loading...</div> window.addEventListener("load", function () {
<iframe id="cool-iframe" class="iframe"></iframe> NProgress.done();
<script type='text/javascript' src='//pl26200346.effectiveratecpm.com/08/db/84/08db842da9b43ad3d13c14634f9fd1c8.js'></script> });
<script type="text/javascript"> });
atOptions = { </script>
'key' : '26bce7e7832b24b139944832990cf69d',
'format' : 'iframe', <script>
'height' : 300, requestIdleCallback(() => {
'width' : 160, const ad = document.createElement("script");
'params' : {} ad.src = "//pl26200346.effectiveratecpm.com/08/db/84/08db842da9b43ad3d13c14634f9fd1c8.js";
}; ad.async = true;
</script> document.body.appendChild(ad);
<script type="text/javascript" src="//spaniardinformationbookworm.com/26bce7e7832b24b139944832990cf69d/invoke.js"></script> });
</body> </script>
</body>
</html> </html>

View File

@ -1,114 +1,172 @@
<!DOCTYPE html> <!DOCTYPE html>
<html lang="en"> <html lang="en">
<head> <head>
<meta charset="UTF-8"> <meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta property="og:title" content="Waves."/> <meta property="og:title" content="Waves." />
<meta property="og:description" content="A sleek and minimalist web proxy."/> <meta property="og:description" content="A sleek and minimalist web proxy." />
<meta property="og:image" content="/assets/images/icons/favicon.ico"/> <meta property="og:image" content="/assets/images/icons/favicon.ico" />
<meta name="theme-color" content="#ffffff"/> <meta name="theme-color" content="#ffffff" />
<meta name="msapplication-TileColor" content="#ffffff"/> <meta name="msapplication-TileColor" content="#ffffff" />
<title>Waves.</title> <title>Waves.</title>
<link rel="icon" type="image/x-icon" href="/assets/images/icons/favicon.ico">
<link rel="stylesheet" href="/assets/css/$.css"> <link rel="preconnect" href="https://cdn.jsdelivr.net" crossorigin />
<link rel="stylesheet" href="/assets/css/settings.css">
<link rel="stylesheet" href="/assets/css/toast.css"> <link rel="icon" type="image/x-icon" href="/assets/images/icons/favicon.ico" />
<link href="https://cdn.jsdelivr.net/gh/aquawolf04/font-awesome-pro@5cd1511/css/all.css" rel="stylesheet">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/nprogress/0.2.0/nprogress.min.css"> <link rel="stylesheet" href="/assets/css/$.css" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/nprogress/0.2.0/nprogress.min.js"></script>
<script async src="https://www.googletagmanager.com/gtag/js?id=G-WGJ2192JZY"></script><script>window.dataLayer = window.dataLayer || []; function gtag(){dataLayer.push(arguments);} gtag('js', new Date()); gtag('config', 'G-WGJ2192JZY');</script> <link rel="preload" href="/assets/css/settings.css" as="style" onload="this.onload=null;this.rel='stylesheet'" />
<script type='text/javascript' src='//pl26200262.effectiveratecpm.com/f0/e8/15/f0e81559842363ebf19aa99900ff2d02.js'></script> <link rel="preload" href="/assets/css/toast.css" as="style" onload="this.onload=null;this.rel='stylesheet'" />
<style> <link rel="preload" href="/assets/css/nprogress.css" as="style" onload="this.onload=null;this.rel='stylesheet'" />
body { <noscript>
overflow: hidden; <link rel="stylesheet" href="/assets/css/settings.css" />
<link rel="stylesheet" href="/assets/css/toast.css" />
<link rel="stylesheet" href="/assets/css/nprogress.css" />
</noscript>
<link rel="preload" as="style" href="https://cdn.jsdelivr.net/gh/aquawolf04/font-awesome-pro@5cd1511/css/all.css" onload="this.onload=null;this.rel='stylesheet'" />
<noscript>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/aquawolf04/font-awesome-pro@5cd1511/css/all.css" />
</noscript>
<script async src="https://www.googletagmanager.com/gtag/js?id=G-WGJ2192JZY"></script>
<script>
window.dataLayer = window.dataLayer || [];
function gtag() {
dataLayer.push(arguments);
} }
</style> gtag("js", new Date());
</head> gtag("config", "G-WGJ2192JZY");
<body> </script>
<script src="/baremux/index.js"></script> </head>
<script src="/wah/uv.bundle.js" defer></script> <body>
<script src="/wah/cute1.js" defer></script> <script src="/baremux/index.js"></script>
<script src="/assets/js/navbar.js?v=2.8.4" defer></script> <script src="/assets/js/nprogress.js?v=0.2.0" defer></script>
<script src="/assets/js/load.js?v=2.8.4" defer></script> <script src="/wah/uv.bundle.js" defer></script>
<script src="/assets/js/eruda.js?v=2.8.4" defer></script> <script src="/wah/cute1.js" defer></script>
<script src="/assets/js/register.js?v=2.8.5" defer></script> <script src="/assets/js/eruda.js?v=2.8.4" defer></script>
<script src="/assets/js/settings.js?v=2.8.5" defer></script> <script src="/assets/js/register.js?v=2.8.9" defer></script>
<script src="/assets/js/ping.js?v=2.8.4" defer></script> <script src="/assets/js/settings.js?v=2.8.9" defer></script>
<script src="/assets/js/greetings.js?v=2.8.5" defer></script> <script src="/assets/js/ping.js?v=2.8.9" defer></script>
<script src="/assets/js/shortcuts.js?v=2.8.4" defer></script> <script src="/assets/js/greetings.js?v=2.8.9" defer></script>
<script src="/assets/js/$.js?v=2.8.4" defer></script> <script src="/assets/js/shortcuts.js?v=2.8.9" defer></script>
<div class="relative flex flex-col h-[100vh] items-center justify-center bg-white transition-bg"> <script src="/assets/js/$.js?v=2.8.9" defer></script>
<div class="absolute inset-0 overflow-hidden"> <script src="/assets/js/wv.js?v=1.4.1" defer></script>
<div class="god-rays absolute -inset-[10px] opacity-50"></div>
</div> <div class="relative flex flex-col h-[100vh] items-center justify-center bg-black transition-bg">
<div class="absolute inset-0 overflow-hidden">
<div class="god-rays absolute -inset-[10px] opacity-50"></div>
</div> </div>
<div class="home-navbar"> </div>
<img src="/assets/images/icons/favicon.ico" class="favicon">
<span id="waves">Waves.</span> <div class="home-navbar">
<a href="/" id="home" style="color: #ffffff;">Home</a> <img src="/assets/images/icons/favicon.ico" class="favicon" />
<a href="/g" id="games">Games</a> <span id="waves">Waves.</span>
<a href="/a" id="apps">Apps</a> <a href="/" id="home" style="color: #ffffff;">Home</a>
<a href="#" id="movies">Movies</a> <a href="/g" id="games">Games</a>
<a href="#" id="ai">AI</a> <a href="/s" id="apps">Shortcuts</a>
<a href="#" id="settings-icon"> <a href="#" id="movies">Movies</a>
<i id="settings-icon" class="settings-icon fa-regular fa-gear"></i> <a href="#" id="ai">AI</a>
</a> <a href="#" id="settings-icon"><i class="settings-icon fa-regular fa-gear"></i></a>
</div>
<div id="settings-menu" class="settings-menu"></div>
<div class="navbar">
<ul class="nav-buttons">
<li><a id="backIcon" href="#"><i class="fa-regular fa-arrow-left"></i></a></li>
<li><a id="refreshIcon" href="#"><i class="fa-regular fa-rotate-right"></i></a></li>
<li><a id="forwardIcon" href="#"><i class="fa-regular fa-arrow-right"></i></a></li>
<li><a id="fullscreenIcon" href="#"><i class="fa-regular fa-expand"></i></a></li>
<li>
<div class="small-searchbar" style="position: relative;">
<i id="lockIcon" class="fa-solid fa-lock"></i>
<input class="waves" type="text" id="searchInputt" placeholder="Search for a query or enter a URL..." autocomplete="off" style="padding-left: 40px;" />
<span class="shortcut-indicator-2">Ctrl + S</span>
</div>
</li>
<li><a href="/"><i class="fa-regular fa-home"></i></a></li>
<li><a href="/g"><i class="fa-regular fa-gamepad"></i></a></li>
<li><a href="/s"><i class="fa-regular fa-rocket"></i></a></li>
<li><a id="erudaIcon" href="#"><i class="fa-regular fa-code"></i></a></li>
</ul>
</div>
<div class="search-container">
<div class="search-title">Waves.</div>
<div class="search-bar">
<input class="waves" type="text" id="searchInput" placeholder="What's been on your mind lately?" autocomplete="off" />
<span class="shortcut-indicator">Ctrl + S</span>
</div> </div>
<div id="settings-menu" class="settings-menu"></div> </div>
<div class="navbar">
<ul class="nav-buttons"> <div id="erudaLoadingScreen" style="display: none;">Eruda is loading...</div>
<li><a id="backIcon" href="#"><i class="fa-regular fa-arrow-left"></i></a></li> <div id="overlay" class="overlay"></div>
<li><a id="refreshIcon" href="#"><i class="fa-regular fa-rotate-right"></i></a></li>
<li><a id="forwardIcon" href="#"><i class="fa-regular fa-arrow-right"></i></a></li> <div id="namePrompt" class="popup">
<li><a id="fullscreenIcon" href="#"><i class="fa-regular fa-expand"></i></a></li> <div class="input-container">
<li> <label for="userName">Please enter a name so we know what to call you:</label>
<div class="small-searchbar" style="position: relative;"> <div class="input-wrapper">
<i id="lockIcon" class="fa-solid fa-lock"></i> <input type="text" id="userName" placeholder="Your name" autocomplete="off" />
<input class="waves" type="text" id="searchInputt" </div>
placeholder="Search for a query or enter a URL..." autocomplete="off" <button id="doneButton" onclick="submitName()" disabled><i class="fa-regular fa-check"></i> Done</button>
style="padding-left: 40px;">
<span class="shortcut-indicator-2">Ctrl + S</span>
</div>
</li>
<li><a href="/"><i class="fa-regular fa-home"></i></a></li>
<li><a href="/g"><i class="fa-regular fa-gamepad"></i></a></li>
<li><a href="/a"><i class="fa-regular fa-grid-2"></i></a></li>
<li><a id="erudaIcon" href="#"><i class="fa-regular fa-code"></i></a></li>
</ul>
</div> </div>
<div class="search-container"> </div>
<div class="search-title">Waves.</div>
<div class="search-bar"> <div id="pingDisplay"><i class="fas fa-satellite-dish"></i> Ping: Connecting...</div>
<input class="waves" type="text" id="searchInput" placeholder="What's been on your mind lately?" autocomplete="off"> <div id="greeting"></div>
<span class="shortcut-indicator">Ctrl + S</span> <iframe id="cool-iframe" class="iframe"></iframe>
</div> <div id="hi">Hii,</div>
</div>
<div id="erudaLoadingScreen" style="display: none;">Eruda is loading...</div> <div id="copyright">
<div id="overlay" class="overlay"></div> <i class="fa-regular fa-copyright"></i> 2025
<div id="namePrompt" class="popup"> <a class="hover-link" href="https://discord.gg/ire" target="_blank" rel="noopener noreferrer"><span class="copyrightname">Waves Services</span></a>.
<div class="input-container"> All Rights Reserved.
<label for="userName">Please enter a name so we know what to call you:</label> </div>
<div class="input-wrapper">
<input type="text" id="userName" placeholder="Your name" autocomplete="off"> <div id="discord">
</div> <a class="hover-link" href="https://discord.gg/ire" target="_blank" rel="noopener noreferrer">
<button id="doneButton" onclick="submitName()" disabled> <i class="fa-brands fa-discord"></i> Discord
<i class="fa-regular fa-check"></i> Done </a>
</button> </div>
</div>
</div> <div id="github">
<div id="pingDisplay">Ping: Connecting...</div> <a class="hover-link" href="https://github.com/xojw/waves" target="_blank" rel="noopener noreferrer">
<div id="greeting"></div> <i class="fa-brands fa-github"></i> Github
<iframe id="cool-iframe" class="iframe"></iframe> </a>
<script type='text/javascript' src='//pl26200346.effectiveratecpm.com/08/db/84/08db842da9b43ad3d13c14634f9fd1c8.js'></script> </div>
<script type="text/javascript">
atOptions = { <script defer>
'key' : '26bce7e7832b24b139944832990cf69d', document.addEventListener("DOMContentLoaded", function () {
'format' : 'iframe', NProgress.configure({ showSpinner: false });
'height' : 300, NProgress.start();
'width' : 160,
'params' : {} const titleElement = document.querySelector(".search-title");
}; if (titleElement) {
</script> const text = titleElement.textContent.trim();
<script type="text/javascript" src="//spaniardinformationbookworm.com/26bce7e7832b24b139944832990cf69d/invoke.js"></script> titleElement.textContent = "";
</body> text.split("").forEach((letter, i) => {
const span = document.createElement("span");
span.textContent = letter;
span.style.animationDelay = `${i * 0.05}s`;
titleElement.appendChild(span);
});
}
window.addEventListener("load", function () {
NProgress.done();
});
});
</script>
<script>
requestIdleCallback(() => {
const ad = document.createElement("script");
ad.src = "//pl26200346.effectiveratecpm.com/08/db/84/08db842da9b43ad3d13c14634f9fd1c8.js";
ad.async = true;
document.body.appendChild(ad);
});
</script>
</body>
</html> </html>

View File

@ -1 +0,0 @@
google.com, pub-7835554576835583, DIRECT, f08c47fec0942fa0

View File

@ -7,6 +7,7 @@ body {
color: #e0e0e0; color: #e0e0e0;
overflow-x: hidden; overflow-x: hidden;
transition: background-color 0.3s ease; transition: background-color 0.3s ease;
animation: fadeIn 0.3s ease;
scroll-behavior: smooth; scroll-behavior: smooth;
position: relative; position: relative;
z-index: 1; z-index: 1;
@ -54,7 +55,7 @@ body {
color: #ffffff; color: #ffffff;
display: inline-block; display: inline-block;
text-align: left; text-align: left;
margin: 1px 80px 0 10px; margin: 1px 75px 0 10px;
white-space: nowrap; white-space: nowrap;
cursor: default; cursor: default;
transition: all 0.3s ease; transition: all 0.3s ease;
@ -62,7 +63,7 @@ body {
.home-navbar { .home-navbar {
transform: translateX(-50%); transform: translateX(-50%);
width: 670px; width: 700px;
top: 1%; top: 1%;
margin-bottom: -10px; margin-bottom: -10px;
margin-left: 50%; margin-left: 50%;
@ -71,7 +72,6 @@ body {
height: 35px; height: 35px;
color: #818181; color: #818181;
padding: 10px; padding: 10px;
animation: fadeIn 2s ease;
text-align: center; text-align: center;
font-size: 18px; font-size: 18px;
font-weight: bold; font-weight: bold;
@ -86,14 +86,14 @@ body {
} }
.home-navbar .favicon { .home-navbar .favicon {
width: 24px; width: 28px;
height: 24px; height: 24px;
margin-right: -10px; margin-right: -9px;
vertical-align: middle; vertical-align: middle;
} }
.home-navbar a { .home-navbar a {
color: #afafaf; color: #7c7c7c;
text-decoration: none; text-decoration: none;
padding: 8px 16px; padding: 8px 16px;
font-size: 14px; font-size: 14px;
@ -104,7 +104,8 @@ body {
} }
.home-navbar a:hover { .home-navbar a:hover {
font-size: 16px; color: #bbbbbb;
font-size: 18px;
} }
.home-navbar a:active { .home-navbar a:active {
@ -113,8 +114,8 @@ body {
.home-navbar i { .home-navbar i {
color: #ffffff; color: #ffffff;
margin-right: -15px; margin-right: -19px;
margin-left: 115px; margin-left: 119px;
} }
.navbar { .navbar {
@ -222,6 +223,26 @@ body {
color: #818181; color: #818181;
} }
.shortcut-indicator {
position: absolute;
top: 50%;
left: 50%;
transform: translate(calc(-50% + 235px), -50%);
font-size: 12px;
font-weight: 500;
color: #000000;
background-color: #c4c4c4;
padding: 2px 6px;
border-radius: 7px;
cursor: pointer;
transition: all 0.3s ease;
animation: fadeIn 0.3s ease;
}
.shortcut-indicator:hover {
background-color: #ffffff;
}
.shortcut-indicator-2 { .shortcut-indicator-2 {
position: absolute; position: absolute;
top: 50%; top: 50%;
@ -235,12 +256,20 @@ body {
border-radius: 7px; border-radius: 7px;
cursor: pointer; cursor: pointer;
transition: all 0.3s ease; transition: all 0.3s ease;
animation: fadeUp 0.3s ease;
} }
.shortcut-indicator-2:hover { .shortcut-indicator-2:hover {
background-color: #ffffff; background-color: #ffffff;
} }
.arrow-mode {
display: inline-block;
margin-left: 17px;
transition: all 0.3s ease;
animation: fadeIn 0.3s ease;
}
#lockIcon { #lockIcon {
position: absolute; position: absolute;
left: 25px; left: 25px;
@ -255,7 +284,6 @@ body {
margin-top: 20%; margin-top: 20%;
left: 50%; left: 50%;
transform: translate(-50%, -50%); transform: translate(-50%, -50%);
animation: fadeIn 2s ease;
text-align: center; text-align: center;
width: 90%; width: 90%;
} }
@ -265,25 +293,22 @@ body {
font-weight: bolder; font-weight: bolder;
text-align: center; text-align: center;
display: inline-block; display: inline-block;
background: linear-gradient(-45deg, #4e4e4e, #ffffff); background: linear-gradient(-45deg, #8d8d8d, #ffffff);
-webkit-background-clip: text; -webkit-background-clip: text;
background-clip: text; background-clip: text;
-webkit-text-fill-color: transparent; -webkit-text-fill-color: transparent;
color: transparent; color: transparent;
cursor: default; cursor: default;
transition: all 0.3s ease; transition: all 0.3s ease;
} }
.search-title span { .search-title span {
display: inline-block; display: inline-block;
background: inherit;
-webkit-background-clip: text;
background-clip: text;
-webkit-text-fill-color: transparent;
color: transparent;
opacity: 0; opacity: 0;
transform: translateX(-50px); background: inherit;
animation: fadeInFromLeft 0.5s ease-in-out forwards; color: transparent;
transform: translateY(4rem);
animation: fadeSlideIn 0.6s forwards;
} }
.search-bar { .search-bar {
@ -323,25 +348,6 @@ body {
color: #ffffff69; color: #ffffff69;
} }
.shortcut-indicator {
position: absolute;
top: 50%;
left: 50%;
transform: translate(calc(-50% + 235px), -50%);
font-size: 12px;
font-weight: 500;
color: #000000;
background-color: #c4c4c4;
padding: 2px 6px;
border-radius: 7px;
cursor: pointer;
transition: all 0.3s ease;
}
.shortcut-indicator:hover {
background-color: #ffffff;
}
#erudaLoadingScreen { #erudaLoadingScreen {
position: fixed; position: fixed;
top: 50%; top: 50%;
@ -387,13 +393,13 @@ body {
} }
.hover-link { .hover-link {
color: #949494; color: #b3b3b3;
text-decoration: none; text-decoration: none;
transition: color 0.3s ease; transition: color 0.3s ease;
} }
.hover-link:hover { .hover-link:hover {
color: #dadada; color: #ffffff;
} }
#pingDisplay { #pingDisplay {
@ -401,10 +407,9 @@ body {
margin-top: -46px; margin-top: -46px;
left: 50%; left: 50%;
transform: translate(-50%, -50%); transform: translate(-50%, -50%);
font-weight: bold; font-weight: 550;
color: #888888; color: #888888;
cursor: default; cursor: default;
animation: fadeIn 2s ease;
padding: 5px 10px; padding: 5px 10px;
transition: all 0.3s ease; transition: all 0.3s ease;
z-index: -1; z-index: -1;
@ -412,7 +417,7 @@ body {
} }
#pingDisplay:hover { #pingDisplay:hover {
color: #b6b6b6; color: #d3d3d3;
} }
.god-rays { .god-rays {
@ -426,7 +431,6 @@ body {
background-image: var(--stripes), var(--rays); background-image: var(--stripes), var(--rays);
background-size: 300%, 200%; background-size: 300%, 200%;
background-position: 50% 50%, 50% 50%; background-position: 50% 50%, 50% 50%;
animation: fadeIn 2s ease;
mask-image: radial-gradient(ellipse at 100% 0%, transparent 40%, transparent 70%); mask-image: radial-gradient(ellipse at 100% 0%, transparent 40%, transparent 70%);
-webkit-mask-image: radial-gradient(ellipse at 100% 0%, white 40%, transparent 70%); -webkit-mask-image: radial-gradient(ellipse at 100% 0%, white 40%, transparent 70%);
pointer-events: none; pointer-events: none;
@ -456,7 +460,7 @@ body {
display: none; display: none;
opacity: 0; opacity: 0;
transition: opacity 0.3s ease-in-out; transition: opacity 0.3s ease-in-out;
animation: fadeInOverlay 0.3s ease-in-out forwards; animation: fadeIn 0.3s ease-in-out forwards;
} }
#namePrompt { #namePrompt {
@ -572,7 +576,6 @@ body {
position: fixed; position: fixed;
left: 50%; left: 50%;
transform: translate(-50%, -50%); transform: translate(-50%, -50%);
animation: fadeIn 2s ease;
opacity: 0; opacity: 0;
transition: all 0.3s ease; transition: all 0.3s ease;
cursor: default; cursor: default;
@ -580,42 +583,98 @@ body {
} }
#greeting:hover { #greeting:hover {
color: #b6b6b6; color: #d3d3d3;
} }
#namePrompt.fade-out { #namePrompt.fade-out {
animation: fadeOutPrompt 0.3s ease-in-out forwards; animation: fadeOut 0.3s ease-in-out forwards;
} }
@keyframes fadeInFromLeft { #hi {
0% { position: fixed;
opacity: 0; bottom: 10px;
transform: translateX(-50px); left: 10px;
} z-index: 9999;
background-color: #08080894;
100% { border: 1px solid #ffffff21;
opacity: 1; color: #aaaaaa;
transform: translateX(0); font-weight: 540;
} transition: all 0.3s ease;
cursor: default;
padding: 8px 12px;
border-radius: 15px;
font-size: 14px;
} }
@keyframes fadeIn { #hi:hover {
from { color: #ffffff;
opacity: 0; }
}
#copyright {
position: fixed;
bottom: 10px;
left: 50%;
transform: translateX(-50%);
z-index: 9999;
background-color: #08080894;
border: 1px solid #ffffff21;
color: #858585;
font-weight: 540;
transition: all 0.3s ease;
cursor: default;
padding: 8px 12px;
border-radius: 15px;
font-size: 14px;
}
#copyright:hover {
color: #afafaf;
}
#discord {
position: fixed;
bottom: 10px;
right: 100px;
z-index: 9999;
background-color: #08080894;
border: 1px solid #ffffff21;
color: #858585;
font-weight: 540;
transition: all 0.3s ease;
cursor: default;
padding: 8px 12px;
border-radius: 15px;
font-size: 14px;
}
#github {
position: fixed;
bottom: 10px;
right: 10px;
z-index: 9999;
background-color: #08080894;
border: 1px solid #ffffff21;
color: #858585;
font-weight: 540;
transition: all 0.3s ease;
cursor: default;
padding: 8px 12px;
border-radius: 15px;
font-size: 14px;
}
.fadeIn {
animation: fadeIn 0.3s ease-in-out forwards;
}
.fadeOut {
animation: fadeOut 0.3s ease-in-out forwards;
}
@keyframes fadeSlideIn {
to { to {
opacity: 1; opacity: 1;
} transform: translateY(0);
}
@keyframes fadeInOverlay {
0% {
opacity: 0;
}
100% {
opacity: 1;
} }
} }
@ -631,7 +690,17 @@ body {
} }
} }
@keyframes fadeOutPrompt { @keyframes fadeIn {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
@keyframes fadeOut {
0% { 0% {
opacity: 1; opacity: 1;
} }
@ -651,47 +720,6 @@ body {
} }
} }
@keyframes swing {
0%,
100% {
transform: rotate(3deg);
}
50% {
transform: rotate(-3deg);
}
}
@keyframes steamLarge {
0% {
stroke-dashoffset: 13;
opacity: 0.6;
}
100% {
stroke-dashoffset: 39;
opacity: 0;
}
}
@keyframes steamSmall {
10% {
stroke-dashoffset: 9;
opacity: 0.6;
}
80% {
stroke-dashoffset: 27;
opacity: 0;
}
100% {
stroke-dashoffset: 27;
opacity: 0;
}
}
@keyframes spin { @keyframes spin {
0% { 0% {
transform: rotate(0deg); transform: rotate(0deg);

View File

@ -5,7 +5,6 @@
} }
.games-page h1 { .games-page h1 {
animation: fadeIn 2s ease;
font-size: 2.5rem; font-size: 2.5rem;
margin-bottom: 20px; margin-bottom: 20px;
color: #fff; color: #fff;
@ -82,7 +81,6 @@
margin-top: 20px; margin-top: 20px;
margin-bottom: 20px; margin-bottom: 20px;
color: #a8a8a8; color: #a8a8a8;
animation: fadeIn 2s ease;
position: relative; position: relative;
} }

View File

@ -0,0 +1 @@
#nprogress{pointer-events:none}#nprogress .bar{background:#29d;position:fixed;z-index:1031;top:0;left:0;width:100%;height:2px}#nprogress .peg{display:block;position:absolute;right:0;width:100px;height:100%;box-shadow:0 0 10px #29d,0 0 5px #29d;opacity:1;-webkit-transform:rotate(3deg) translate(0,-4px);-ms-transform:rotate(3deg) translate(0,-4px);transform:rotate(3deg) translate(0,-4px)}#nprogress .spinner{display:block;position:fixed;z-index:1031;top:15px;right:15px}#nprogress .spinner-icon{width:18px;height:18px;box-sizing:border-box;border:2px solid transparent;border-top-color:#29d;border-left-color:#29d;border-radius:50%;-webkit-animation:nprogress-spinner 400ms linear infinite;animation:nprogress-spinner 400ms linear infinite}.nprogress-custom-parent{overflow:hidden;position:relative}.nprogress-custom-parent #nprogress .bar,.nprogress-custom-parent #nprogress .spinner{position:absolute}@-webkit-keyframes nprogress-spinner{0%{-webkit-transform:rotate(0deg)}100%{-webkit-transform:rotate(360deg)}}@keyframes nprogress-spinner{0%{transform:rotate(0deg)}100%{transform:rotate(360deg)}}

View File

@ -1,17 +1,16 @@
.apps-page { .shortcuts-page {
padding: 100px 20px 40px; padding: 100px 20px 40px;
text-align: center; text-align: center;
position: relative; position: relative;
} }
.apps-page h1 { .shortcuts-page h1 {
animation: fadeIn 2s ease;
font-size: 2.5rem; font-size: 2.5rem;
margin-bottom: 20px; margin-bottom: 20px;
color: #fff; color: #fff;
} }
.apps-grid { .shortcuts-grid {
display: flex; display: flex;
flex-wrap: wrap; flex-wrap: wrap;
justify-content: center; justify-content: center;
@ -22,14 +21,14 @@
margin: 0 auto; margin: 0 auto;
} }
.content.apps-page { .content.shortcuts-page {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
align-items: center; align-items: center;
text-align: center; text-align: center;
} }
.app-card { .shortcut-card {
background-color: #08080894; background-color: #08080894;
border-radius: 25px; border-radius: 25px;
padding: 15px 20px; padding: 15px 20px;
@ -49,7 +48,7 @@
animation: fadeIn 2s ease; animation: fadeIn 2s ease;
} }
.app-card img { .shortcut-card img {
width: 100%; width: 100%;
height: 200px; height: 200px;
object-fit: cover; object-fit: cover;
@ -58,40 +57,39 @@
transition: all 0.3s ease; transition: all 0.3s ease;
} }
.app-card:hover img { .shortcut-card:hover img {
filter: brightness(1); filter: brightness(1);
} }
.app-card:hover { .shortcut-card:hover {
background-color: #333333; background-color: #333333;
} }
.app-card h2 { .shortcut-card h2 {
font-size: 1rem; font-size: 1rem;
margin: 10px 0; margin: 10px 0;
color: #fff; color: #fff;
} }
.app-card p { .shortcut-card p {
font-size: 1rem; font-size: 1rem;
color: #ccc; color: #ccc;
} }
.apps-search-bar { .shortcuts-search-bar {
text-align: center; text-align: center;
margin-top: 20px; margin-top: 20px;
margin-bottom: 20px; margin-bottom: 20px;
color: #a8a8a8; color: #a8a8a8;
animation: fadeIn 2s ease;
position: relative; position: relative;
} }
#appSearchInput { #shortcutSearchInput {
padding: 14px 30px; padding: 14px 30px;
border: 1px solid #ffffff1a; border: 1px solid #ffffff1a;
background-image: url('/assets/images/icons/search.png'); background-image: url('/assets/images/icons/search.png');
background-size: 35px 35px; background-size: 35px 35px;
background-position: 10px center; background-position: 5px center;
background-repeat: no-repeat; background-repeat: no-repeat;
padding-left: 45px; padding-left: 45px;
border-radius: 20px; border-radius: 20px;
@ -104,12 +102,12 @@
transition: all 0.3s ease; transition: all 0.3s ease;
} }
#appSearchInput:focus, #shortcutSearchInput:focus,
#appSearchInput:hover { #shortcutSearchInput:hover {
border: 1px solid #ffffff69; border: 1px solid #ffffff69;
} }
#appSearchInput::placeholder { #shortcutSearchInput::placeholder {
color: #a8a8a8; color: #a8a8a8;
} }

View File

@ -63,7 +63,7 @@
#close-settings:hover { #close-settings:hover {
transform: rotate(90deg); transform: rotate(90deg);
color: #d3d3d3; color: #ffffff;
} }
#close-settings i { #close-settings i {
@ -91,11 +91,12 @@
max-width: 300px; max-width: 300px;
margin-bottom: 15px; margin-bottom: 15px;
} }
.transport-selected { .transport-selected {
background-color: #141414; background-color: #141414;
border: 1px solid #ffffff1a;
color: #e0e0e0; color: #e0e0e0;
padding: 10px; padding: 10px;
border: 1px solid #4141411a;
border-radius: 15px; border-radius: 15px;
cursor: pointer; cursor: pointer;
display: flex; display: flex;
@ -136,8 +137,7 @@
opacity: 0; opacity: 0;
} }
.transport-options.transport-show, .transport-options.transport-show {
.server-options.transport-show {
max-height: 200px; max-height: 200px;
opacity: 1; opacity: 1;
} }
@ -159,7 +159,7 @@
margin-left: -80px; margin-left: -80px;
background-color: #141414; background-color: #141414;
color: #e0e0e0; color: #e0e0e0;
border: 1px solid #4141411a; border: 1px solid #ffffff1a;
border-radius: 15px; border-radius: 15px;
font-size: 15px; font-size: 15px;
outline: none; outline: none;

View File

@ -32,6 +32,10 @@
display: inline-block; display: inline-block;
} }
.toast i {
margin-right: 8px;
}
.toast.show { .toast.show {
animation: slideIn 0.3s forwards; animation: slideIn 0.3s forwards;
} }
@ -51,6 +55,21 @@
animation: progress 3s linear forwards; animation: progress 3s linear forwards;
} }
.toast .toast-close {
background: none;
border: none;
color: #888888;
font-size: 18px;
cursor: pointer;
padding: 0;
margin-left: 10px;
transition: 0.3s;
}
.toast-close:hover {
color: #ffffff;
}
@keyframes slideIn { @keyframes slideIn {
0% { 0% {
right: -300px; right: -300px;
@ -79,19 +98,4 @@
100% { 100% {
width: 0%; width: 0%;
} }
}
.toast .toast-close {
background: none;
border: none;
color: #888888;
font-size: 18px;
cursor: pointer;
padding: 0;
margin-left: 10px;
transition: 0.3s;
}
.toast-close:hover {
color: #d3d3d3;
} }

View File

@ -1,5 +1,5 @@
{ {
"apps": [ "shortcuts": [
{ {
"icon": "/assets/images/a/crazygames.jpg", "icon": "/assets/images/a/crazygames.jpg",
"title": "Crazy Games", "title": "Crazy Games",
@ -51,4 +51,4 @@
"link": "https://store.steampowered.com" "link": "https://store.steampowered.com"
} }
] ]
} }

View File

@ -13,7 +13,6 @@
<script> <script>
var gameLoaded = false; var gameLoaded = false;
window.addEventListener("beforeunload", function (e) { window.addEventListener("beforeunload", function (e) {
if (adsVisible || !gameLoaded || !lockedOccured) return null;
var confirmationMessage = "Are you sure you want to leave? "; var confirmationMessage = "Are you sure you want to leave? ";
(e || window.event).returnValue = confirmationMessage; //Gecko + IE (e || window.event).returnValue = confirmationMessage; //Gecko + IE
return confirmationMessage; //Gecko + Webkit, Safari, Chrome etc. return confirmationMessage; //Gecko + Webkit, Safari, Chrome etc.
@ -86,52 +85,10 @@
}, },
}); });
</script> </script>
<!-- MIDROLL/INTERSTITIAL VIDEO API -->
<script src="js/cpmstar.js"></script>
</head> </head>
<body> <body>
<div class="ads">
<div class="ad-smallscreen">
<div class="ad ad-rectangle-bottom"></div>
</div>
<div class="ad ad-rectangle-upper" id="adRectangleUpper">
<!-- 300X250B PLACEMENT TAG - PLACE INTO BODY (ZONE TAG REQUIRED) -->
<script>
(function (w, pid) {
var r = function (c, m) {
c = c.split("").reduce(function (a, b) {
return ((a << 5) - a + b.charCodeAt(0)) >>> m;
}, 0);
return (10 + ((c * 7) % 26)).toString(36) + c.toString(36);
},
y = r(w.location.href.split("#")[0], 1),
c = r(w.location.href.split("#")[0] + pid, 0);
w.document.write('<div style="width:300px;height:250px" class="' + c + '"></div>');
})(window, 83023);
</script>
</div>
<div class="ad-largescreen">
<div class="ad ad-leaderboard-bottom">
<!-- 300X600B PLACEMENT TAG - PLACE INTO BODY (ZONE TAG REQUIRED) -->
<script>
(function (w, pid) {
var r = function (c, m) {
c = c.split("").reduce(function (a, b) {
return ((a << 5) - a + b.charCodeAt(0)) >>> m;
}, 0);
return (10 + ((c * 7) % 26)).toString(36) + c.toString(36);
},
y = r(w.location.href.split("#")[0], 1),
c = r(w.location.href.split("#")[0] + pid, 0);
w.document.write('<div style="width:300px;height:600px" class="' + c + '"></div>');
})(window, 85420);
</script>
</div>
</div>
</div>
<!-- <div id="interAdsContainer" style="display: none;"></div> -->
<div id="gameContainer"></div> <div id="gameContainer"></div>
<div id="loader"> <div id="loader">
<img class="logo" src="logo.png" /> <img class="logo" src="logo.png" />
@ -222,55 +179,6 @@
var refreshNextTime = true; var refreshNextTime = true;
function showAds() {
document.getElementsByClassName("ad-rectangle-bottom")[0].style.display = "block";
document.getElementsByClassName("ad-leaderboard-bottom")[0].style.display = "block";
document.getElementById("adRectangleUpper").style.display = "block";
if (typeof counter === "undefined") {
startCounter();
resumeCounter();
} else {
resumeCounter();
refresh();
}
}
function hideAds() {
document.getElementsByClassName("ad-rectangle-bottom")[0].style.display = "none";
document.getElementsByClassName("ad-leaderboard-bottom")[0].style.display = "none";
document.getElementById("adRectangleUpper").style.display = "none";
pauseCounter();
}
// hide ads
hideAds();
function refresh() {
//console.log("time since ads refresh = " + timeSinceRefresh + " seconds");
//console.log("time ads visible = " + timeAdsVisible + " seconds");
if (timeSinceRefresh <= 30 || timeAdsVisible <= 2) {
//console.log("don't refresh");
return;
}
if (document.getElementById("adRectangleBottom") != null && window.getComputedStyle(document.getElementsByClassName("ad-smallscreen")[0]).display != "none") {
cpmstarAPI({ kind: "adcmd", module: "POOL 83023", command: "refresh" });
}
if (document.getElementById("adLeaderboardBottom") != null && window.getComputedStyle(document.getElementsByClassName("ad-largescreen")[0]).display != "none") {
cpmstarAPI({ kind: "adcmd", module: "POOL 85420", command: "refresh" });
}
cpmstarAPI({ kind: "adcmd", module: "POOL 83025", command: "refresh" });
timeSinceRefresh = 0;
timeAdsVisible = 0;
//console.log("refresh ads");
}
window.onfocus = function () { window.onfocus = function () {
//console.log("onfocus"); //console.log("onfocus");
resumeCounter(); resumeCounter();
@ -283,26 +191,16 @@
}; };
var timeSinceRefresh = 0; var timeSinceRefresh = 0;
var timeAdsVisible = 0;
var counter; var counter;
var adsVisible = false;
function startCounter() { function startCounter() {
timeSinceRefresh++; timeSinceRefresh++;
if (adsVisible) timeAdsVisible++;
counter = setTimeout(function () { counter = setTimeout(function () {
startCounter(); startCounter();
}, 1000); }, 1000);
} }
function resumeCounter() {
adsVisible = true;
}
function pauseCounter() {
adsVisible = false;
}
</script> </script>
<!-- Firebase App (the core Firebase SDK) is always required and must be listed first --> <!-- Firebase App (the core Firebase SDK) is always required and must be listed first -->
<script src="firebase/firebase-app.js"></script> <script src="firebase/firebase-app.js"></script>
@ -341,4 +239,4 @@
fixMacUserAgent(); fixMacUserAgent();
</script> </script>
</body> </body>
</html> </html>

View File

@ -1,293 +1,478 @@
document.addEventListener('DOMContentLoaded', () => { document.addEventListener('DOMContentLoaded', () => {
const historyStack = [] window.APP = {};
let currentIndex = -1
const refreshIcon = document.getElementById('refreshIcon') const iframe = document.getElementById('cool-iframe');
const fullscreenIcon = document.getElementById('fullscreenIcon') const erudaLoadingScreen = document.getElementById('erudaLoadingScreen');
const backIcon = document.getElementById('backIcon') const searchInput1 = document.getElementById('searchInput');
const forwardIcon = document.getElementById('forwardIcon') const movies = document.getElementById('movies');
const iframe = document.getElementById('cool-iframe') const ai = document.getElementById('ai');
const erudaLoadingScreen = document.getElementById('erudaLoadingScreen') const topBar = document.querySelector('.topbar');
if (!refreshIcon || !fullscreenIcon || !backIcon || !forwardIcon || !iframe) return const refreshIcon = document.getElementById('refreshIcon');
const originalTitle = document.title const fullscreenIcon = document.getElementById('fullscreenIcon');
let loadingHidden = false const backIcon = document.getElementById('backIcon');
function showLoadingScreen(withToast = true, showEruda = false) { const forwardIcon = document.getElementById('forwardIcon');
loadingHidden = false const searchInput2 = document.getElementById('searchInputt');
NProgress.start() const lockIcon = document.getElementById('lockIcon');
document.title = 'Loading... <3' const navbarToggle = document.getElementById('navbar-toggle');
if (withToast) { const navBar = document.querySelector('.navbar');
showToast(
'Consider joining our <a href="https://discord.gg/dJvdkPRheV" target="_blank" class="hover-link">Discord</a>&nbsp;<3', const historyStack = [];
'success', let currentIndex = -1;
'heart' const originalTitle = document.title;
) let isLoading = false;
}
} if (!iframe || !refreshIcon || !fullscreenIcon || !backIcon || !forwardIcon) {
function hideLoadingScreen() { return;
if (loadingHidden) return }
loadingHidden = true
NProgress.done() const animationStyle = document.createElement('style');
document.title = originalTitle animationStyle.textContent = `
} @keyframes slideLeft {0% { transform: translateX(0); } 50% { transform: translateX(-5px); } 100% { transform: translateX(0); }}
refreshIcon.addEventListener('click', () => { @keyframes slideRight {0% { transform: translateX(0); } 50% { transform: translateX(5px); } 100% { transform: translateX(0); }}
refreshIcon.classList.add('spin') .button-animate-back { animation: slideLeft 0.3s ease-in-out; }
if (iframe.tagName === 'IFRAME') { .button-animate-forward { animation: slideRight 0.3s ease-in-out; }
const currentUrl = iframe.contentWindow.location.href .spin { animation: spinAnimation 0.3s linear; }
if (normalizeUrl(currentUrl) !== normalizeUrl(historyStack[currentIndex] || '')) { @keyframes spinAnimation { 0% { transform: rotate(0deg); } 100% { transform: rotate(360deg); } }
addToHistory(currentUrl) `;
} document.head.appendChild(animationStyle);
iframe.contentWindow.location.reload(true)
} function showLoadingScreen(withToast = true) {
setTimeout(() => refreshIcon.classList.remove('spin'), 300) if (isLoading) return;
}) isLoading = true;
fullscreenIcon.addEventListener('click', () => { if (typeof NProgress !== 'undefined') NProgress.start();
if (iframe.requestFullscreen) iframe.requestFullscreen()
else if (iframe.mozRequestFullScreen) iframe.mozRequestFullScreen() if (withToast) {
else if (iframe.webkitRequestFullscreen) iframe.webkitRequestFullscreen() showToast(
else if (iframe.msRequestFullscreen) iframe.msRequestFullscreen() 'Consider joining our <a href="https://discord.gg/dJvdkPRheV" target="_blank" class="hover-link">Discord</a>&nbsp;<3',
}) 'success',
backIcon.addEventListener('click', () => { 'heart'
if (currentIndex > 0) { );
currentIndex-- }
iframe.src = historyStack[currentIndex] }
showLoadingScreen(false, false)
updateNavButtons() function hideLoadingScreen() {
updateDecodedSearchInput() if (!isLoading) return;
} if (typeof NProgress !== 'undefined') NProgress.done();
}) document.title = originalTitle;
forwardIcon.addEventListener('click', () => { isLoading = false;
if (currentIndex < historyStack.length - 1) { if (erudaLoadingScreen) erudaLoadingScreen.style.display = 'none';
currentIndex++ }
iframe.src = historyStack[currentIndex]
showLoadingScreen(false, false) function normalizeUrl(urlStr) {
updateNavButtons() if (!urlStr || urlStr === 'about:blank') return urlStr;
updateDecodedSearchInput() try {
} const url = new URL(urlStr);
}) url.searchParams.delete('ia');
function normalizeUrl(urlStr) { return url.toString();
try { } catch {
const url = new URL(urlStr) return urlStr;
url.searchParams.delete('ia') }
return url.toString() }
} catch {
return urlStr function decodeUrl(encodedUrl) {
} if (!encodedUrl) return '';
} try {
function addToHistory(url) { const prefix = (typeof __uv$config !== 'undefined' && __uv$config.prefix) ? __uv$config.prefix : '/wa/a/';
const normalized = normalizeUrl(url) const decodeFunction = (typeof __uv$config !== 'undefined' && __uv$config.decodeUrl) ? __uv$config.decodeUrl : decodeURIComponent;
if (currentIndex >= 0 && normalizeUrl(historyStack[currentIndex]) === normalized) return const urlObject = new URL(encodedUrl, window.location.origin);
if (currentIndex < historyStack.length - 1) historyStack.splice(currentIndex + 1) if (urlObject.pathname.startsWith(prefix)) {
historyStack.push(url) const encodedPart = urlObject.pathname.slice(prefix.length);
currentIndex++ return decodeFunction(encodedPart) + urlObject.search + urlObject.hash;
updateNavButtons() }
updateDecodedSearchInput() } catch {}
} try {
function updateNavButtons() { return decodeURIComponent(encodedUrl);
backIcon.disabled = currentIndex <= 0 } catch {
forwardIcon.disabled = currentIndex >= historyStack.length - 1 return encodedUrl;
backIcon.classList.toggle('disabled', currentIndex <= 0) }
forwardIcon.classList.toggle('disabled', currentIndex >= historyStack.length - 1) }
}
function updateDecodedSearchInput() { function updateNavButtons() {
const searchInput2 = document.getElementById('searchInputt') if (!backIcon || !forwardIcon) return;
if (!searchInput2) return const canGoBack = currentIndex > 0;
let url = '' const canGoForward = currentIndex < historyStack.length - 1;
if (currentIndex >= 0 && historyStack[currentIndex]) { backIcon.disabled = !canGoBack;
url = historyStack[currentIndex] forwardIcon.disabled = !canGoForward;
} else if (iframe.src) { backIcon.classList.toggle('disabled', !canGoBack);
url = iframe.src forwardIcon.classList.toggle('disabled', !canGoForward);
} }
searchInput2.value = decodeUrl(url)
const lockIcon = document.getElementById('lockIcon') function updateDecodedSearchInput() {
if (lockIcon) { if (!searchInput2) return;
lockIcon.className = decodeUrl(url).startsWith('https://') ? let currentUrl = '';
'fa-regular fa-lock' : if (currentIndex >= 0 && historyStack[currentIndex]) {
'fa-regular fa-lock-open' currentUrl = historyStack[currentIndex];
lockIcon.style.color = '' } else if (iframe.src && iframe.src !== 'about:blank') {
} currentUrl = iframe.src;
} }
iframe.addEventListener('load', () => { const decoded = decodeUrl(currentUrl);
try { searchInput2.value = decoded;
hideLoadingScreen()
} catch { if (lockIcon) {
hideLoadingScreen() const isSecure = decoded.startsWith('https://');
} finally { lockIcon.className = isSecure ? 'fa-regular fa-lock' : 'fa-regular fa-lock-open';
if (erudaLoadingScreen) erudaLoadingScreen.style.display = 'none' }
} }
})
iframe.addEventListener('error', () => { function addToHistory(url, isReplacingCurrent = false) {
hideLoadingScreen() if (!url || url === 'about:blank') return;
})
iframe.addEventListener('loadstart', () => { const normalizedNewUrl = normalizeUrl(url);
const navBar = document.querySelector('.navbar') const currentHistoryEntry = historyStack[currentIndex];
const navbarToggle = document.getElementById('navbar-toggle') const normalizedCurrentHistoryEntry = currentIndex >= 0 ? normalizeUrl(currentHistoryEntry) : null;
if (navbarToggle && navbarToggle.checked && navBar) navBar.style.display = 'block'
showLoadingScreen(false, false) if (isReplacingCurrent && currentIndex >= 0) {
}) if (normalizedCurrentHistoryEntry !== normalizedNewUrl || currentHistoryEntry !== url) {
const navBar = document.querySelector('.navbar') historyStack[currentIndex] = url;
const topBar = document.querySelector('.topbar') } else {
const searchInput1 = document.getElementById('searchInput') return;
const searchInput2 = document.getElementById('searchInputt') }
const movies = document.getElementById('movies') } else {
const ai = document.getElementById('ai') if (normalizedCurrentHistoryEntry === normalizedNewUrl && currentHistoryEntry === url) {
const navbarToggle = document.getElementById('navbar-toggle') return;
if (navbarToggle && navBar) { }
const savedNavbarState = localStorage.getItem('navbarToggled') if (currentIndex < historyStack.length - 1) {
navbarToggle.checked = savedNavbarState === null ? true : savedNavbarState === 'true' historyStack.splice(currentIndex + 1);
navBar.style.display = iframe.style.display === 'block' && navbarToggle.checked ? 'block' : 'none' }
navbarToggle.addEventListener('change', () => { historyStack.push(url);
localStorage.setItem('navbarToggled', navbarToggle.checked) currentIndex++;
navBar.style.display = iframe.style.display === 'block' && navbarToggle.checked ? 'block' : 'none' }
}) updateNavButtons();
} updateDecodedSearchInput();
iframe.style.display = 'none' }
window.addEventListener('load', hideLoadingScreen)
;[searchInput1, searchInput2].forEach(input => { function generateSubject() {
if (input) { const subjects = ['math', 'science', 'history', 'art', 'programming', 'philosophy'];
input.addEventListener('keyup', e => { const randomSubject = subjects[Math.floor(Math.random() * subjects.length)];
if (e.key === 'Enter') { try {
const val = input.value.trim() history.replaceState({}, '', `/learning?subject=${randomSubject}`);
if (val) handleSearch(val) } catch (e) {}
else showToast('Please enter something in the Search Bar.', 'error', 'warning') }
}
}) function setupIframeNavigationListeners() {
} try {
}) const iframeWindow = iframe.contentWindow;
if (movies) movies.addEventListener('click', e => { if (!iframeWindow || iframeWindow === window || iframeWindow.location.href === 'about:blank') return;
e.preventDefault()
handleSearch('https://movies.usewaves.site/') const handleNav = (isReplace = false) => {
}) setTimeout(() => {
if (ai) ai.addEventListener('click', e => { try {
e.preventDefault() const newUrlInIframe = iframeWindow.location.href;
handleSearch('https://ai.usewaves.site/') if (newUrlInIframe === 'about:blank' && historyStack[currentIndex] === 'about:blank') return;
}) addToHistory(newUrlInIframe, isReplace);
function clearBackground() { } catch (e) {}
const preserved = [ }, 0);
document.querySelector('.navbar'), };
document.getElementById('cool-iframe'),
document.querySelector('.loading-screen'), if (!iframeWindow.history.pushState.__isPatched) {
erudaLoadingScreen const originalPushState = iframeWindow.history.pushState;
] iframeWindow.history.pushState = function(...args) {
Array.from(document.body.children).forEach(child => { originalPushState.apply(this, args);
if (!preserved.includes(child)) child.remove() handleNav(false);
}) };
} iframeWindow.history.pushState.__isPatched = true;
async function handleSearch(query) { }
if (!query || !query.trim()) { if (!iframeWindow.history.replaceState.__isPatched) {
showToast('Please enter something in the Search Bar.', 'error', 'warning') const originalReplaceState = iframeWindow.history.replaceState;
return iframeWindow.history.replaceState = function(...args) {
} originalReplaceState.apply(this, args);
clearBackground() handleNav(true);
let searchURL };
if ( iframeWindow.history.replaceState.__isPatched = true;
query.startsWith('/assets/g/') || }
query.startsWith(window.location.origin + '/assets/g/')
) { iframeWindow.removeEventListener('popstate', iframeWindow.__popstateHandler);
searchURL = query iframeWindow.__popstateHandler = () => handleNav(false);
} else { iframeWindow.addEventListener('popstate', iframeWindow.__popstateHandler);
searchURL = generateSearchUrl(query)
} iframeWindow.removeEventListener('hashchange', iframeWindow.__hashchangeHandler);
if (searchInput2) searchInput2.value = searchURL iframeWindow.__hashchangeHandler = () => handleNav(false);
historyStack.length = 0 iframeWindow.addEventListener('hashchange', iframeWindow.__hashchangeHandler);
currentIndex = -1 } catch (error) {}
showLoadingScreen(true, false) }
iframe.style.display = 'block'
if (topBar) topBar.style.display = 'none' iframe.addEventListener('loadstart', () => {
backIcon.disabled = forwardIcon.disabled = true showLoadingScreen(false);
let finalUrl if (navbarToggle && navbarToggle.checked && navBar) {
try { navBar.style.display = 'block';
const u = new URL(searchURL, window.location.origin) }
if (u.origin === window.location.origin && u.pathname.startsWith('/assets/g/')) { });
finalUrl = u.href
} else { iframe.addEventListener('load', () => {
finalUrl = await getUrl(searchURL) hideLoadingScreen();
} try {
} catch { const newUrl = iframe.contentWindow ? iframe.contentWindow.location.href : iframe.src;
finalUrl = await getUrl(searchURL) if (newUrl && newUrl !== 'about:blank') {
} if (currentIndex === -1 || normalizeUrl(historyStack[currentIndex]) !== normalizeUrl(newUrl) || historyStack[currentIndex] !== newUrl) {
iframe.src = finalUrl addToHistory(newUrl);
iframe.onload = () => { } else if (historyStack[currentIndex] !== newUrl) {
hideLoadingScreen() addToHistory(newUrl, true);
if (navbarToggle && navbarToggle.checked && navBar) navBar.style.display = 'block' }
generateSubject() } else if (newUrl === 'about:blank' && historyStack.length > 0 && historyStack[currentIndex] !== 'about:blank') {
updateDecodedSearchInput() if (currentIndex > 0) {
} const previousUrl = historyStack[currentIndex - 1];
iframe.onerror = () => { currentIndex--;
hideLoadingScreen() iframe.src = previousUrl;
} return;
} }
window.handleSearch = handleSearch }
function generateSearchUrl(query) { setupIframeNavigationListeners();
try { generateSubject();
return new URL(query).toString() if (navbarToggle && navbarToggle.checked && navBar) {
} catch { navBar.style.display = 'block';
try { }
const u = new URL(`https://${query}`) } catch (error) {} finally {
if (u.hostname.includes('.')) return u.toString() updateNavButtons();
} catch {} updateDecodedSearchInput();
} }
return `https://duckduckgo.com/?q=${encodeURIComponent(query)}&ia=web` });
}
function showToast(message, type = 'success', iconType = 'check') { iframe.addEventListener('error', () => {
const toast = document.createElement('div') hideLoadingScreen();
toast.className = `toast show ${type}` showToast('Error: Could not load page content.', 'error', 'times-circle');
const icons = { updateNavButtons();
success: '<i class="fa-regular fa-check-circle" style="margin-right: 8px;"></i>', updateDecodedSearchInput();
error: '<i class="fa-regular fa-times-circle" style="margin-right: 8px;"></i>', });
info: '<i class="fa-regular fa-info-circle" style="margin-right: 8px;"></i>',
warning: '<i class="fa-regular fa-exclamation-triangle" style="margin-right: 8px;"></i>', function toggleButtonAnimation(button, animationClass) {
heart: '<i class="fa-regular fa-heart" style="margin-right: 8px;"></i>' if (button) {
} button.classList.add(animationClass);
const icon = icons[iconType] || icons.heart setTimeout(() => button.classList.remove(animationClass), 200);
toast.innerHTML = `${icon}${message} ` }
const progressBar = document.createElement('div') }
progressBar.className = 'progress-bar'
toast.appendChild(progressBar) backIcon.addEventListener('click', () => {
const closeBtn = document.createElement('button') toggleButtonAnimation(backIcon, 'button-animate-back');
closeBtn.className = 'toast-close' if (currentIndex > 0) {
closeBtn.innerHTML = '<i class="fa-solid fa-xmark" style="margin-left: 8px; font-size: 0.8em;"></i>' currentIndex--;
closeBtn.addEventListener('click', () => { showLoadingScreen(false);
toast.classList.add('hide') iframe.src = historyStack[currentIndex];
setTimeout(() => toast.remove(), 500) updateNavButtons();
}) updateDecodedSearchInput();
toast.appendChild(closeBtn) }
document.body.appendChild(toast) });
setTimeout(() => {
toast.classList.add('hide') forwardIcon.addEventListener('click', () => {
setTimeout(() => toast.remove(), 500) toggleButtonAnimation(forwardIcon, 'button-animate-forward');
}, 3000) if (currentIndex < historyStack.length - 1) {
} currentIndex++;
function preloadResources(url) { showLoadingScreen(false);
if (!url) return iframe.src = historyStack[currentIndex];
try { updateNavButtons();
const link = document.createElement('link') updateDecodedSearchInput();
link.rel = 'preload' }
link.href = url });
link.as = 'fetch'
link.crossOrigin = 'anonymous' refreshIcon.addEventListener('click', () => {
document.head.appendChild(link) if (refreshIcon) refreshIcon.classList.add('spin');
} catch {} if (iframe.contentWindow) {
} showLoadingScreen(false);
function getUrl(url) { const currentIframeUrl = iframe.contentWindow.location.href;
return Promise.resolve(__uv$config.prefix + __uv$config.encodeUrl(url)) if (normalizeUrl(currentIframeUrl) !== normalizeUrl(historyStack[currentIndex] || '')) {
} addToHistory(currentIframeUrl);
function generateSubject() { }
const subjects = ['math', 'science', 'history', 'art', 'programming', 'philosophy'] iframe.contentWindow.location.reload(true);
const random = subjects[Math.floor(Math.random() * subjects.length)] }
history.replaceState({}, '', '/learning?subject=' + random) if (refreshIcon) setTimeout(() => refreshIcon.classList.remove('spin'), 300);
} });
function decodeUrl(enc) {
try { fullscreenIcon.addEventListener('click', () => {
const o = new URL(enc, window.location.origin) if (iframe.requestFullscreen) iframe.requestFullscreen();
const p = (__uv$config && __uv$config.prefix) || '/wa/a/' else if (iframe.mozRequestFullScreen) iframe.mozRequestFullScreen();
if (o.pathname.startsWith(p)) { else if (iframe.webkitRequestFullscreen) iframe.webkitRequestFullscreen();
const part = o.pathname.slice(p.length) else if (iframe.msRequestFullscreen) iframe.msRequestFullscreen();
return (__uv$config.decodeUrl ? __uv$config.decodeUrl(part) : decodeURIComponent(part)) });
}
} catch {} function generateSearchUrl(query) {
return enc query = query.trim();
} if (!query) return `https://duckduckgo.com/?q=&ia=web`;
window.decodeUrl = decodeUrl
window.addToHistory = addToHistory if (/^[a-zA-Z]+:\/\//.test(query)) {
window.updateDecodedSearchInput = updateDecodedSearchInput try {
window.normalizeUrl = normalizeUrl new URL(query);
}) return query;
} catch (e) {}
}
if (/^(localhost|(\d{1,3}\.){3}\d{1,3})(:\d+)?(\/.*)?$/.test(query) || query.toLowerCase() === "localhost") {
if (!query.toLowerCase().startsWith("http:") && !query.toLowerCase().startsWith("https:")) {
return `http://${query}`;
}
return query;
}
try {
const urlWithHttps = new URL(`https://${query}`);
if (urlWithHttps.hostname &&
urlWithHttps.hostname.includes('.') &&
!urlWithHttps.hostname.endsWith('.') &&
urlWithHttps.hostname !== '.' &&
urlWithHttps.hostname.split('.').pop().length >= 2 &&
!/^\d+$/.test(urlWithHttps.hostname.split('.').pop())
) {
return urlWithHttps.toString();
}
} catch (e) {}
return `https://duckduckgo.com/?q=${encodeURIComponent(query)}&ia=web`;
}
async function getUrl(url) {
if (typeof __uv$config !== 'undefined' && __uv$config.encodeUrl) {
return Promise.resolve(__uv$config.prefix + __uv$config.encodeUrl(url));
}
return Promise.resolve(url);
}
function clearBackground() {
const preservedElements = [
navBar, iframe, document.querySelector('.loading-screen'),
erudaLoadingScreen, topBar
].filter(el => el != null);
Array.from(document.body.children).forEach(child => {
if (!preservedElements.includes(child) && child.tagName !== 'SCRIPT' && child.tagName !== 'STYLE' && !child.classList.contains('toast')) {
child.remove();
}
});
}
async function handleSearch(query) {
if (!query || !query.trim()) {
showToast('Please enter something in the Search Bar.', 'error', 'warning');
return;
}
clearBackground();
let searchURL = generateSearchUrl(query);
historyStack.length = 0;
currentIndex = -1;
updateNavButtons();
showLoadingScreen(true);
iframe.style.display = 'block';
if (topBar) topBar.style.display = 'flex';
if (navBar && navbarToggle && navbarToggle.checked) navBar.style.display = 'block';
let finalUrlToLoad;
if (searchURL.startsWith(window.location.origin + '/assets/g/')) {
finalUrlToLoad = searchURL;
} else if (searchURL.startsWith('/assets/g/')) {
finalUrlToLoad = new URL(searchURL, window.location.origin).href;
} else {
try {
const tempUrl = new URL(searchURL);
if (tempUrl.origin === window.location.origin && tempUrl.pathname.startsWith('/assets/g/')) {
finalUrlToLoad = tempUrl.href;
} else {
finalUrlToLoad = await getUrl(searchURL);
}
} catch (e) {
finalUrlToLoad = await getUrl(searchURL);
}
}
if (searchInput2) searchInput2.value = decodeUrl(finalUrlToLoad);
iframe.src = finalUrlToLoad;
}
window.APP.handleSearch = handleSearch;
[searchInput1, searchInput2].forEach(input => {
if (input) {
input.addEventListener('keyup', e => {
if (e.key === 'Enter') {
const queryValue = input.value.trim();
if (queryValue) {
APP.handleSearch(queryValue);
if (input === searchInput1) searchInput1.value = '';
} else {
showToast('Please enter something in the Search Bar.', 'error', 'warning');
}
}
});
if (input === searchInput2) {
input.addEventListener('focus', updateDecodedSearchInput);
}
}
});
if (movies) movies.addEventListener('click', e => {
e.preventDefault();
APP.handleSearch('https://movies.usewaves.site/');
});
if (ai) ai.addEventListener('click', e => {
e.preventDefault();
APP.handleSearch('https://ai.usewaves.site/');
});
function showToast(message, type = 'success', iconType = 'check') {
const toast = document.createElement('div');
toast.className = `toast show ${type}`;
const icons = {
'check': 'fa-regular fa-check-circle',
'times-circle': 'fa-regular fa-times-circle',
'info': 'fa-regular fa-info-circle',
'warning': 'fa-regular fa-exclamation-triangle',
'heart': 'fa-solid fa-heart'
};
toast.innerHTML = `<i class="${icons[iconType] || icons.heart}" style="margin-right: 8px;"></i>${message}`;
const progressBar = document.createElement('div');
progressBar.className = 'progress-bar';
toast.appendChild(progressBar);
const closeBtn = document.createElement('button');
closeBtn.className = 'toast-close';
closeBtn.innerHTML = '<i class="fa-solid fa-xmark" style="margin-left: 8px; font-size: 0.8em;"></i>';
closeBtn.onclick = () => {
toast.classList.add('hide');
setTimeout(() => toast.remove(), 500);
};
toast.appendChild(closeBtn);
document.body.appendChild(toast);
setTimeout(() => {
toast.classList.add('hide');
setTimeout(() => toast.remove(), 500);
}, 3000);
}
if (navbarToggle && navBar && iframe) {
const savedNavbarState = localStorage.getItem('navbarToggled');
navbarToggle.checked = savedNavbarState !== 'false';
const updateNavbarDisplayBasedOnToggle = () => {
if (iframe.style.display === 'block') {
navBar.style.display = navbarToggle.checked ? 'block' : 'none';
} else {
navBar.style.display = 'none';
}
};
updateNavbarDisplayBasedOnToggle();
navbarToggle.addEventListener('change', () => {
localStorage.setItem('navbarToggled', navbarToggle.checked.toString());
updateNavbarDisplayBasedOnToggle();
});
window.APP.updateNavbarDisplay = updateNavbarDisplayBasedOnToggle;
}
window.addEventListener('load', () => {
let iframeInitiallyHidden = true;
if (iframe.src && iframe.src !== 'about:blank') {
iframeInitiallyHidden = false;
}
if (iframeInitiallyHidden) {
hideLoadingScreen();
if (topBar) topBar.style.display = 'flex';
iframe.style.display = 'none';
} else {
if (topBar) topBar.style.display = 'flex';
iframe.style.display = 'block';
}
if (window.APP.updateNavbarDisplay) window.APP.updateNavbarDisplay();
updateNavButtons();
updateDecodedSearchInput();
});
window.APP.decodeUrl = decodeUrl;
window.APP.normalizeUrl = normalizeUrl;
});

View File

@ -1,45 +0,0 @@
document.addEventListener('DOMContentLoaded', function() {
const searchInput = document.getElementById('appSearchInput');
const grid = document.querySelector('.apps-grid');
let appsData = [];
fetch('/assets/data/a.json')
.then(response => response.json())
.then(data => {
appsData = data.apps;
searchInput.placeholder = `Search through ${appsData.length} Apps…`;
displayApps(appsData);
searchInput.addEventListener('input', function() {
const query = searchInput.value.toLowerCase();
const filteredApps = appsData.filter(app => {
const title = app.title ? app.title.toLowerCase() : '';
const description = app.description ? app.description.toLowerCase() : '';
return title.includes(query) || description.includes(query);
});
displayApps(filteredApps);
});
})
.catch(err => console.error('Error loading apps data:', err));
function displayApps(apps) {
grid.innerHTML = '';
if (apps.length === 0) {
grid.innerHTML = '<p>Zero apps were found matching your search :(</p>';
}
apps.forEach(app => {
const card = document.createElement('div');
card.classList.add('app-card');
card.innerHTML = `
<img src="${app.icon}" alt="${app.title} Icon" />
<h2>${app.title}</h2>
`;
card.addEventListener('click', function() {
window.handleSearch(app.link);
});
grid.appendChild(card);
});
}
});

View File

@ -1,98 +1,69 @@
document.addEventListener('DOMContentLoaded', () => { document.addEventListener('DOMContentLoaded', function() {
const searchInput = document.getElementById('gameSearchInput'); const searchInput = document.getElementById('gameSearchInput');
const grid = document.querySelector('.games-grid'); const grid = document.querySelector('.games-grid');
let gamesData = [];
let filteredData = [];
const BATCH_SIZE = 50;
let renderedCount = 0;
const sentinel = document.createElement('div'); const sentinel = document.createElement('div');
sentinel.className = 'sentinel'; let allGames = [];
grid.after(sentinel); let filteredGames = [];
let renderedCount = 0;
const BATCH_SIZE = 20;
const observer = new IntersectionObserver(entries => { const observer = new IntersectionObserver(entries => {
entries.forEach(entry => { if (entries[0].isIntersecting) loadNextBatch();
if (entry.isIntersecting) { }, { rootMargin: '500px' });
renderNextBatch();
}
});
}, { rootMargin: '200px', threshold: 0.1 });
function debounce(fn, wait = 200) {
let t;
return (...args) => {
clearTimeout(t);
t = setTimeout(() => fn.apply(this, args), wait);
};
}
fetch('/assets/data/g.json') fetch('/assets/data/g.json')
.then(r => r.json()) .then(res => res.json())
.then(data => { .then(data => {
gamesData = data; allGames = data;
filteredData = data; filteredGames = data;
searchInput.placeholder = `Search through ${data.length} Games…`; searchInput.placeholder = `Search through ${allGames.length} Games…`;
grid.parentNode.appendChild(sentinel);
observer.observe(sentinel); observer.observe(sentinel);
renderNextBatch(); resetAndRender();
searchInput.addEventListener('input', debounce(() => {
const q = searchInput.value.trim().toLowerCase();
filteredData = gamesData.filter(g =>
(g.name || '').toLowerCase().includes(q)
);
resetRendering();
}, 250));
}) })
.catch(console.error); .catch(err => console.error(err));
function resetRendering() { searchInput.addEventListener('input', function() {
const q = this.value.toLowerCase();
filteredGames = allGames.filter(game =>
(game.name || '').toLowerCase().includes(q)
);
resetAndRender();
});
function resetAndRender() {
grid.innerHTML = ''; grid.innerHTML = '';
renderedCount = 0; renderedCount = 0;
observer.observe(sentinel); if (filteredGames.length === 0) {
renderNextBatch(); grid.innerHTML = '<p>Zero games were found matching your search :(</p>';
}
function renderNextBatch() {
const batch = filteredData.slice(renderedCount, renderedCount + BATCH_SIZE);
if (!batch.length) {
observer.unobserve(sentinel); observer.unobserve(sentinel);
return; return;
} }
observer.observe(sentinel);
loadNextBatch();
}
const frag = document.createDocumentFragment(); function loadNextBatch() {
batch.forEach(game => { const nextCount = Math.min(renderedCount + BATCH_SIZE, filteredGames.length);
for (let i = renderedCount; i < nextCount; i++) {
const game = filteredGames[i];
const card = document.createElement('div'); const card = document.createElement('div');
card.className = 'game-card'; card.classList.add('game-card');
card.innerHTML = ` card.innerHTML = `
<img <img src="/assets/g/${game.directory}/${game.image}" alt="${game.name} Icon" />
loading="lazy"
src="/assets/g/${game.directory}/${game.image}"
alt="${game.name} Icon"
/>
<h2>${game.name}</h2> <h2>${game.name}</h2>
`; `;
card.addEventListener('click', () => { card.addEventListener('click', () => {
window.handleSearch(`/assets/g/${game.directory}`); const gameUrl = window.location.origin + `/assets/g/${game.directory}`;
APP.handleSearch(gameUrl);
}); });
frag.appendChild(card); grid.appendChild(card);
}); }
renderedCount = nextCount;
grid.appendChild(frag); if (renderedCount >= filteredGames.length) {
renderedCount += batch.length;
preloadNextImages(5);
if (renderedCount >= filteredData.length) {
observer.unobserve(sentinel); observer.unobserve(sentinel);
} else {
grid.parentNode.appendChild(sentinel);
} }
} }
function preloadNextImages(limit = 3) {
const next = filteredData.slice(renderedCount, renderedCount + limit);
next.forEach(({ directory, image }) => {
const img = new Image();
img.src = `/assets/g/${directory}/${image}`;
});
}
}); });

View File

@ -1,6 +1,7 @@
window.onload = function() { window.onload = function() {
const storedName = localStorage.getItem('userName'); const storedName = localStorage.getItem('userName');
const path = window.location.pathname; const path = window.location.pathname;
if (!storedName) { if (!storedName) {
document.getElementById('overlay').style.display = 'block'; document.getElementById('overlay').style.display = 'block';
document.getElementById('namePrompt').style.display = 'block'; document.getElementById('namePrompt').style.display = 'block';
@ -12,24 +13,29 @@ window.onload = function() {
}); });
return; return;
} }
const welcomeMsg = getWelcomeMessage(storedName); const welcomeMsg = getWelcomeMessage(storedName);
const iconType = getIconType(path); const iconType = getIconType(path);
showToast(welcomeMsg, 'success', iconType); showToast(welcomeMsg, 'success', iconType);
const greetingElement = document.getElementById('greeting'); const greetingElement = document.getElementById('greeting');
if (greetingElement) { if (greetingElement) {
updateGreeting(storedName); updateGreeting(storedName);
} }
updateHi(storedName);
}; };
function submitName() { function submitName() {
const name = document.getElementById('userName').value.trim(); const name = document.getElementById('userName').value.trim();
if (!name) return; if (!name) return;
localStorage.setItem('userName', name); localStorage.setItem('userName', name);
updateGreeting(name); updateGreeting(name);
updateHi(name);
document.getElementById('namePrompt').classList.add('fade-out'); document.getElementById('namePrompt').classList.add('fade-out');
showToast(`Hey, ${name}! Welcome to Waves!`, 'success', 'wave'); showToast(`Hey, ${name}! Welcome to Waves!`, 'success', 'wave');
const path = window.location.pathname;
setTimeout(() => { setTimeout(() => {
document.getElementById('namePrompt').style.display = 'none'; document.getElementById('namePrompt').style.display = 'none';
document.getElementById('overlay').style.display = 'none'; document.getElementById('overlay').style.display = 'none';
@ -40,8 +46,8 @@ function getWelcomeMessage(name) {
const path = window.location.pathname; const path = window.location.pathname;
if (path === '/g') { if (path === '/g') {
return `Have fun playing games, ${name}!`; return `Have fun playing games, ${name}!`;
} else if (path === '/a') { } else if (path === '/s') {
return `Enjoy our collection of apps, ${name}!`; return `Enjoy our collection of, ${name}!`;
} else { } else {
return `Welcome back, ${name}!`; return `Welcome back, ${name}!`;
} }
@ -49,21 +55,79 @@ function getWelcomeMessage(name) {
function getIconType(path) { function getIconType(path) {
if (path === '/g') return 'game'; if (path === '/g') return 'game';
if (path === '/a') return 'apps'; if (path === '/s') return 'shortcuts';
return 'wave'; return 'wave';
} }
function updateGreeting(name) { const generalGreetings = [
const { text, icon } = getGreeting(); { text: 'Have fun', icon: '<i class="fa-regular fa-party-horn"></i>', suffix: '!' },
{ text: 'Hope you enjoy Waves', icon: '<i class="fa-solid fa-heart"></i>', suffix: ' <3' },
{ text: 'Consider joining our Discord (discord.gg/ire)', icon: '<i class="fa-solid fa-smile"></i>', suffix: '!' },
{ text: 'How you doing today', icon: '<i class="fa-regular fa-question"></i>', suffix: '?' }
];
const timeGreetings = [];
timeGreetings.push(
{ text: 'Good morning, sunshine', icon: '<i class="fa-regular fa-sun"></i>', suffix: ' :D' },
{ text: 'Heres to a bright morning', icon: '<i class="fa-regular fa-cloud-sun"></i>', suffix: '.' },
{ text: 'Enjoy your morning', icon: '<i class="fa-regular fa-mug-hot"></i>', suffix: '!' },
{ text: 'Your day starts here', icon: '<i class="fa-regular fa-star"></i>', suffix: '!' }
);
timeGreetings.push(
{ text: 'Good afternoon', icon: '<i class="fa-regular fa-leaf"></i>', suffix: '!' },
{ text: 'Hope your day is going well', icon: '<i class="fa-regular fa-coffee"></i>', suffix: '.' },
{ text: 'Keep up the pace', icon: '<i class="fa-regular fa-book"></i>', suffix: '!' },
{ text: 'Stay on track today', icon: '<i class="fa-regular fa-sun"></i>', suffix: '.' }
);
timeGreetings.push(
{ text: 'Good evening', icon: '<i class="fa-regular fa-cloud-moon"></i>', suffix: '!' },
{ text: 'Time to unwind', icon: '<i class="fa-regular fa-fire"></i>', suffix: '.' },
{ text: 'Evenings here—relax', icon: '<i class="fa-regular fa-star"></i>', suffix: '.' },
{ text: 'Breathe and recharge', icon: '<i class="fa-regular fa-moon"></i>', suffix: '…' }
);
timeGreetings.push(
{ text: 'Good night', icon: '<i class="fa-regular fa-bed"></i>', suffix: '!' },
{ text: 'Rest well', icon: '<i class="fa-regular fa-blanket"></i>', suffix: '.' },
{ text: 'Sweet dreams', icon: '<i class="fa-regular fa-star-and-crescent"></i>', suffix: '!' },
{ text: 'See you tomorrow', icon: '<i class="fa-regular fa-moon"></i>', suffix: '!' }
);
function getGreeting() {
const now = new Date();
const hour = now.getHours();
let pool = [];
if (hour >= 5 && hour < 12) {
pool = timeGreetings.slice(0, 4);
} else if (hour < 17) {
pool = timeGreetings.slice(4, 8);
} else if (hour < 21) {
pool = timeGreetings.slice(8, 12);
} else {
pool = timeGreetings.slice(12, 16);
}
if (Math.random() < 0.5) {
pool = generalGreetings;
}
return pool[Math.floor(Math.random() * pool.length)];
}
function updateGreeting(name) {
const { text, icon, suffix } = getGreeting();
const el = document.getElementById('greeting'); const el = document.getElementById('greeting');
if (el) { if (!el) return;
if (text === 'Hope you enjoy Waves') {
el.innerHTML = `${icon} ${text}, ${name} <3`; el.innerHTML = `${icon} ${text}, ${name}${suffix}`;
} else { el.style.opacity = 1;
el.innerHTML = `${icon} ${text}, ${name}!`; }
}
el.style.opacity = 1; function updateHi(name) {
const hiEl = document.getElementById('hi');
if (hiEl) {
hiEl.textContent = `Hii, ${name}!!`;
} }
} }
@ -78,7 +142,7 @@ function showToast(message, type = 'success', iconType = 'wave') {
warning: '<i class="fas fa-exclamation-triangle" style="margin-right: 8px;"></i>', warning: '<i class="fas fa-exclamation-triangle" style="margin-right: 8px;"></i>',
wave: '<i class="fa-regular fa-hand-wave" style="margin-right: 8px;"></i>', wave: '<i class="fa-regular fa-hand-wave" style="margin-right: 8px;"></i>',
game: '<i class="fa-regular fa-gamepad" style="margin-right: 8px;"></i>', game: '<i class="fa-regular fa-gamepad" style="margin-right: 8px;"></i>',
apps: '<i class="fa-regular fa-th" style="margin-right: 8px;"></i>', apps: '<i class="fa-regular fa-th" style="margin-right: 8px;"></i>'
}; };
toast.innerHTML = `${icons[iconType] || icons.wave}${message}`; toast.innerHTML = `${icons[iconType] || icons.wave}${message}`;
@ -97,59 +161,9 @@ function showToast(message, type = 'success', iconType = 'wave') {
toast.appendChild(closeBtn); toast.appendChild(closeBtn);
document.body.appendChild(toast); document.body.appendChild(toast);
setTimeout(() => { setTimeout(() => {
toast.classList.add('hide'); toast.classList.add('hide');
setTimeout(() => toast.remove(), 500); setTimeout(() => toast.remove(), 500);
}, 3000); }, 3000);
}
function getGreeting() {
const now = new Date();
const hour = now.getHours();
const timeGreetings = [];
const generalGreetings = [
{ text: 'Welcome aboard', icon: '<i class="fa-regular fa-rocket"></i>' },
{ text: 'Lets do something great', icon: '<i class="fa-regular fa-lightbulb"></i>' },
{ text: 'Hope you enjoy Waves', icon: '<i class="fa-regular fa-heart"></i>' },
{ text: 'Time to explore', icon: '<i class="fa-regular fa-compass"></i>' },
{ text: 'Lets roll', icon: '<i class="fa-regular fa-tire"></i>' },
{ text: 'Another great visit', icon: '<i class="fa-regular fa-thumbs-up"></i>' },
{ text: 'The adventure continues', icon: '<i class="fa-regular fa-map"></i>' }
];
if (hour >= 5 && hour < 12) {
timeGreetings.push(
{ text: 'Good morning, sunshine', icon: '<i class="fa-regular fa-sun"></i>' },
{ text: 'Heres to a bright morning', icon: '<i class="fa-regular fa-cloud-sun"></i>' },
{ text: 'Enjoy your morning', icon: '<i class="fa-regular fa-mug-hot"></i>' },
{ text: 'Your day starts here', icon: '<i class="fa-regular fa-star"></i>' }
);
} else if (hour < 17) {
timeGreetings.push(
{ text: 'Good afternoon', icon: '<i class="fa-regular fa-leaf"></i>' },
{ text: 'Hope your day is going well', icon: '<i class="fa-regular fa-coffee"></i>' },
{ text: 'Keep up the pace', icon: '<i class="fa-regular fa-book"></i>' },
{ text: 'Stay on track today', icon: '<i class="fa-regular fa-sun"></i>' }
);
} else if (hour < 21) {
timeGreetings.push(
{ text: 'Good evening', icon: '<i class="fa-regular fa-cloud-moon"></i>' },
{ text: 'Time to unwind', icon: '<i class="fa-regular fa-fire"></i>' },
{ text: 'Evenings here—relax', icon: '<i class="fa-regular fa-star"></i>' },
{ text: 'Breathe and recharge', icon: '<i class="fa-regular fa-moon"></i>' }
);
} else {
timeGreetings.push(
{ text: 'Good night', icon: '<i class="fa-regular fa-bed"></i>' },
{ text: 'Rest well', icon: '<i class="fa-regular fa-blanket"></i>' },
{ text: 'Sweet dreams', icon: '<i class="fa-regular fa-star-and-crescent"></i>' },
{ text: 'See you tomorrow', icon: '<i class="fa-regular fa-moon"></i>' }
);
}
const useGeneral = Math.random() < 0.5;
const pool = useGeneral ? generalGreetings : timeGreetings;
return pool[Math.floor(Math.random() * pool.length)];
} }

View File

@ -1,21 +0,0 @@
document.addEventListener('DOMContentLoaded', function () {
NProgress.configure({ showSpinner: false });
NProgress.start();
});
window.addEventListener('load', function () {
NProgress.done();
});
const titleElement = document.querySelector('.search-title');
if (titleElement) {
const text = titleElement.textContent;
titleElement.innerHTML = '';
text.split('').forEach((letter, index) => {
const span = document.createElement('span');
span.textContent = letter;
span.style.animationDelay = `${index * 0.2}s`;
titleElement.appendChild(span);
});
}

View File

@ -1,183 +0,0 @@
const style = document.createElement('style');
style.textContent = `
@keyframes slideLeft {0% { transform: translateX(0); } 50% { transform: translateX(-5px); } 100% { transform: translateX(0); }}
@keyframes slideRight {0% { transform: translateX(0); } 50% { transform: translateX(5px); } 100% { transform: translateX(0); }}
.button-animate-back { animation: slideLeft 0.3s ease-in-out; }
.button-animate-forward { animation: slideRight 0.3s ease-in-out; }
`;
document.head.appendChild(style);
const historyStack = [];
let currentIndex = -1;
const elements = {
refreshIcon: document.getElementById('refreshIcon'),
fullscreenIcon: document.getElementById('fullscreenIcon'),
backIcon: document.getElementById('backIcon'),
forwardIcon: document.getElementById('forwardIcon'),
searchInput2: document.getElementById('searchInputt'),
iframe: document.getElementById('cool-iframe')
};
const originalTitle = document.title;
let loadingFallbackTimeout;
elements.refreshIcon.addEventListener('click', handleRefresh);
elements.fullscreenIcon.addEventListener('click', handleFullscreen);
elements.backIcon.addEventListener('click', handleBack);
elements.forwardIcon.addEventListener('click', handleForward);
function showLoadingScreen() {
if (typeof NProgress !== 'undefined') {
NProgress.start();
document.title = 'Loading... <3';
setTimeout(() => {
if (typeof NProgress !== 'undefined') NProgress.done();
}, 10000);
}
}
function hideLoadingScreen() {
if (typeof NProgress !== 'undefined') NProgress.done();
document.title = originalTitle;
}
function handleRefresh() {
elements.refreshIcon.classList.add('spin');
const iframe = elements.iframe;
const currentUrl = iframe.contentWindow.location.href;
if (normalizeUrl(currentUrl) !== normalizeUrl(historyStack[currentIndex] || '')) {
addToHistory(currentUrl);
}
iframe.contentWindow.location.reload(true);
setTimeout(() => elements.refreshIcon.classList.remove('spin'), 300);
}
function handleFullscreen() {
const iframe = elements.iframe;
if (iframe && iframe.tagName === 'IFRAME') iframe.requestFullscreen();
}
function handleBack() {
toggleButtonAnimation(elements.backIcon, 'button-animate-back');
if (currentIndex > 0) {
currentIndex--;
updateIframeSrc();
}
}
function handleForward() {
toggleButtonAnimation(elements.forwardIcon, 'button-animate-forward');
if (currentIndex < historyStack.length - 1) {
currentIndex++;
updateIframeSrc();
}
}
function toggleButtonAnimation(button, animationClass) {
button.classList.add(animationClass);
setTimeout(() => button.classList.remove(animationClass), 200);
}
function normalizeUrl(urlStr) {
try {
const url = new URL(urlStr);
url.searchParams.delete('ia');
return url.toString();
} catch (e) {
return urlStr;
}
}
function addToHistory(url) {
const normalized = normalizeUrl(url);
if (currentIndex >= 0 && normalizeUrl(historyStack[currentIndex]) === normalized) return;
if (currentIndex < historyStack.length - 1) historyStack.splice(currentIndex + 1);
historyStack.push(url);
currentIndex++;
updateNavButtons();
updateDecodedSearchInput();
}
function updateIframeSrc() {
showLoadingScreen();
elements.iframe.src = historyStack[currentIndex];
updateNavButtons();
updateDecodedSearchInput();
}
function updateNavButtons() {
const isAtStart = currentIndex <= 0;
const isAtEnd = currentIndex >= historyStack.length - 1;
elements.backIcon.disabled = isAtStart;
elements.forwardIcon.disabled = isAtEnd;
elements.backIcon.classList.toggle('disabled', isAtStart);
elements.forwardIcon.classList.toggle('disabled', isAtEnd);
}
function updateDecodedSearchInput() {
if (elements.searchInput2) {
const url = historyStack[currentIndex] || elements.iframe.src;
elements.searchInput2.value = decodeUrl(url);
}
}
function decodeUrl(url) {
try {
return decodeURIComponent(url);
} catch (e) {
return url;
}
}
window.addToHistory = addToHistory;
window.updateDecodedSearchInput = updateDecodedSearchInput;
window.normalizeUrl = normalizeUrl;
function detectIframeNavigation() {
try {
const iframeWindow = elements.iframe.contentWindow;
const pushState = iframeWindow.history.pushState;
const replaceState = iframeWindow.history.replaceState;
iframeWindow.history.pushState = function() {
pushState.apply(this, arguments);
handleIframeNavigation(iframeWindow.location.href);
};
iframeWindow.history.replaceState = function() {
replaceState.apply(this, arguments);
handleIframeNavigation(iframeWindow.location.href);
};
iframeWindow.addEventListener('popstate', () => handleIframeNavigation(iframeWindow.location.href));
iframeWindow.addEventListener('hashchange', () => handleIframeNavigation(iframeWindow.location.href));
} catch (error) {}
}
function handleIframeNavigation(rawUrl) {
let urlStr = rawUrl;
try {
urlStr = decodeUrl(rawUrl);
} catch {}
try {
const u = new URL(urlStr);
if (u.hostname.endsWith('duckduckgo.com')) {
if (typeof NProgress !== 'undefined') NProgress.done();
return;
}
} catch (e) {}
if (normalizeUrl(urlStr) !== normalizeUrl(historyStack[currentIndex] || '')) {
showLoadingScreen();
addToHistory(urlStr);
} else {
hideLoadingScreen();
}
}
elements.iframe.addEventListener('load', () => {
try {
detectIframeNavigation();
if (historyStack.length === 0) {
addToHistory(elements.iframe.contentWindow.location.href);
} else {
handleIframeNavigation(elements.iframe.contentWindow.location.href);
}
} catch (error) {}
hideLoadingScreen();
});

View File

@ -0,0 +1 @@
!function(n,e){"function"==typeof define&&define.amd?define(e):"object"==typeof exports?module.exports=e():n.NProgress=e()}(this,function(){function n(n,e,t){return e>n?e:n>t?t:n}function e(n){return 100*(-1+n)}function t(n,t,r){var i;return i="translate3d"===c.positionUsing?{transform:"translate3d("+e(n)+"%,0,0)"}:"translate"===c.positionUsing?{transform:"translate("+e(n)+"%,0)"}:{"margin-left":e(n)+"%"},i.transition="all "+t+"ms "+r,i}function r(n,e){var t="string"==typeof n?n:o(n);return t.indexOf(" "+e+" ")>=0}function i(n,e){var t=o(n),i=t+e;r(t,e)||(n.className=i.substring(1))}function s(n,e){var t,i=o(n);r(n,e)&&(t=i.replace(" "+e+" "," "),n.className=t.substring(1,t.length-1))}function o(n){return(" "+(n.className||"")+" ").replace(/\s+/gi," ")}function a(n){n&&n.parentNode&&n.parentNode.removeChild(n)}var u={};u.version="0.2.0";var c=u.settings={minimum:.08,easing:"ease",positionUsing:"",speed:200,trickle:!0,trickleRate:.02,trickleSpeed:800,showSpinner:!0,barSelector:'[role="bar"]',spinnerSelector:'[role="spinner"]',parent:"body",template:'<div class="bar" role="bar"><div class="peg"></div></div><div class="spinner" role="spinner"><div class="spinner-icon"></div></div>'};u.configure=function(n){var e,t;for(e in n)t=n[e],void 0!==t&&n.hasOwnProperty(e)&&(c[e]=t);return this},u.status=null,u.set=function(e){var r=u.isStarted();e=n(e,c.minimum,1),u.status=1===e?null:e;var i=u.render(!r),s=i.querySelector(c.barSelector),o=c.speed,a=c.easing;return i.offsetWidth,l(function(n){""===c.positionUsing&&(c.positionUsing=u.getPositioningCSS()),f(s,t(e,o,a)),1===e?(f(i,{transition:"none",opacity:1}),i.offsetWidth,setTimeout(function(){f(i,{transition:"all "+o+"ms linear",opacity:0}),setTimeout(function(){u.remove(),n()},o)},o)):setTimeout(n,o)}),this},u.isStarted=function(){return"number"==typeof u.status},u.start=function(){u.status||u.set(0);var n=function(){setTimeout(function(){u.status&&(u.trickle(),n())},c.trickleSpeed)};return c.trickle&&n(),this},u.done=function(n){return n||u.status?u.inc(.3+.5*Math.random()).set(1):this},u.inc=function(e){var t=u.status;return t?("number"!=typeof e&&(e=(1-t)*n(Math.random()*t,.1,.95)),t=n(t+e,0,.994),u.set(t)):u.start()},u.trickle=function(){return u.inc(Math.random()*c.trickleRate)},function(){var n=0,e=0;u.promise=function(t){return t&&"resolved"!==t.state()?(0===e&&u.start(),n++,e++,t.always(function(){e--,0===e?(n=0,u.done()):u.set((n-e)/n)}),this):this}}(),u.render=function(n){if(u.isRendered())return document.getElementById("nprogress");i(document.documentElement,"nprogress-busy");var t=document.createElement("div");t.id="nprogress",t.innerHTML=c.template;var r,s=t.querySelector(c.barSelector),o=n?"-100":e(u.status||0),l=document.querySelector(c.parent);return f(s,{transition:"all 0 linear",transform:"translate3d("+o+"%,0,0)"}),c.showSpinner||(r=t.querySelector(c.spinnerSelector),r&&a(r)),l!=document.body&&i(l,"nprogress-custom-parent"),l.appendChild(t),t},u.remove=function(){s(document.documentElement,"nprogress-busy"),s(document.querySelector(c.parent),"nprogress-custom-parent");var n=document.getElementById("nprogress");n&&a(n)},u.isRendered=function(){return!!document.getElementById("nprogress")},u.getPositioningCSS=function(){var n=document.body.style,e="WebkitTransform"in n?"Webkit":"MozTransform"in n?"Moz":"msTransform"in n?"ms":"OTransform"in n?"O":"";return e+"Perspective"in n?"translate3d":e+"Transform"in n?"translate":"margin"};var l=function(){function n(){var t=e.shift();t&&t(n)}var e=[];return function(t){e.push(t),1==e.length&&n()}}(),f=function(){function n(n){return n.replace(/^-ms-/,"ms-").replace(/-([\da-z])/gi,function(n,e){return e.toUpperCase()})}function e(n){var e=document.body.style;if(n in e)return n;for(var t,r=i.length,s=n.charAt(0).toUpperCase()+n.slice(1);r--;)if(t=i[r]+s,t in e)return t;return n}function t(t){return t=n(t),s[t]||(s[t]=e(t))}function r(n,e,r){e=t(e),n.style[e]=r}var i=["Webkit","O","Moz","ms"],s={};return function(n,e){var t,i,s=arguments;if(2==s.length)for(t in e)i=e[t],void 0!==i&&e.hasOwnProperty(t)&&r(n,t,i);else r(n,s[1],s[2])}}();return u});

View File

@ -10,7 +10,7 @@
ws = new WebSocket(wsUrl); ws = new WebSocket(wsUrl);
ws.onopen = function() { ws.onopen = function() {
pingDisplay.innerHTML = '<i class="fas fa-wifi"></i> Ping: Waiting...'; pingDisplay.innerHTML = '<i class="fas fa-satellite-dish"></i> Ping: Waiting...';
}; };
ws.onmessage = function(event) { ws.onmessage = function(event) {
@ -23,7 +23,7 @@
})); }));
} }
if (data.type === "latency" && typeof data.latency === "number") { if (data.type === "latency" && typeof data.latency === "number") {
pingDisplay.innerHTML = '<i class="fa-regular fa-wifi"></i> Ping: ' + data.latency + ' ms'; pingDisplay.innerHTML = '<i class="fas fa-satellite-dish"></i> ' + 'Ping: ' + '~' + data.latency + 'ms';
} }
} catch (err) { } catch (err) {
console.error("Error parsing message:", err); console.error("Error parsing message:", err);
@ -31,11 +31,11 @@
}; };
ws.onerror = function() { ws.onerror = function() {
pingDisplay.innerHTML = '<i class="fa-regular fa-wifi"></i> Ping: Error'; pingDisplay.innerHTML = '<i class="fas fa-satellite-dish"></i> Ping: Error';
}; };
ws.onclose = function() { ws.onclose = function() {
pingDisplay.innerHTML = '<i class="fa-regular fa-wifi"></i> Ping: Disconnected'; pingDisplay.innerHTML = '<i class="fas fa-satellite-dish"></i> Ping: Disconnected';
setTimeout(createWebSocket, 1000); setTimeout(createWebSocket, 1000);
}; };
} }

View File

@ -1,124 +1,80 @@
document.addEventListener('DOMContentLoaded', function() { ;(function(){
const originalLog = console.log; const origLog = console.log.bind(console);
const originalWarn = console.warn; document.addEventListener("DOMContentLoaded", () => {
const originalError = console.error; origLog(
const scriptLogs = []; "%c\n" +
" ᶻ 𝗓 𐰁 .ᐟ\n" +
" |\\ _,,,---,,_\n" +
" /, `.-'`' -. ;-;;,_\n" +
" |,4- ) )-,_..;\\ ( `'-'\n" +
" '---''(_/--' `-`\\_)\n discord.gg/dJvdkPRheV",
"color: hotpink; font-size: 16px; display: block; white-space: pre; text-align: center; padding-left: 28%;"
);
});
function isScriptLog(args) { const labelStyle = "background: white; color: black; font-weight: bold; padding: 2px 4px; border-radius: 2px";
return args[0] && (args[0].includes('%c[+]%c') || args[0].includes('%c[*]%c') || args[0].includes('%c[#]%c') || args[0].includes('%c[-]%c') || args[0].includes('%c[!]%c')); const messageStyle = "background: black; color: white; padding: 2px 4px; border-radius: 2px";
} ["log","info","warn","error","debug"].forEach(method => {
const orig = console[method].bind(console);
console[method] = (...args) => {
const text = args.map(a => typeof a === 'string' ? a : JSON.stringify(a)).join(' ');
orig(`%cWaves:%c ${text}`, labelStyle, messageStyle);
};
});
console.log = function(...args) { document.addEventListener("DOMContentLoaded", function(){
if (isScriptLog(args)) { const defaultWispUrl = `${window.location.protocol==="https:"?"wss":"ws"}://${window.location.host}/w/`;
scriptLogs.push(args); let currentWispUrl = localStorage.getItem("customWispUrl") || defaultWispUrl;
} const wispUrl = currentWispUrl;
originalLog.apply(console, args); const connection = new BareMux.BareMuxConnection("/baremux/worker.js");
};
console.warn = function(...args) { registerSW();
if (isScriptLog(args)) {
scriptLogs.push(args);
}
originalWarn.apply(console, args);
};
console.error = function(...args) { async function registerSW(){
if (isScriptLog(args)) { try {
scriptLogs.push(args); if (!navigator.serviceWorker) return console.error("Service Workers are not supported by this browser.");
} await ensureWebSocketConnection(wispUrl);
originalError.apply(console, args); console.log("Registering Service Worker...");
}; await navigator.serviceWorker.register("/wah/sw.js", { scope: "/wah/a/" });
console.log("Service Worker registered successfully.");
const savedTransport = localStorage.getItem("transport") || "epoxy";
switchTransport(savedTransport);
updateTransportUI(savedTransport);
console.log(`Using ${capitalizeTransport(savedTransport)} transport.`);
} catch (e) {
console.error(`An error occurred during Service Worker registration or WebSocket connection: ${e.message||e}`);
}
}
setInterval(() => { async function ensureWebSocketConnection(url){
const currentLogs = [...scriptLogs]; return new Promise((resolve, reject) => {
console.clear(); console.log("Establishing WebSocket connection...");
currentLogs.forEach(log => originalLog.apply(console, log)); const ws = new WebSocket(url);
}, 400); ws.onopen = () => { console.log("WebSocket connection established."); resolve(ws); };
ws.onerror = e => { console.error(`Failed to establish WebSocket connection: ${e.message||e}`); reject(e); };
ws.onclose = ev => {
if (ev.code !== 1000) console.warn(`WebSocket connection closed. Reason: ${ev.reason||"No reason provided"}`);
else console.warn("WebSocket connection closed normally.");
};
});
}
const defaultWispUrl = `${window.location.protocol === "https:" ? "wss" : "ws"}://${window.location.host}/w/`; function switchTransport(t){
let currentWispUrl = localStorage.getItem('customWispUrl') || defaultWispUrl; const m = { epoxy: "/epoxy/index.mjs", libcurl: "/libcurl/index.mjs" }[t];
const wispUrl = currentWispUrl; if (m) connection.setTransport(m, [{ wisp: wispUrl }]);
const connection = new BareMux.BareMuxConnection("/baremux/worker.js"); }
async function registerSW() { function updateTransportUI(t){
try { document.querySelector(".transport-selected").textContent = capitalizeTransport(t);
if (!navigator.serviceWorker) { }
console.log("%c[!]%c Service Workers are not supported by this browser.", "background-color: black; color: white; font-weight: bold;", "background-color: black; color: white;");
return;
}
await ensureWebSocketConnection(wispUrl);
console.log("%c[+]%c Registering Service Worker...", "background-color: black; color: white; font-weight: bold;", "background-color: black; color: white;");
await navigator.serviceWorker.register("/wah/sw.js", { scope: '/wah/a/' });
console.log("%c[*]%c Service Worker registered successfully.", "background-color: black; color: white; font-weight: bold;", "background-color: black; color: white;");
const savedTransport = localStorage.getItem('transport') || "epoxy";
switchTransport(savedTransport);
updateTransportUI(savedTransport);
console.log(`%c[#]%c Using ${capitalizeTransport(savedTransport)} transport.`, "background-color: black; color: white; font-weight: bold;", "background-color: black; color: white;");
} catch (error) {
logError(error, 'An error occurred during Service Worker registration or WebSocket connection');
}
}
async function ensureWebSocketConnection(url) { function capitalizeTransport(t){
return new Promise((resolve, reject) => { return t.charAt(0).toUpperCase() + t.slice(1).toLowerCase();
console.log("%c[+]%c Establishing WebSocket connection...", "background-color: black; color: white; font-weight: bold;", "background-color: black; color: white;"); }
const ws = new WebSocket(url);
ws.onopen = () => {
console.log("%c[*]%c WebSocket connection established.", "background-color: black; color: white; font-weight: bold;", "background-color: black; color: white;");
resolve(ws);
};
ws.onerror = (error) => {
logError(error, 'Failed to establish WebSocket connection');
reject(error);
};
ws.onclose = (event) => {
if (event.code !== 1000) {
console.warn(`%c[-]%c WebSocket connection closed. Reason: ${event.reason || "No reason provided"}`, "background-color: black; color: white; font-weight: bold;", "background-color: black; color: white;");
} else {
console.warn("%c[-]%c WebSocket connection closed normally.", "background-color: black; color: white; font-weight: bold;", "background-color: black; color: white;");
}
};
});
}
function logError(error, message) { document.addEventListener("wispUrlChanged", function(e){
console.error(`%c[!]%c ${message}: ${error.message || error}`, "background-color: black; color: white; font-weight: bold;", "background-color: black; color: white;"); currentWispUrl = e.detail;
} switchTransport(localStorage.getItem("transport") || "epoxy");
});
function switchTransport(transport) { });
const transportMap = { })();
"epoxy": "/epoxy/index.mjs",
"libcurl": "/libcurl/index.mjs"
};
const transportFile = transportMap[transport];
if (transportFile) {
connection.setTransport(transportFile, [{ wisp: wispUrl }]);
}
}
async function changeTransport(newTransport) {
try {
localStorage.setItem('transport', newTransport);
switchTransport(newTransport);
updateTransportUI(newTransport);
} catch (error) {
logError(error, 'An error occurred while storing transport preference');
}
}
function updateTransportUI(transport) {
const transportSelected = document.querySelector(".transport-selected");
transportSelected.textContent = capitalizeTransport(transport);
}
function capitalizeTransport(transport) {
return transport.charAt(0).toUpperCase() + transport.slice(1).toLowerCase();
}
document.addEventListener('wispUrlChanged', function(e) {
currentWispUrl = e.detail;
switchTransport(localStorage.getItem('transport') || "epoxy");
});
registerSW();
});

45
public/assets/js/s.js Normal file
View File

@ -0,0 +1,45 @@
document.addEventListener('DOMContentLoaded', function() {
const searchInput = document.getElementById('shortcutSearchInput');
const grid = document.querySelector('.shortcuts-grid');
let shortcutsData = [];
fetch('/assets/data/s.json')
.then(response => response.json())
.then(data => {
shortcutsData = data.shortcuts;
searchInput.placeholder = `Search through ${shortcutsData.length} Shortcuts...`;
displayShortcuts(shortcutsData);
searchInput.addEventListener('input', function() {
const query = searchInput.value.toLowerCase();
const filteredShortcuts = shortcutsData.filter(shortcut => {
const title = shortcut.title ? shortcut.title.toLowerCase() : '';
const description = shortcut.description ? shortcut.description.toLowerCase() : '';
return title.includes(query) || description.includes(query);
});
displayShortcuts(filteredShortcuts);
});
})
.catch(err => console.error('Error loading shortcuts data:', err));
function displayShortcuts(shortcuts) {
grid.innerHTML = '';
if (shortcuts.length === 0) {
grid.innerHTML = '<p>Zero shortcuts were found matching your search :(</p>';
}
shortcuts.forEach(shortcut => {
const card = document.createElement('div');
card.classList.add('shortcut-card');
card.innerHTML = `
<img src="${shortcut.icon}" alt="${shortcut.title} Icon" />
<h2>${shortcut.title}</h2>
`;
card.addEventListener('click', function() {
APP.handleSearch(shortcut.link);
});
grid.appendChild(card);
});
}
});

View File

@ -1,210 +1,350 @@
document.addEventListener('DOMContentLoaded', function() { document.addEventListener('DOMContentLoaded', function() {
const settingsMenu = document.getElementById('settings-menu'); const settingsMenu = document.getElementById('settings-menu');
settingsMenu.innerHTML = ` settingsMenu.innerHTML = `
<h2>Settings</h2> <h2>Settings</h2>
<div class="settings-tabs"> <div class="settings-tabs">
<button class="tab-button active" id="proxy-tab"><i class="fa-regular fa-server"></i> Proxy</button> <button class="tab-button active" id="proxy-tab">
<button class="tab-button" id="cloak-tab"><i class="fa-regular fa-user-secret"></i> Cloak</button> <i class="fa-regular fa-server"></i> Proxy
<button class="tab-button" id="appearance-tab"><i class="fa-regular fa-palette"></i> Appearance</button> </button>
<button class="tab-button" id="info-tab"><i class="fa-regular fa-info"></i> Info</button> <button class="tab-button" id="cloak-tab">
</div> <i class="fa-regular fa-user-secret"></i> Cloak
<div id="proxy-content" class="tab-content"> </button>
<label for="transport-selector">Transport</label> <button class="tab-button" id="appearance-tab">
<p>Transport is how the proxy will send information.</p> <i class="fa-regular fa-palette"></i> Appearance
<div class="transport-selector"> </button>
<div class="transport-selected">Epoxy</div> <button class="tab-button" id="info-tab">
<div class="transport-options"> <i class="fa-regular fa-info"></i> Info
<div>Epoxy</div> </button>
<div>Libcurl</div> </div>
<div id="proxy-content" class="tab-content">
<label for="transport-selector">Transport</label>
<p>Transport is how the proxy will send information.</p>
<div class="transport-selector">
<div class="transport-selected">Epoxy</div>
<div class="transport-options">
<div>Epoxy</div>
<div>Libcurl</div>
</div>
</div>
<label for="wisp-server">Wisp Server</label>
<p>Enter a different Wisp Server to connect to.</p>
<p>Recommended to keep this as default.</p>
<input type="text" id="wisp-server" placeholder="Wisp Server URL Here..." autocomplete="off">
<button id="save-wisp-url">Save</button>
</div>
<div id="cloak-content" class="tab-content">
<label for="aboutblank-toggle">Auto About:Blank</label>
<p>Turn this on to go into about:blank every time the page loads (Recommended).</p>
<input type="checkbox" id="aboutblank-toggle">
</div>
<div id="appearance-content" class="tab-content">
<label for="navbar-toggle">Navigation Bar</label>
<p>Keep this on for the navigation bar when searching (Recommended).</p>
<input type="checkbox" id="navbar-toggle">
</div>
<div id="info-content" class="tab-content">
<label>Version 2.8.9</label>
<label
onmouseover="this.querySelector('span').style.color='lime'"
onmouseout="this.querySelector('span').style.color='green'">
Server Status:
<span style="color: green; transition: color 0.3s ease; font-size: 0.95em;">Running</span>
</label>
<label
onmouseover="this.querySelector('span').style.color='lime'"
onmouseout="this.querySelector('span').style.color='green'">
Server Speed:
<span id="server-speed" style="color: green; transition: color 0.3s ease; font-size: 0.95em;">Checking...</span>
</label>
<label
onmouseover="this.querySelector('span').style.color='#dadada'"
onmouseout="this.querySelector('span').style.color='#949494'">
Server Uptime:
<span id="server-uptime" style="color: #949494; transition: color 0.3s ease; font-size: 0.95em;">Calculating...</span>
</label>
<label
onmouseover="this.querySelector('span').style.color='#dadada'"
onmouseout="this.querySelector('span').style.color='#949494'">
Server Specs:
<span id="server-specs" style="color: #949494; transition: color 0.3s ease; font-size: 0.95em;">Loading...</span>
</label>
<p>Having any problems? Join our Discord Server below or open an issue on GitHub for support.</p>
<div style="display: flex; gap: 10px; justify-content: left; align-items: left; margin-top: 10px; margin-bottom: -20px;">
<label>
<a href="https://discord.gg/dJvdkPRheV" target="_blank" class="hover-link">
<i class="fab fa-discord" style="font-size: 20px;"></i>
</a>
</label>
<label>
<a href="https://github.com/xojw/waves" target="_blank" class="hover-link">
<i class="fab fa-github" style="font-size: 20px;"></i>
</a>
</label>
</div> </div>
</div> </div>
<label for="wisp-server">Wisp Server</label>
<p>Enter a different Wisp Server to connect to.</p> <button id="close-settings">
<p>Recommended to keep this as default.</p> <i class="fa-regular fa-times"></i>
<input type="text" id="wisp-server" placeholder="Wisp Server URL Here..." autocomplete="off"> </button>
<button id="save-wisp-url">Save</button>
</div>
<div id="cloak-content" class="tab-content">
<label for="aboutblank-toggle">About:Blank</label>
<p>Turn this on to go into about:blank every time the page loads (Recommended).</p>
<input type="checkbox" id="aboutblank-toggle">
</div>
<div id="appearance-content" class="tab-content">
<label for="navbar-toggle">Navigation Bar</label>
<p>Keep this on for the navigation bar when searching (Recommended).</p>
<input type="checkbox" id="navbar-toggle">
</div>
<div id="info-content" class="tab-content">
<label>Version 2.8.5</label>
<label onmouseover="this.querySelector('span').style.color='lime'" onmouseout="this.querySelector('span').style.color='green'">
Server Status: <span style="color: green; transition: color 0.3s ease;">Running</span>
</label>
<p>If you want to see Waves status please visit <a href="https://status.usewaves.site" target="_blank" class="hover-link">https://status.usewaves.site</a>.</p>
<div style="display: flex; gap: 10px; justify-content: left; align-items: left; margin-top: 10px; margin-bottom: -20px;">
<label><a href="https://discord.gg/dJvdkPRheV" target="_blank" class="hover-link"><i class="fab fa-discord" style="font-size: 20px;"></i></a></label>
<label><a href="https://github.com/xojw/waves" target="_blank" class="hover-link"><i class="fab fa-github" style="font-size: 20px;"></i></a></label>
</div>
</div>
<button id="close-settings"><i class="fa-regular fa-times"></i></button>
`; `;
const settingsIcon = document.getElementById('settings-icon');
const closeSettingsButton = document.getElementById('close-settings');
const saveButton = document.getElementById('save-wisp-url');
const transportSelector = document.querySelector('.transport-selector');
const transportSelected = transportSelector.querySelector('.transport-selected');
const transportOptions = transportSelector.querySelector('.transport-options');
const navbarToggle = document.getElementById('navbar-toggle');
const defaultWispUrl = `${window.location.protocol === "https:" ? "wss" : "ws"}://${window.location.host}/w/`;
let currentWispUrl = localStorage.getItem('customWispUrl') || defaultWispUrl;
const wispInput = document.querySelector("#wisp-server");
wispInput.value = currentWispUrl;
function isValidUrl(url) { const settingsIcon = document.getElementById('settings-icon');
try { const closeSettingsBtn = document.getElementById('close-settings');
const parsedUrl = new URL(url); const saveWispBtn = document.getElementById('save-wisp-url');
return (parsedUrl.protocol === "wss:" || parsedUrl.protocol === "ws:") && url.endsWith('/'); const transportSelector = document.querySelector('.transport-selector');
} catch (_) { const transportSelected = transportSelector.querySelector('.transport-selected');
return false; const transportOptions = transportSelector.querySelector('.transport-options');
} const navbarToggle = document.getElementById('navbar-toggle');
} const defaultWispUrl = `${window.location.protocol === "https:" ? "wss" : "ws"}://${window.location.host}/w/`;
let currentWispUrl = localStorage.getItem('customWispUrl') || defaultWispUrl;
const wispInput = document.querySelector("#wisp-server");
wispInput.value = currentWispUrl;
let isToggling = false;
function updateWispServerUrl(url) { navbarToggle.checked = localStorage.getItem('navbarToggled') !== 'false';
if (isValidUrl(url)) {
currentWispUrl = url;
localStorage.setItem('customWispUrl', url);
document.dispatchEvent(new CustomEvent('wispUrlChanged', { detail: currentWispUrl }));
wispInput.value = currentWispUrl;
showToast('success', `WISP URL successfully updated to: ${currentWispUrl}`);
location.reload();
} else {
currentWispUrl = defaultWispUrl;
localStorage.setItem('customWispUrl', defaultWispUrl);
wispInput.value = defaultWispUrl;
showToast('error', "Invalid URL. Reverting back to default...");
location.reload();
}
}
saveButton.addEventListener('click', () => {
updateWispServerUrl(wispInput.value.trim());
});
settingsIcon.addEventListener('click', (event) => {
event.preventDefault();
toggleSettingsMenu();
});
closeSettingsButton.addEventListener('click', toggleSettingsMenu);
function toggleSettingsMenu() { function isValidUrl(url) {
const icon = document.querySelector('#settings-icon i.settings-icon'); try {
if (settingsMenu.classList.contains('open')) { const p = new URL(url);
settingsMenu.classList.add('close'); return (p.protocol === "wss:" || p.protocol === "ws:") && url.endsWith('/');
icon.classList.replace('fa-solid', 'fa-regular'); } catch (_) {
setTimeout(() => settingsMenu.classList.remove('open', 'close'), 300); return false;
} else { }
settingsMenu.classList.add('open'); }
icon.classList.replace('fa-regular', 'fa-solid');
setTimeout(() => settingsMenu.classList.remove('close'), 300);
}
}
transportSelected.addEventListener('click', function(e) {
e.stopPropagation();
transportOptions.classList.toggle('transport-show');
this.classList.toggle('transport-arrow-active');
});
Array.from(transportOptions.getElementsByTagName('div')).forEach(option => {
option.addEventListener('click', function(e) {
e.stopPropagation();
const selectedValue = this.textContent;
transportSelected.textContent = selectedValue;
localStorage.setItem('transport', selectedValue.toLowerCase());
transportOptions.classList.remove('transport-show');
transportSelected.classList.remove('transport-arrow-active');
document.dispatchEvent(new Event('newTransport', { detail: selectedValue.toLowerCase() }));
showToast('success', `Transport successfully changed to ${selectedValue}`);
location.reload();
});
});
document.getElementById('proxy-content').classList.add('active');
function switchTab(activeTabId, activeContentId, ...others) { function runScriptIfChecked() {
[others[1], others[3], others[5]].forEach(id => document.getElementById(id).classList.remove('active')); let inFrame;
[others[0], others[2], others[4]].forEach(id => document.getElementById(id).classList.remove('active')); try {
document.getElementById(activeContentId).classList.add('active'); inFrame = window !== top;
document.getElementById(activeTabId).classList.add('active'); } catch (e) {
} inFrame = true;
document.getElementById('proxy-tab').addEventListener('click', function() { }
switchTab('proxy-tab', 'proxy-content', 'appearance-tab', 'appearance-content', 'cloak-tab', 'cloak-content', 'info-tab', 'info-content'); const aboutBlankChecked = JSON.parse(localStorage.getItem("aboutBlankChecked")) || false;
}); if (!aboutBlankChecked || inFrame) {
document.getElementById('cloak-tab').addEventListener('click', function() { return;
switchTab('cloak-tab', 'cloak-content', 'proxy-tab', 'proxy-content', 'appearance-tab', 'appearance-content', 'info-tab', 'info-content'); }
}); const defaultTitle = "Google.";
document.getElementById('appearance-tab').addEventListener('click', function() { const defaultIcon = "https://www.google.com/favicon.ico";
switchTab('appearance-tab', 'appearance-content', 'proxy-tab', 'proxy-content', 'cloak-tab', 'cloak-content', 'info-tab', 'info-content'); const title = localStorage.getItem("siteTitle") || defaultTitle;
}); const icon = localStorage.getItem("faviconURL") || defaultIcon;
document.getElementById('info-tab').addEventListener('click', function() { const iframeSrc = "/";
switchTab('info-tab', 'info-content', 'proxy-tab', 'proxy-content', 'appearance-tab', 'appearance-content', 'cloak-tab', 'cloak-content'); const popup = window.open("", "_blank");
}); if (!popup || popup.closed) {
document.querySelectorAll('.tab-button').forEach(btn => { alert("Failed to load automask. Please allow popups and try again.");
btn.addEventListener('click', function() { return;
const icon = this.querySelector('i'); }
if (icon.classList.contains('fa-bounce')) return; popup.document.head.innerHTML = `
icon.classList.add('fa-bounce'); <title>${title}</title>
setTimeout(() => icon.classList.remove('fa-bounce'), 750); <link rel="icon" href="${icon}">
}); `;
}); popup.document.body.innerHTML = `
navbarToggle.addEventListener('change', function() { <iframe style="height: 100%; width: 100%; border: none; position: fixed; top: 0; right: 0; left: 0; bottom: 0;" src="${iframeSrc}"></iframe>
showToast(this.checked ? 'success' : 'error', `Navigation Bar is now ${this.checked ? 'enabled' : 'disabled'}.`); `;
}); window.location.replace("https://bisd.schoology.com/home");
function runScriptIfChecked() { }
let inFrame;
try { inFrame = window !== top; } catch (e) { inFrame = true; } document.getElementById("aboutblank-toggle").addEventListener("change", function() {
const aboutBlankChecked = JSON.parse(localStorage.getItem("aboutBlankChecked")) || false; localStorage.setItem("aboutBlankChecked", JSON.stringify(this.checked));
if (!aboutBlankChecked || inFrame) return; if (this.checked) {
const title = localStorage.getItem("siteTitle") || "Google."; showToast('success', 'Auto About:Blank is now enabled.');
const icon = localStorage.getItem("faviconURL") || "https://www.google.com/favicon.ico"; } else {
const popup = window.open("", "_blank"); showToast('error', 'Auto About:Blank is now disabled.');
if (!popup || popup.closed) { }
alert("Failed to load automask. Please allow popups and try again."); runScriptIfChecked();
return; });
}
popup.document.head.innerHTML = `<title>${title}</title><link rel="icon" href="${icon}">`; window.addEventListener("load", function() {
popup.document.body.innerHTML = `<iframe style="height:100%;width:100%;border:none;position:fixed;top:0;right:0;left:0;bottom:0;" src="/"></iframe>`; const aboutBlankChecked = JSON.parse(localStorage.getItem("aboutBlankChecked")) || false;
window.location.replace("https://bisd.schoology.com/home"); document.getElementById("aboutblank-toggle").checked = aboutBlankChecked;
} runScriptIfChecked();
document.getElementById("aboutblank-toggle").addEventListener("change", function() { });
localStorage.setItem("aboutBlankChecked", JSON.stringify(this.checked));
showToast(this.checked ? 'success' : 'error', `About:Blank is now ${this.checked ? 'enabled' : 'disabled'}.`); function updateWispServerUrl(url) {
runScriptIfChecked(); if (isValidUrl(url)) {
}); currentWispUrl = url;
window.addEventListener("load", function() { localStorage.setItem('customWispUrl', url);
const aboutBlankChecked = JSON.parse(localStorage.getItem("aboutBlankChecked")) || false; document.dispatchEvent(new CustomEvent('wispUrlChanged', {
document.getElementById("aboutblank-toggle").checked = aboutBlankChecked; detail: currentWispUrl
runScriptIfChecked(); }));
}); showToast('success', `Wisp Server URL changed to: ${currentWispUrl}`);
function showToast(type, message) { } else {
const toast = document.createElement('div'); currentWispUrl = defaultWispUrl;
toast.className = `toast ${type} show`; localStorage.setItem('customWispUrl', defaultWispUrl);
const icons = { document.dispatchEvent(new CustomEvent('wispUrlChanged', {
success: '<i class="fa-regular fa-check-circle" style="margin-right:8px;"></i>', detail: currentWispUrl
error: '<i class="fa-regular fa-times-circle" style="margin-right:8px;"></i>', }));
info: '<i class="fa-regular fa-info-circle" style="margin-right:8px;"></i>', showToast('error', "Invalid URL. Reverting to default...");
warning: '<i class="fa-regular fa-exclamation-triangle" style="margin-right:8px;"></i>' }
}; }
toast.innerHTML = `${icons[type] || ''}${message}`;
const progressBar = document.createElement('div');
progressBar.className = 'progress-bar';
toast.appendChild(progressBar); function updateServerInfo() {
const closeBtn = document.createElement('button'); const speedSpan = document.getElementById('server-speed');
closeBtn.className = 'toast-close'; const uptimeSpan = document.getElementById('server-uptime');
closeBtn.innerHTML = '<i class="fa-regular fa-xmark" style="margin-left:8px;font-size:0.8em;"></i>'; const specsSpan = document.getElementById('server-specs');
closeBtn.addEventListener('click', () => { let uptimeInterval;
toast.classList.replace('show', 'hide');
setTimeout(() => toast.remove(), 500); fetch('/api/info')
}); .then(response => {
toast.appendChild(closeBtn); if (!response.ok) throw new Error();
document.body.appendChild(toast); return response.json();
setTimeout(() => { })
toast.classList.replace('show', 'hide'); .then(data => {
setTimeout(() => toast.remove(), 500); if (data?.speed) {
}, 3000); const updateUptimeDisplay = () => {
} const uptime = Date.now() - data.startTime;
const days = Math.floor(uptime / 86400000);
const hours = Math.floor((uptime % 86400000) / 3600000);
const minutes = Math.floor((uptime % 3600000) / 60000);
const seconds = Math.floor((uptime % 60000) / 1000);
uptimeSpan.textContent = `${days}d ${hours}h ${minutes}m ${seconds}s`;
};
updateUptimeDisplay();
clearInterval(uptimeInterval);
uptimeInterval = setInterval(updateUptimeDisplay, 1000);
speedSpan.textContent = `${data.speed} (${data.averageLatency}ms)`;
specsSpan.textContent = data.specs;
}
setTimeout(updateServerInfo, 10000);
})
.catch(() => {
speedSpan.textContent = 'Connection error';
setTimeout(updateServerInfo, 30000);
});
}
function initializeInfo() {
const infoTab = document.getElementById('info-tab');
const infoContent = document.getElementById('info-content');
const startMonitoring = () => {
updateServerInfo();
infoTab.removeEventListener('click', startMonitoring);
};
if (infoContent.classList.contains('active')) {
updateServerInfo();
} else {
infoTab.addEventListener('click', startMonitoring, {
once: true
});
}
}
function showToast(type, message) {
const toast = document.createElement('div');
toast.className = `toast ${type} show`;
const icons = {
success: '<i class="fa-regular fa-check-circle"></i>',
error: '<i class="fa-regular fa-times-circle"></i>',
info: '<i class="fa-regular fa-info-circle"></i>',
warning: '<i class="fa-regular fa-exclamation-triangle"></i>'
};
toast.innerHTML = `${icons[type]||''}${message}`;
const progressBar = document.createElement('div');
progressBar.className = 'progress-bar';
toast.appendChild(progressBar);
const closeBtn = document.createElement('button');
closeBtn.className = 'toast-close';
closeBtn.innerHTML = '<i class="fa-regular fa-xmark"></i>';
closeBtn.addEventListener('click', () => {
toast.classList.replace('show', 'hide');
setTimeout(() => toast.remove(), 500);
});
toast.appendChild(closeBtn);
document.body.appendChild(toast);
setTimeout(() => {
toast.classList.replace('show', 'hide');
setTimeout(() => toast.remove(), 500);
}, 3000);
}
saveWispBtn.addEventListener('click', () => updateWispServerUrl(wispInput.value.trim()));
settingsIcon.addEventListener('click', e => {
e.preventDefault();
toggleSettingsMenu();
});
closeSettingsBtn.addEventListener('click', toggleSettingsMenu);
function toggleSettingsMenu() {
if (isToggling) return;
isToggling = true;
const icon = document.querySelector('#settings-icon i.settings-icon');
if (settingsMenu.classList.contains('open')) {
settingsMenu.classList.add('close');
icon.classList.replace('fa-solid', 'fa-regular');
setTimeout(() => {
settingsMenu.classList.remove('open', 'close');
isToggling = false;
}, 300);
} else {
settingsMenu.classList.add('open');
icon.classList.replace('fa-regular', 'fa-solid');
setTimeout(() => {
settingsMenu.classList.remove('close');
isToggling = false;
}, 300);
}
}
transportSelected.addEventListener('click', e => {
e.stopPropagation();
transportOptions.classList.toggle('transport-show');
transportSelected.classList.toggle('transport-arrow-active');
});
Array.from(transportOptions.getElementsByTagName('div')).forEach(option => {
option.addEventListener('click', function(e) {
e.stopPropagation();
const val = this.textContent;
transportSelected.textContent = val;
localStorage.setItem('transport', val.toLowerCase());
transportOptions.classList.remove('transport-show');
transportSelected.classList.remove('transport-arrow-active');
document.dispatchEvent(new CustomEvent('newTransport', {
detail: val.toLowerCase()
}));
showToast('success', `Transport changed to ${val}`);
});
});
document.getElementById('proxy-content').classList.add('active');
function switchTab(activeTab, activeContent, ...others) {
others.forEach(id => document.getElementById(id).classList.remove('active'));
document.getElementById(activeTab).classList.add('active');
document.getElementById(activeContent).classList.add('active');
}
document.getElementById('proxy-tab').addEventListener('click', () => switchTab('proxy-tab', 'proxy-content', 'cloak-tab', 'cloak-content', 'appearance-tab', 'appearance-content', 'info-tab', 'info-content'));
document.getElementById('cloak-tab').addEventListener('click', () => switchTab('cloak-tab', 'cloak-content', 'proxy-tab', 'proxy-content', 'appearance-tab', 'appearance-content', 'info-tab', 'info-content'));
document.getElementById('appearance-tab').addEventListener('click', () => switchTab('appearance-tab', 'appearance-content', 'proxy-tab', 'proxy-content', 'cloak-tab', 'cloak-content', 'info-tab', 'info-content'));
document.getElementById('info-tab').addEventListener('click', () => switchTab('info-tab', 'info-content', 'proxy-tab', 'proxy-content', 'cloak-tab', 'cloak-content', 'appearance-tab', 'appearance-content'));
document.querySelectorAll('.tab-button').forEach(btn => {
btn.addEventListener('click', function() {
const icon = this.querySelector('i');
if (!icon.classList.contains('fa-bounce')) {
icon.classList.add('fa-bounce');
setTimeout(() => icon.classList.remove('fa-bounce'), 750);
}
});
});
navbarToggle.addEventListener('change', function() {
localStorage.setItem('navbarToggled', this.checked.toString());
showToast(this.checked ? 'success' : 'error', `Navigation Bar ${this.checked ? 'enabled' : 'disabled'}`);
if (window.APP && typeof window.APP.updateNavbarDisplay === 'function') {
window.APP.updateNavbarDisplay();
}
});
initializeInfo();
}); });

View File

@ -1,109 +1,147 @@
(function () { (function(){
document.addEventListener('DOMContentLoaded', function () { document.addEventListener('DOMContentLoaded', function(){
function getSearchInputs() { const indicators = document.querySelectorAll('.shortcut-indicator, .shortcut-indicator-2, .shortcut-indicator-3, .shortcut-indicator-4');
return [ const arrowIndicators = document.querySelectorAll('.shortcut-indicator, .shortcut-indicator-2');
document.getElementById('searchInput'), indicators.forEach(el => {
document.getElementById('searchInputt'), if (!el.dataset.original) el.dataset.original = el.innerHTML;
document.getElementById('gameSearchInput'), });
document.getElementById('appSearchInput')
].filter(Boolean); function getSearchInputs(){
return [
document.getElementById('searchInput'),
document.getElementById('searchInputt'),
document.getElementById('gameSearchInput'),
document.getElementById('shortcutSearchInput')
].filter(Boolean);
}
function isVisible(el){
return !!(el.offsetWidth || el.offsetHeight || el.getClientRects().length);
}
function focusFirstVisibleInput(){
const inputs = getSearchInputs();
for (let inp of inputs) {
if (isVisible(inp)) {
inp.focus();
return inp;
}
} }
if (inputs[0]) {
function isVisible(el) { inputs[0].focus();
return !!(el.offsetWidth || el.offsetHeight || el.getClientRects().length); return inputs[0];
} }
return null;
}
function focusFirstVisibleInput() { let arrowMode = false;
const inputs = getSearchInputs();
for (const input of inputs) { function updateIndicatorState(){
if (isVisible(input)) { const hasText = getSearchInputs().some(i => i.value.trim() !== '');
input.focus(); if (hasText === arrowMode) return;
return; arrowMode = hasText;
} arrowIndicators.forEach(ind => {
} ind.classList.remove('fadeIn');
if (inputs.length) { ind.classList.add('fadeOut');
inputs[0].focus(); setTimeout(() => {
} if (hasText) {
ind.innerHTML = '<i class="fa-solid fa-arrow-right"></i>';
ind.classList.add('arrow-mode');
} else {
ind.innerHTML = ind.dataset.original;
ind.classList.remove('arrow-mode');
}
ind.classList.remove('fadeOut');
ind.classList.add('fadeIn');
}, 100);
});
}
function triggerSubmit(input){
const query = input.value.trim();
if (!query) {
showToast('Please enter something in the Search Bar.','error','warning');
return;
} }
if (window.APP && typeof APP.handleSearch === 'function') {
APP.handleSearch(query);
if (input.id === 'searchInput') input.value = '';
}
}
document.addEventListener('keydown', function (e) { function handleIndicatorAction(){
if (e.key === 'Escape') { const inputs = getSearchInputs().filter(isVisible);
const inputs = getSearchInputs(); const active = document.activeElement;
const active = document.activeElement; if (inputs.includes(active) && active.value.trim()) {
if (inputs.includes(active)) { triggerSubmit(active);
active.blur(); return;
e.preventDefault(); }
return; const withText = inputs.find(i => i.value.trim());
} if (withText) {
} triggerSubmit(withText);
return;
}
focusFirstVisibleInput();
}
if (e.ctrlKey && e.key.toLowerCase() === 's') { updateIndicatorState();
e.preventDefault(); getSearchInputs().forEach(i => i.addEventListener('input', updateIndicatorState));
focusFirstVisibleInput();
}
});
document.querySelectorAll( document.addEventListener('keydown', e => {
'.shortcut-indicator, .shortcut-indicator-2, .shortcut-indicator-3, .shortcut-indicator-4' if (e.key === 'Escape') {
).forEach(function (el) { const act = document.activeElement;
el.addEventListener('click', function (e) { if (getSearchInputs().includes(act)) {
e.preventDefault(); act.blur();
focusFirstVisibleInput(); e.preventDefault();
}); }
}); }
if (e.ctrlKey && e.key.toLowerCase() === 's') {
e.preventDefault();
focusFirstVisibleInput();
}
});
document.body.addEventListener('click', function (e) { document.body.addEventListener('click', e => {
if ( const ind = e.target.closest('.shortcut-indicator, .shortcut-indicator-2, .shortcut-indicator-3, .shortcut-indicator-4');
e.target.classList.contains('shortcut-indicator') || if (!ind) return;
e.target.classList.contains('shortcut-indicator-2') || e.preventDefault();
e.target.classList.contains('shortcut-indicator-3') || if (ind.classList.contains('arrow-mode')) {
e.target.classList.contains('shortcut-indicator-4') handleIndicatorAction();
) { } else {
e.preventDefault(); focusFirstVisibleInput();
focusFirstVisibleInput(); }
} });
});
const coolIframe = document.getElementById('cool-iframe'); const coolIframe = document.getElementById('cool-iframe');
if (coolIframe) { if (coolIframe){
coolIframe.addEventListener('load', function () { coolIframe.addEventListener('load', () => {
const doc = coolIframe.contentWindow.document; const doc = coolIframe.contentWindow.document;
doc.addEventListener('keydown', innerE => {
doc.addEventListener('keydown', function (e) { if (innerE.key === 'Escape') {
if (e.key === 'Escape') { if (doc.activeElement.blur) doc.activeElement.blur();
if (doc.activeElement && doc.activeElement.blur) { innerE.preventDefault();
doc.activeElement.blur(); }
e.preventDefault(); if (innerE.ctrlKey && innerE.key.toLowerCase() === 's') {
return; innerE.preventDefault();
} document.dispatchEvent(new KeyboardEvent('keydown', { key: 's', ctrlKey: true, bubbles: true }));
} }
if (e.ctrlKey && e.key.toLowerCase() === 's') { });
e.preventDefault(); doc.querySelectorAll('.shortcut-indicator, .shortcut-indicator-2, .shortcut-indicator-3, .shortcut-indicator-4')
document.dispatchEvent(new KeyboardEvent('keydown', { .forEach(el => {
key: 's', el.addEventListener('click', ev => {
ctrlKey: true ev.preventDefault();
})); window.parent.postMessage({ type: 'iframe-focus-search' }, '*');
}
}); });
});
doc.querySelectorAll(
'.shortcut-indicator, .shortcut-indicator-2, .shortcut-indicator-3, .shortcut-indicator-4'
).forEach(function (iframeEl) {
iframeEl.addEventListener('click', function (e) {
e.preventDefault();
window.parent.postMessage({
type: 'iframe-focus-search'
}, '*');
});
});
});
}
window.addEventListener('message', function (event) {
const msg = event.data;
if (msg.type === 'iframe-focus-search') {
focusFirstVisibleInput();
}
}); });
}); }
window.addEventListener('message', msgEvt => {
if (msgEvt.data?.type === 'iframe-focus-search'){
const inp = focusFirstVisibleInput();
if (inp && inp.value.trim()) triggerSubmit(inp);
}
});
});
})(); })();

59
public/assets/js/wv.js Normal file
View File

@ -0,0 +1,59 @@
(async()=>{
const storageKey = 'wv-verified';
const last = localStorage.getItem(storageKey);
if(last && Date.now() - last < 2592000000) return;
const style = document.createElement('style');
style.textContent = `
:root{--bg:#000;--card:rgba(0,0,0,0.85);--accent:#fff;--radius:12px;--trans:.3s}
#wv-overlay{position:fixed;inset:0!important;pointer-events:auto;user-select:none;background:var(--bg);display:flex;align-items:center;justify-content:center;font-family:system-ui;z-index:2147483647!important;opacity:1;transition:opacity .4s}
#wv-card{background:var(--card);backdrop-filter:blur(12px);border-radius:var(--radius);padding:32px;width:320px;text-align:center;color:var(--accent)}
#wv-progress{width:100%;height:6px;background:#333;border-radius:var(--radius);overflow:hidden;margin:16px 0}
#wv-bar{width:0;height:100%;background:var(--accent);transition:width var(--trans)}
#wv-info{font-size:.95rem;opacity:.8}
#wv-complete{display:none;}
#wv-complete.show{display:block;}
`;
document.head.appendChild(style);
const overlay = document.createElement('div'); overlay.id='wv-overlay';
overlay.innerHTML = `
<div id="wv-card">
<h2><i class="fas fa-shield-alt"></i> Verifying Browser</h2>
<div id="wv-progress"><div id="wv-bar"></div></div>
<div id="wv-info"></div>
</div>
<div id="wv-complete"><h2><i class="fas fa-check-circle"></i> Success!</h2><p>You May Continue.</p></div>
`;
document.body.appendChild(overlay);
const info = document.getElementById('wv-info');
const bar = document.getElementById('wv-bar');
const tests = [
{msg:'Automation',pass:!navigator.webdriver},
{msg:'Headless',pass:!/headless|phantomjs|puppeteer|selenium/i.test(navigator.userAgent)},
{msg:'Languages',pass:Array.isArray(navigator.languages) && navigator.languages.length>0},
{msg:'Plugins',pass:navigator.plugins.length>0},
{msg:'WebGL',pass:(()=>{try{const c=document.createElement('canvas');const g=c.getContext('webgl')||c.getContext('experimental-webgl');return!!g;}catch{return false;}})()}
];
let failures = [];
for(let i=0;i<tests.length;i++){
const t=tests[i];
info.textContent = `${t.msg}...`;
if(!t.pass) failures.push(t.msg);
bar.style.width = `${((i+1)/tests.length)*100}%`;
await new Promise(r=>setTimeout(r,200));
}
if(failures.length===0){
localStorage.setItem(storageKey, Date.now());
document.getElementById('wv-card').style.display='none';
const done = document.getElementById('wv-complete'); done.classList.add('show');
setTimeout(()=>overlay.style.opacity='0',500);
setTimeout(()=>overlay.remove(),800);
} else {
info.innerHTML = `Failed:<br>${failures.map(f=>`${f}`).join('<br>')}`;
bar.style.background='red';
}
})();

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff