Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
3kh0
GitHub Repository: 3kh0/3kh0.github.io-replit
Path: blob/main/js/index.js
617 views
1
/*
2
Hello epic hacker (maybe skid) you are looking at one of the many scripts that powers the site,
3
this script has extra comments and info to help you understand what is going on.
4
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.
5
The code sets up several variables and functions that are used to fetch data from the server,
6
manipulate the document's content, and create custom HTML elements.
7
The isBlocked function checks if a URL is blocked by fetching the content of its README.md
8
file and returning true if it does not start with "# 3kh0 Assets",
9
or if there is an error while fetching the file.
10
The getCDN function iterates through a list of CDN URLs, calls isBlocked on each of them,
11
and returns the first URL that is not blocked,
12
or the first URL in the list if they are all blocked.
13
The rest of the code sets up various event listeners and HTML elements, loads the main.js file,
14
and sets the website's theme and theme colors based on values in local storage.
15
The code is mostly concerned with setting up the website's initial state and is executed when the website loads.
16
*/
17
18
// This function checks if a cookie with the given key exists.
19
function checkCookie(key) {
20
var value = "; " + document.cookie; // get the cookie value
21
var parts = value.split("; " + key + "="); // split the value by the key
22
if (parts.length == 2) {
23
return true; // the key exists
24
} else {
25
return false; // the key does not exist
26
}
27
}
28
29
var key = "myKey"; // set the key to check for
30
if (!checkCookie(key)) { // if the key does not exist in the cookie
31
alert("Hello! This website is free to use but it costs alot money to maintain with the servers for games which is really expensive, so if you have ad blocker it would be nice of you to turn it off so we can keep the site running! Thank you for supporting us! <3"); // display an alert message
32
var expirationDate = new Date(); // create a new date object
33
expirationDate.setFullYear(expirationDate.getFullYear() + 1); // set the expiration date to one year from now
34
document.cookie = key + "=true; expires=" + expirationDate.toUTCString(); // create the cookie with the key and expiration date
35
}
36
37
var crate;
38
39
// Checks if a CDN is blocked by testing the README.md file
40
async function isBlocked(url) {
41
try {
42
var README = await fetch(url + '/README.md');
43
var content = await README.text();
44
if (content.startsWith('# 3kh0 Assets')) {
45
// The CDN is not blocked
46
return false;
47
} else {
48
// The CDN is not returning a valid response or is blocked
49
return true;
50
}
51
} catch {
52
return true;
53
}
54
}
55
56
async function getCDN(cdns) {
57
for (let cdn of cdns) {
58
var blocked = await isBlocked(cdn);
59
if (!blocked) {
60
return cdn;
61
}
62
}
63
return cdns[0];
64
}
65
66
// Define some varibles for later
67
const path = location.pathname;
68
const origin = localStorage.getItem('instance');
69
const cdn = localStorage.getItem('cdn');
70
const queryString = window.location.search;
71
window.history.pushState({}, '', path);
72
const urlParams = new URLSearchParams(queryString);
73
const onLoadData = urlParams.get('onload');
74
75
const base = document.createElement('base');
76
base.href = location.origin + path.replace(path.split('\\').pop().split('/').pop(), '');
77
document.head.appendChild(base);
78
79
// If we do not have the origin var, we make it
80
if (!origin) {
81
localStorage.setItem('instance', base.href);
82
location.reload();
83
}
84
85
// If we do not have the cdn var, we make it
86
if (!cdn) {
87
fetch('./assets/json/cdns.json')
88
.then((res) => res.json())
89
.then(async (cdns) => {
90
localStorage.setItem('cdn', await getCDN(cdns));
91
location.reload();
92
});
93
}
94
95
const instance = encodeURIComponent(origin.replace(location.origin, ''));
96
97
// If we have onLoadData, we run it now
98
99
window.addEventListener('load', () => {
100
if (onLoadData) {
101
try {
102
eval(onLoadData);
103
} catch(e) {
104
console.error(e);
105
}
106
}
107
108
// Set up the WidgetBot crate
109
if(Crate) {
110
crate = new Crate({
111
server: '971769908205604864', // EchoDev
112
channel: '1017203047388160050', // #guest-chat
113
// notifications: false,
114
})
115
}
116
});
117
118
// If we have any errors, we will log it
119
window.addEventListener('error', (e) => {
120
console.error(e);
121
});
122
123
// Add the main script in the <head> tags
124
const jsdelivr = document.createElement('script');
125
jsdelivr.setAttribute('src', 'https://cdn.jsdelivr.net/gh/3kh0/3kh0.github.io/js/main.js');
126
document.head.append(jsdelivr);
127
128
// Collect Tab Cloak data from local storage
129
var tab = localStorage.getItem('tab');
130
if (tab) {
131
try {
132
// Parse the data, it is in JSON
133
var tabData = JSON.parse(tab);
134
} catch {
135
var tabData = {};
136
}
137
} else {
138
var tabData = {};
139
}
140
141
// Set the Tab title if the Tab cloak data is there
142
if (tabData.title) {
143
document.title = tabData.title;
144
}
145
146
// Set the Tab icon if the Tab cloak data is there
147
if (tabData.icon) {
148
document.querySelector('link[rel="icon"]').href = tabData.icon;
149
}
150
151
// Set theme colors if the user has set it
152
function getContrastHex(hexcolor) {
153
hexcolor = hexcolor.replace('#', '');
154
var r = parseInt(hexcolor.substr(0, 2), 16);
155
var g = parseInt(hexcolor.substr(2, 2), 16);
156
var b = parseInt(hexcolor.substr(4, 2), 16);
157
var yiq = (r * 299 + g * 587 + b * 114) / 1000;
158
return yiq >= 128 ? '#1c1c1c' : 'white';
159
}
160
161
// Set theme colors if the user has set it
162
function getColorHex(hexcolor) {
163
hexcolor = hexcolor.replace('#', '');
164
var r = parseInt(hexcolor.substr(0, 2), 16);
165
var g = parseInt(hexcolor.substr(2, 2), 16);
166
var b = parseInt(hexcolor.substr(4, 2), 16);
167
var yiq = (r * 299 + g * 587 + b * 114) / 1000;
168
return yiq >= 128 ? 'white' : 'black';
169
}
170
171
// Set theme colors if the user has set it
172
var theme = localStorage.getItem('theme') || 'default';
173
let themes;
174
175
// Fetching themes
176
fetch(origin + 'assets/json/themes.json')
177
.then((res) => res.json())
178
.then((data_themes) => {
179
themes = data_themes;
180
181
if (theme !== 'custom') {
182
document.body.setAttribute('theme', theme);
183
184
if (location.pathname.includes('/settings')) {
185
themes.forEach((palette) => {
186
if (palette.theme == theme) {
187
console.log(palette.theme);
188
document.querySelector('#theme_color').value = palette.color;
189
}
190
});
191
}
192
} else {
193
// Get custom theme
194
const theme = localStorage.getItem('theme_color');
195
196
document.body.setAttribute('theme', 'custom');
197
document.body.style = `--theme: ${theme}; --background: ${getContrastHex(theme)}; --text: ${getColorHex(theme)}; --text-secondary: ${getColorHex(theme)};`;
198
199
if (location.pathname.includes('/settings')) {
200
// Make the custom theme color selector
201
document.querySelector('#theme_color').value = theme;
202
}
203
}
204
})
205
.catch((e) => {
206
// Houston, we have a problem.
207
console.error(e);
208
throw new Error('Failed to load themes');
209
});
210
211
// Add the changelogAdded element for the changelog
212
class changelogAdded extends HTMLElement {
213
constructor() {
214
super();
215
this.innerHTML = `
216
<div class="changelog-item">
217
<div class="changelog-type" added></div>
218
${this.innerText}
219
</div>
220
`;
221
}
222
}
223
224
customElements.define('changelog-added', changelogAdded);
225
226
// Add the changelogRemoved element for the changelog
227
class changelogRemoved extends HTMLElement {
228
constructor() {
229
super();
230
this.innerHTML = `
231
<div class="changelog-item">
232
<div class="changelog-type" removed></div>
233
${this.innerText}
234
</div>
235
`;
236
}
237
}
238
customElements.define('changelog-removed', changelogRemoved);
239
240
// Add the changelogChanged element for the changelog
241
class changelogChanged extends HTMLElement {
242
constructor() {
243
super();
244
this.innerHTML = `
245
<div class="changelog-item">
246
<div class="changelog-type" changed></div>
247
${this.innerText}
248
</div>
249
`;
250
}
251
}
252
customElements.define('changelog-changed', changelogChanged);
253
254
// Parrot theme random colors
255
function setParrotColors() {
256
var parrotColor = "rgb(195, 158, 31)"
257
var parrotColors = ["#ff4c4b", "#c39e1f", "#b42e63"]
258
259
document.querySelectorAll("*").forEach((item) => {
260
if (getComputedStyle(item).color == parrotColor) {
261
item.style.color = parrotColors[Math.floor((Math.random()*parrotColors.length))]
262
}
263
})
264
}
265
266
if (localStorage.getItem("theme") == "parrot") {
267
setParrotColors()
268
}
269
270
// Handle secret themes
271
function foundSecretTheme(name) {
272
document.body.setAttribute('theme', name);
273
localStorage.setItem('theme', name);
274
localStorage.setItem(name, 'true');
275
if (document.querySelector('.' + name)) {
276
document.querySelector('.' + name).removeAttribute('hidden');
277
}
278
}
279
280
// Handle the secret theme button
281
function secretThemeButton(name) {
282
if (localStorage.getItem(name) == 'true') {
283
if (document.querySelector('.' + name)) {
284
document.querySelector('.' + name).removeAttribute('hidden');
285
}
286
}
287
}
288
289
// Keybind themes
290
function createSecretThemeType(name, pattern) {
291
window[name + 'pattern'] = pattern;
292
window[name + 'current'] = 0;
293
294
var themePattern = window[name + 'pattern'];
295
var themeCurrent = window[name + 'current'];
296
297
// Log key presses to see if the user got the theme
298
document.addEventListener('keydown', function (e) {
299
if (e.key !== themePattern[themeCurrent]) {
300
return (themeCurrent = 0);
301
}
302
303
// Add this to the theme list
304
themeCurrent++;
305
306
if (themePattern.length == themeCurrent) {
307
themeCurrent = 0;
308
foundSecretTheme(name);
309
}
310
});
311
312
secretThemeButton(name);
313
}
314
315
// Define the cool themes, stop using this as a cheatsheet
316
createSecretThemeType('nebelung', ['ArrowUp', 'ArrowUp', 'ArrowDown', 'ArrowDown', 'ArrowLeft', 'ArrowRight', 'ArrowLeft', 'ArrowRight', 'b', 'a']);
317
createSecretThemeType('piplup', ['p', 'i', 'p', 'l', 'u', 'p', 'i', 's', 'c', 'o', 'o', 'l']);
318
createSecretThemeType('forternish', ['c', 'o', 'm', 'i', 'c', 's', 'a', 'n', 's']);
319
createSecretThemeType('russell2259', ['l', 'o', 'l']);
320
321
// Define the secret theme button, stop using this as a cheatsheet
322
secretThemeButton('hacker');
323
324
// Handle the secret theme button
325
window.nebelung_the_hacker = function () {
326
foundSecretTheme('hacker');
327
};
328
329