Upload files to "v4/js"

This commit is contained in:
LEGALISE_PIRACY 2024-01-30 01:28:06 +00:00
parent 8e5617c571
commit 7c6b962ece
5 changed files with 856 additions and 0 deletions

218
v4/js/games.js Normal file
View File

@ -0,0 +1,218 @@
/*
Hello epic hacker (maybe skid) you are looking at one of the many scripts that powers the site,
this script has extra comments and info to help you understand what is going on.
This is a JavaScript code that creates a game catalog page with a search feature,
a game detail page, and the ability to save and load user data.
It uses fetch to load game data from a JSON file, creates game elements for each game,
and adds click event listeners to show the game in a game container.
The code also includes functions to handle saving and loading user data as well as a function to handle a specific key sequence.
*/
// Select the elements
const gamesContainer = document.querySelector(".games");
const searchBar = document.querySelector(".searchbar");
const gameContainer = document.querySelector(".gamecontainer");
const gameFrame = gameContainer.querySelector(".frame");
const gameNav = gameContainer.querySelector(".nav");
// Listen for input event on the search bar
searchBar.addEventListener("input", (e) => {
const query = searchBar.value.trim().toLowerCase();
// Loop through all the games in the container and show/hide them depending on whether they match the search query
for (let game of gamesContainer.children) {
if (game instanceof Element) {
if (query) {
const gameName = game
.querySelector("span")
.innerText.trim()
.toLowerCase();
if (gameName.includes(query)) {
game.removeAttribute("hidden");
} else {
game.setAttribute("hidden", "");
}
} else {
game.removeAttribute("hidden");
}
}
}
// If there are no games shown, display the "No games" message, otherwise hide it
if (document.querySelectorAll(".game:not([hidden])").length == 0) {
document.querySelector(".nogames").style.display = "initial";
} else {
document.querySelector(".nogames").style.display = "none";
}
});
// Fetch the games data from a JSON file
fetch("./assets/json/games.json")
.then((res) => res.json())
.then((games) => {
// Loop through each game and create a new game element for it
games.forEach((game) => {
const gameEl = document.createElement("div");
gameEl.className = "game";
gameEl.innerHTML = `<img src="${
cdn + game.root + "/" + game.img
}"/><span>${game.name}</span>`;
gamesContainer.appendChild(gameEl);
// Add click event listener to the game element to show the game in the game container
gameEl.onclick = (e) => {
gamesContainer.classList.add("hidden");
searchBar.classList.add("hidden");
gameContainer.classList.remove("hidden");
document.querySelector(".saveItems").classList.add("hidden");
document.querySelector(".navbar").classList.add("noshadow");
gameFrame.querySelector(
"iframe"
).src = `./assets/game.html?game=${game.root}`;
gameNav.querySelector("span").textContent = game.name;
};
// Add click event listener to the back button in the game container to go back to the games list
gameNav.querySelector("#back").addEventListener("click", (e) => {
gamesContainer.classList.remove("hidden");
searchBar.classList.remove("hidden");
gameContainer.classList.add("hidden");
document.querySelector(".saveItems").classList.remove("hidden");
document.querySelector(".navbar").classList.remove("noshadow");
gameFrame.src = "";
});
// Add click event listener to the fullscreen button in the game container to enter fullscreen mode
gameNav.querySelector("#fullscreen").addEventListener("click", (e) => {
if (!document.fullscreenElement) {
gameFrame.requestFullscreen();
}
});
});
})
.catch((e) => {
alert("Could not load games");
alert(e);
});
// Hide the spinner element after the page is loaded
document.querySelector(".spinner").style.display = "none";
// Function to get the main save data
function getMainSave() {
var mainSave = {};
// List of items in localStorage that should not be saved
var localStorageDontSave = ["theme", "tab", "nebelung"];
// Convert localStorage to an array of key-value pairs and remove the items that should not be saved
let localStorageSave = Object.entries(localStorage);
for (let entry in localStorageSave) {
if (localStorageDontSave.includes(localStorageSave[entry][0])) {
localStorageSave.splice(entry, 1);
}
}
// Convert the localStorage array to a base64-encoded JSON string
localStorageSave = btoa(JSON.stringify(localStorageSave));
// Add the localStorage data to the mainSave object
mainSave.localStorage = localStorageSave;
// Get the cookies data and add it to the mainSave object
cookiesSave = document.cookie;
cookiesSave = btoa(cookiesSave);
mainSave.cookies = cookiesSave;
// Convert the mainSave object to a base64-encoded JSON string
mainSave = btoa(JSON.stringify(mainSave));
// Encrypt the mainSave data using AES encryption with the key 'save'
mainSave = CryptoJS.AES.encrypt(mainSave, "save").toString();
// Return the encrypted mainSave data
return mainSave;
}
// Function to download the main save data as a file
function downloadMainSave() {
var data = new Blob([getMainSave()]);
var dataURL = URL.createObjectURL(data);
var fakeElement = document.createElement("a");
fakeElement.href = dataURL;
fakeElement.download = "games.save";
fakeElement.click();
URL.revokeObjectURL(dataURL);
}
// Function to get the main save data from an uploaded file
function getMainSaveFromUpload(data) {
// Decrypt the uploaded data using AES decryption with the key 'save'
data = CryptoJS.AES.decrypt(data, "save").toString(CryptoJS.enc.Utf8);
// Parse the decrypted data as JSON
var mainSave = JSON.parse(atob(data));
var mainLocalStorageSave = JSON.parse(atob(mainSave.localStorage));
var cookiesSave = atob(mainSave.cookies);
// Set the items in localStorage using the uploaded data
for (let item of mainLocalStorageSave) {
localStorage.setItem(item[0], item[1]);
}
// Set the cookies using the uploaded data
document.cookie = cookiesSave;
}
// Function to handle the file upload
function uploadMainSave() {
var hiddenUpload = document.querySelector(".hiddenUpload");
hiddenUpload.click();
// Listen for the change event on the file input element
hiddenUpload.addEventListener("change", function (e) {
var files = e.target.files;
var file = files[0];
if (!file) {
return;
}
// Read the contents of the uploaded file as text and call getMainSaveFromUpload with the result
var reader = new FileReader();
reader.onload = function (e) {
getMainSaveFromUpload(e.target.result);
// Show a success message to the user
var uploadResult = document.querySelector(".uploadResult");
uploadResult.innerText = "Uploaded save!";
uploadResult.style.display = "initial";
setTimeout(function () {
uploadResult.style.display = "none";
}, 3000);
};
reader.readAsText(file);
});
}
// Handle the hii pattern when keys are pressed
var hiiPattern = ["h", "i", "i"];
var hiiCurrent = 0;
document.addEventListener("keydown", function (e) {
if (e.key !== hiiPattern[hiiCurrent]) {
return (hiiCurrent = 0);
}
hiiCurrent++;
if (hiiPattern.length == hiiCurrent) {
hiiCurrent = 0;
document.querySelector(".hii").removeAttribute("hidden");
}
});

84
v4/js/home.js Normal file
View File

@ -0,0 +1,84 @@
/*
Hello epic hacker (maybe skid) you are looking at one of the many scripts that powers the site,
this script has extra comments and info to help you understand what is going on.
This is a JavaScript code that generates random splash messages and sets them in the DOM.
The code declares two variables for caching splash messages, "splashCacheAll" and "splashCache".
The "randomSay" function fetches a set of splash messages and selects a random one from the set,
caching the remaining messages in the "splashCache" variable.
If the selected message contains special placeholders like "%REAL_IP%", "%GAMES_NUMBER%", or "%SPLASH_NUMBER%",
the placeholders are replaced with corresponding values, such as the user's IP address, the number of available games,
or the total number of splash messages. The "setRandomSay" function sets the selected splash message in the DOM.
If there is an element with class "message", the "setRandomSay" function is called to set a random splash message in the DOM.
*/
// Declare variables for caching splash messages
var splashCacheAll;
var splashCache;
// Async function that returns a random splash message
async function randomSay() {
// If splashCache is defined and not empty
if (splashCache) {
// If splashCache is empty, set it equal to the full set of splash messages
if (!splashCache.length) {
splashCache = splashCacheAll;
}
// Set says variable to the current splashCache
var says = splashCache;
} else {
// If splashCache is undefined or empty, fetch the full set of splash messages
var say = await fetch("./assets/json/say.json");
var says = await say.json();
// Store the full set of splash messages in both splashCacheAll and splashCache
splashCacheAll = says;
splashCache = says;
}
// Get a random splash message from the current says set
var getRandomSay = says[Math.floor(Math.random() * says.length)];
// Remove the randomly selected splash message from the cache
splashCache = splashCache.filter((splash) => splash !== getRandomSay);
// Return the randomly selected splash message
return getRandomSay;
}
// Async function that sets a random splash message in the DOM
async function setRandomSay() {
// Get a random splash message using the randomSay() function
var randomSplash = await randomSay();
// If the random message is "%REAL_IP%", replace it with the user's IP address
if (randomSplash == "%REAL_IP%") {
var ips = await getIPs();
if (ips[0]) {
randomSplash = "Your real IP is " + ips[0];
} else {
randomSplash = "Cannot get your real IP :(";
}
}
// If the random message is "%GAMES_NUMBER%", replace it with the number of games available
else if (randomSplash == "%GAMES_NUMBER%") {
var gamesFetch = await fetch(location.origin + "/assets/json/games.json");
var games = await gamesFetch.json();
randomSplash = "There are " + games.length + " games currently";
}
// If the random message is "%SPLASH_NUMBER%", replace it with the total number of splash messages
else if (randomSplash == "%SPLASH_NUMBER%") {
randomSplash = "There are " + splashCacheAll.length + " of these messages!";
}
// Set the random splash message in the DOM
document.querySelector(".message").innerText = randomSplash;
}
// If there is an element with class "message", set a random splash message in the DOM
if (document.querySelector(".message")) {
setRandomSay();
}

245
v4/js/index.js Normal file
View File

@ -0,0 +1,245 @@
/*
Hello epic hacker (maybe skid) you are looking at one of the many scripts that powers the site,
this script has extra comments and info to help you understand what is going on.
This code starts off with a script to check if the browser has a cookie, if not, it will display a message kindly asking for the user to turn off their adblocker. Then it sets the cookie so the message is not seen for another year.
The code sets up several variables and functions that are used to fetch data from the server,
manipulate the document's content, and create custom HTML elements.
The isBlocked function checks if a URL is blocked by fetching the content of its README.md
file and returning true if it does not start with "# 3kh0 Assets",
or if there is an error while fetching the file.
The getCDN function iterates through a list of CDN URLs, calls isBlocked on each of them,
and returns the first URL that is not blocked,
or the first URL in the list if they are all blocked.
The rest of the code sets up various event listeners and HTML elements, loads the main.js file,
and sets the website's theme and theme colors based on values in local storage.
The code is mostly concerned with setting up the website's initial state and is executed when the website loads.
*/
// This function checks if a cookie with the given key exists.
function checkCookie(key) {
var value = "; " + document.cookie; // get the cookie value
var parts = value.split("; " + key + "="); // split the value by the key
if (parts.length == 2) {
return true; // the key exists
} else {
return false; // the key does not exist
}
}
// Checks if a CDN is blocked by testing the README.md file
async function isBlocked(url) {
try {
var README = await fetch(url + "/README.md");
var content = await README.text();
if (content.startsWith("# 3kh0 Assets")) {
// The CDN is not blocked
return false;
} else {
// The CDN is not returning a valid response or is blocked
return true;
}
} catch {
return true;
}
}
async function getCDN(cdns) {
for (let cdn of cdns) {
var blocked = await isBlocked(cdn);
if (!blocked) {
return cdn;
}
}
return cdns[0];
}
// Define some varibles for later
const path = location.pathname;
const origin = localStorage.getItem("instance");
const cdn = localStorage.getItem("cdn");
const bare = localStorage.getItem
const queryString = window.location.search;
window.history.pushState({}, "", path);
const urlParams = new URLSearchParams(queryString);
const onLoadData = urlParams.get("onload");
function clearCdnCache() {
fetch("./assets/json/cdns.json")
.then((res) => res.json())
.then(async (cdns) => {
localStorage.setItem("cdn", await getCDN(cdns));
location.reload();
});
}
const base = document.createElement("base");
base.href =
location.origin + path.replace(path.split("\\").pop().split("/").pop(), "");
document.head.appendChild(base);
// If we do not have the origin var, we make it
if (!origin) {
localStorage.setItem("instance", base.href);
location.reload();
}
// If we do not have the cdn var, we make it
if (!cdn) {
fetch("./assets/json/cdns.json")
.then((res) => res.json())
.then(async (cdns) => {
localStorage.setItem("cdn", await getCDN(cdns));
location.reload();
});
}
if (!cdn) {
fetch("./assets/json/cdns.json")
.then((res) => res.json())
.then(async (cdns) => {
localStorage.setItem("cdn", await getCDN(cdns));
location.reload();
});
}
const instance = encodeURIComponent(origin.replace(location.origin, ""));
// If we have onLoadData, we run it now
// If we have any errors, we will log it
window.addEventListener("error", (e) => {
console.error(e);
});
// Add the main script in the <head> tags
// Collect Tab Cloak data from local storage
var tab = localStorage.getItem("tab");
if (tab) {
try {
// Parse the data, it is in JSON
var tabData = JSON.parse(tab);
} catch {
var tabData = {};
}
} else {
var tabData = {};
}
// Set the Tab title if the Tab cloak data is there
if (tabData.title) {
document.title = tabData.title;
}
// Set the Tab icon if the Tab cloak data is there
if (tabData.icon) {
document.querySelector('link[rel="icon"]').href = tabData.icon;
}
// Set theme colors if the user has set it
function getContrastHex(hexcolor) {
hexcolor = hexcolor.replace("#", "");
var r = parseInt(hexcolor.substr(0, 2), 16);
var g = parseInt(hexcolor.substr(2, 2), 16);
var b = parseInt(hexcolor.substr(4, 2), 16);
var yiq = (r * 299 + g * 587 + b * 114) / 1000;
return yiq >= 128 ? "#1c1c1c" : "white";
}
// Set theme colors if the user has set it
function getColorHex(hexcolor) {
hexcolor = hexcolor.replace("#", "");
var r = parseInt(hexcolor.substr(0, 2), 16);
var g = parseInt(hexcolor.substr(2, 2), 16);
var b = parseInt(hexcolor.substr(4, 2), 16);
var yiq = (r * 299 + g * 587 + b * 114) / 1000;
return yiq >= 128 ? "white" : "black";
}
// Set theme colors if the user has set it
var theme = localStorage.getItem("theme") || "default";
let themes;
// Fetching themes
fetch(origin + "assets/json/themes.json")
.then((res) => res.json())
.then((data_themes) => {
themes = data_themes;
if (theme !== "custom") {
document.body.setAttribute("theme", theme);
if (location.pathname.includes("/settings")) {
themes.forEach((palette) => {
if (palette.theme == theme) {
console.log(palette.theme);
document.querySelector("#theme_color").value = palette.color;
}
});
}
} else {
// Get custom theme
const theme = localStorage.getItem("theme_color");
document.body.setAttribute("theme", "custom");
document.body.style = `--theme: ${theme}; --background: ${getContrastHex(
theme
)}; --text: ${getColorHex(theme)}; --text-secondary: ${getColorHex(
theme
)};`;
if (location.pathname.includes("/settings")) {
// Make the custom theme color selector
document.querySelector("#theme_color").value = theme;
}
}
})
.catch((e) => {
// Houston, we have a problem.
console.error(e);
throw new Error("Failed to load themes");
});
// Add the changelogAdded element for the changelog
// Parrot theme random colors
function setParrotColors() {
var parrotColor = "rgb(195, 158, 31)";
var parrotColors = ["#ff4c4b", "#c39e1f", "#b42e63"];
document.querySelectorAll("*").forEach((item) => {
if (getComputedStyle(item).color == parrotColor) {
item.style.color =
parrotColors[Math.floor(Math.random() * parrotColors.length)];
}
});
}
if (localStorage.getItem("theme") == "parrot") {
setParrotColors();
}
// Handle secret themes
function foundSecretTheme(name) {
document.body.setAttribute("theme", name);
localStorage.setItem("theme", name);
localStorage.setItem(name, "true");
if (document.querySelector("." + name)) {
document.querySelector("." + name).removeAttribute("hidden");
}
}
// Handle the secret theme button
function secretThemeButton(name) {
if (localStorage.getItem(name) == "true") {
if (document.querySelector("." + name)) {
document.querySelector("." + name).removeAttribute("hidden");
}
}
}

61
v4/js/main.js Normal file
View File

@ -0,0 +1,61 @@
/*
Hello there!
If you want to add these games to your site, please reach out at my email: echo-the-coder@tuta.io,
or discord: 3kh0_#6969, Thanks and have a great day!
Wondering how this works?
This JavaScript code begins with a console warning message that asks users to reach out via email if they
want to add the games to their website.
The second part of the code defines a function called "script" that logs an informational message to the console when it is called.
The rest of the code creates four separate script tags and adds them to the head of the HTML document.
Each script tag has different attributes and sources, and is appended with the script function.
The first script tag is for Google Tag Manager, the second is for the Arc.io widget, the third is for ad handling using Google Funding Choices,
and the fourth is for Google AdSense.
Each script is added to the page asynchronously for performance reasons.
*/
console.warn(
"%cNote!",
"color: purple; font-weight: 600; background: yellow; padding: 0 5px; border-radius: 5px",
"If you want to add these games to your site, please reach out at my email: echo-the-coder@tuta.io\nPlease do not just add them without asking me first! Thank you!"
);
// function script(text) {
// console.log("%cScript Injection", "color: cyan; font-weight: 600; background: black; padding: 0 5px; border-radius: 5px", text);
// }
// // ====================================
// // SCRIPT INJECTION
// // ====================================
// const gogascript27 = document.createElement("script");
// gogascript27.setAttribute("async", "");
// gogascript27.setAttribute("src", "https://www.googletagmanager.com/gtag/js?id=G-98DP5VKS42");
// const inlinegogascript843 = document.createElement("script");
// inlinegogascript843.innerHTML = `window.dataLayer = window.dataLayer || [];
// function gtag(){dataLayer.push(arguments);}
// gtag('js', new Date());
// gtag('config', 'G-98DP5VKS42');`;
// document.head.append(gogascript27, inlinegogascript843);
// script("Injected script 1/4 (Google Tag Manager)");
// const arcbroker23 = document.createElement("script");
// arcbroker23.setAttribute("async", "");
// arcbroker23.setAttribute("src", "https://arc.io/widget.min.js#eRPHFgiC");
// document.head.append(arcbroker23);
// script("Injected script 2/4 (Arc widget stuff)");
// const adblockhandle44 = document.createElement("script");
// adblockhandle44.setAttribute("src", "https://fundingchoicesmessages.google.com/i/pub-5756835229788588?ers=1");
// adblockhandle44.setAttribute("nonce", "yibq-w_TR5NOCRWsU-VL0Q");
// adblockhandle44.setAttribute("async", "");
// document.head.append(adblockhandle44);
// script("Injected script 3/4 (Ad stuff)");
// const adscipterz92 = document.createElement("script");
// adscipterz92.setAttribute("async", "");
// adscipterz92.setAttribute("src", "https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=ca-pub-5756835229788588");
// adscipterz92.setAttribute("crossorigin", "anonymous");
// document.head.append(adscipterz92);
// script("Injected script 4/4 (Ad stuff)");

248
v4/js/settings.js Normal file
View File

@ -0,0 +1,248 @@
/*
Hello epic hacker (maybe skid) you are looking at one of the many scripts that powers the site,
this script has extra comments and info to help you understand what is going on.
This JavaScript code defines functions that manage the state of a web page's tab,
such as its title and icon, and its theme.
It retrieves a JSON object from local storage, which contains the current state of the tab,
and updates the web page's elements with the stored values.
The code provides functions to modify the tab state and settings, such as setTitle, setFavicon,
resetTab, setTheme, and setThemeColor.
These functions update the web page's elements and store the updated state in local storage.
*/
// Check if there is a saved tab data in localStorage
var tab = localStorage.getItem("tab");
if (tab) {
// If there is saved data, try to parse it
try {
var tabData = JSON.parse(tab);
} catch {
// If there is an error in parsing, create an empty object
var tabData = {};
}
} else {
// If there is no saved data, create an empty object
var tabData = {};
}
// Set the title and icon fields to the values saved in tabData, if they exist
if (tabData.title) {
document.getElementById("title").value = tabData.title;
}
if (tabData.icon) {
document.getElementById("icon").value = tabData.icon;
}
// Default tab settings
var settingsDefaultTab = {
title: "Settings | 3kh0",
icon: "./images/logo.png",
};
// Function to set the document title
function setTitle(title = "") {
if (title) {
document.title = title;
} else {
document.title = settingsDefaultTab.title;
}
// Update the saved tab data with the new title
var tab = localStorage.getItem("tab");
if (tab) {
// If there is saved data, try to parse it
try {
var tabData = JSON.parse(tab);
} catch {
// If there is an error in parsing, create an empty object
var tabData = {};
}
} else {
// If there is no saved data, create an empty object
var tabData = {};
}
if (title) {
// If there is a new title, update tabData
tabData.title = title;
} else {
// If the title is empty, delete the title field from tabData
delete tabData.title;
}
// Save the updated tab data to localStorage
localStorage.setItem("tab", JSON.stringify(tabData));
}
// Function to set the favicon
function setFavicon(icon) {
if (icon) {
document.querySelector("link[rel='icon']").href = icon;
} else {
document.querySelector("link[rel='icon']").href = settingsDefaultTab.icon;
}
// Update the saved tab data with the new icon
var tab = localStorage.getItem("tab");
if (tab) {
// If there is saved data, try to parse it
try {
var tabData = JSON.parse(tab);
} catch {
// If there is an error in parsing, create an empty object
var tabData = {};
}
} else {
// If there is no saved data, create an empty object
var tabData = {};
}
if (icon) {
// If there is a new icon, update tabData
tabData.icon = icon;
} else {
// If the icon is empty, delete the icon field from tabData
delete tabData.icon;
}
// Save the updated tab data to localStorage
localStorage.setItem("tab", JSON.stringify(tabData));
}
function setCloak() {
// applies only to premade cloaks
var cloak = document.getElementById("premadecloaks").value; // cloak seems kind of weird when you spell it out
switch (cloak) {
case "search": // Google Search
setTitle("Google");
setFavicon("./images/cloaks/Google Search.ico");
location.reload();
break;
case "itchio": // itch.io
setTitle("Top free NSFW games for web");
setFavicon("./images/cloaks/D23D344B-4CB0-4799-B525-F4E4F3A36728.ico");
location.reload();
break;
case "wikipedia": // wikipedia
setTitle("ويكيبيديا - جهاد");
setFavicon("https://ar.wikipedia.org/favicon.ico");
location.reload();
break;
case "bsite": // billibilli
setTitle("Billibilli");
setFavicon("https://www.bilibili.com/favicon.ico");
location.reload();
break;
case "drive": // Google Drive
setTitle("My Drive - Google Drive");
setFavicon("./images/cloaks/Google Drive.ico");
location.reload();
break;
case "librex": // LibreX
setTitle("LibreX");
setFavicon("./images/cloaks/9A58D8BC-6595-476A-AD95-B6D8880683C8.ico");
location.reload();
break;
case "youtube": // YouTube
setTitle("YouTube");
setFavicon("./images/cloaks/YouTube.ico");
location.reload();
break;
case "gmail": // Gmail
setTitle("Gmail");
setFavicon("./images/cloaks/Gmail.ico");
location.reload();
break;
case "calendar": // Google Calendar
setTitle("Google Calendar");
setFavicon("./images/cloaks/Calendar.ico");
location.reload();
break;
case "meets": // Google Meet
setTitle("Google Meet");
setFavicon("./images/cloaks/Meet.ico");
location.reload();
break;
case "classroom": // Google Classroom
setTitle("Classes");
setFavicon("./images/cloaks/Classroom.png");
location.reload();
break;
case "canvas": // Canvas
setTitle("Canvas");
setFavicon("./images/cloaks/Canvas.ico");
location.reload();
break;
case "zoom": // Zoom
setTitle("Zoom");
setFavicon("./images/cloaks/Zoom.ico");
location.reload();
break;
case "nitter": // Nitter
setTitle("nitter");
setFavicon("./images/cloaks/63DFB320-0EEC-4F06-AF02-C50DFD2B49AB.ico");
location.reload();
break;
case "teddit": // Teddit
setTitle("teddit");
setFavicon("./images/cloaks/EB4D8FE9-10E9-44B8-A6CE-3F9A0040F94A.ico");
location.reload();
break;
case "cornhub": // Cornhub
setTitle("Cornhub");
setFavicon("./images/cloaks/8FE4C273-914D-431D-907E-3FCF5BB0399F.ico");
location.reload();
break;
case "indivious": // Indivious
setTitle("Indivious");
setFavicon("./images/cloaks/2255E848-AB69-43C1-B470-DBFDA40FAD10.ico");
location.reload();
break;
case "khan": // Khan Academy
setTitle("Dashboard | Khan Academy");
setFavicon("./images/cloaks/Khan Academy.ico");
location.reload();
break;
}
}
// Function to reset the tab settings to default
function resetTab() {
document.title = settingsDefaultTab.title;
document.querySelector("link[rel='icon']").href = settingsDefaultTab.icon;
document.getElementById("title").value = "";
document.getElementById("icon").value = "";
localStorage.setItem("tab", JSON.stringify({}));
}
// Function to set the theme
function setTheme(theme) {
localStorage.setItem("theme", theme);
document.body.setAttribute("theme", theme);
document.body.style = "";
localStorage.removeItem("theme_color");
// Find the theme color from the themes array and set the color
themes.forEach((palette) => {
if (palette.theme == theme) {
document.querySelector("#theme_color").value = palette.color;
}
});
}
// Function to set the custom theme color
function setThemeColor(theme) {
localStorage.setItem("theme", "custom");
localStorage.setItem("theme_color", theme);
document.body.setAttribute("theme", "custom");
document.body.style = `--theme: ${theme}; --background: ${getContrastHex(
theme
)}; --text: ${getColorHex(theme)}; --text-secondary: ${getColorHex(theme)};`;
}