mirror of
https://github.com/QuiteAFancyEmerald/Holy-Unblocker.git
synced 2025-05-12 11:30:01 -04:00
added prettier properly
This commit is contained in:
parent
995183d239
commit
bdc83ba579
45 changed files with 3796 additions and 3134 deletions
1
.prettierignore
Normal file
1
.prettierignore
Normal file
|
@ -0,0 +1 @@
|
||||||
|
/lib
|
233
README.md
233
README.md
|
@ -1,4 +1,5 @@
|
||||||
<img align="left" width="70px" src="https://raw.githubusercontent.com/titaniumnetwork-dev/Holy-Unblocker/master/views/assets/img/icon.png"></img>
|
<img align="left" width="70px" src="https://raw.githubusercontent.com/titaniumnetwork-dev/Holy-Unblocker/master/views/assets/img/icon.png"></img>
|
||||||
|
|
||||||
# Holy Unblocker LTS (v6.x.x)
|
# Holy Unblocker LTS (v6.x.x)
|
||||||
|
|
||||||
Holy Unblocker LTS, an experimental web proxy service, can bypass web filters or 'blockers' regardless of whether the method of censorship is client-side or network-based. This includes the potential ability to bypass content blockers overseas, Chrome extensions, localized client firewalls, and network-related filters.
|
Holy Unblocker LTS, an experimental web proxy service, can bypass web filters or 'blockers' regardless of whether the method of censorship is client-side or network-based. This includes the potential ability to bypass content blockers overseas, Chrome extensions, localized client firewalls, and network-related filters.
|
||||||
|
@ -9,6 +10,7 @@ Works with a large number of sites, including YouTube, Discord, and more!
|
||||||
Also has a good amount of locally hosted games featured on the site.
|
Also has a good amount of locally hosted games featured on the site.
|
||||||
|
|
||||||
#### Supports
|
#### Supports
|
||||||
|
|
||||||
- Youtube.com
|
- Youtube.com
|
||||||
- Discord.com
|
- Discord.com
|
||||||
- Google.com
|
- Google.com
|
||||||
|
@ -17,8 +19,9 @@ Also has a good amount of locally hosted games featured on the site.
|
||||||
- And more sites!
|
- And more sites!
|
||||||
|
|
||||||
#### Features:
|
#### Features:
|
||||||
- Tab customization using the Options menu for improved stealth
|
|
||||||
- Considerable variety with the open selection of proxy types
|
- Tab customization using the Options menu for improved stealth
|
||||||
|
- Considerable variety with the open selection of proxy types
|
||||||
- Game library with moderately decent titles
|
- Game library with moderately decent titles
|
||||||
- Has frequent support articles for issues relating to the various proxy instances
|
- Has frequent support articles for issues relating to the various proxy instances
|
||||||
|
|
||||||
|
@ -44,23 +47,24 @@ Read below for information if the official site is blocked or for obtaining more
|
||||||
|
|
||||||
[](https://railway.app/new/template?template=https%3A%2F%2Fgithub.com%2FQuiteAFancyEmerald%2FHoly-Unblocker)
|
[](https://railway.app/new/template?template=https%3A%2F%2Fgithub.com%2FQuiteAFancyEmerald%2FHoly-Unblocker)
|
||||||
[](https://app.koyeb.com/deploy?type=git&repository=github.com/QuiteAFancyEmerald/Holy-Unblocker-Old&branch=master&name=HolyUnblocker&run_command=npm%start)
|
[](https://app.koyeb.com/deploy?type=git&repository=github.com/QuiteAFancyEmerald/Holy-Unblocker-Old&branch=master&name=HolyUnblocker&run_command=npm%start)
|
||||||
|
|
||||||
</details>
|
</details>
|
||||||
|
|
||||||
## Table of contents:
|
## Table of contents:
|
||||||
|
|
||||||
- [Setup](#how-to-setup)
|
- [Setup](#how-to-setup)
|
||||||
- [Structure](#structure)
|
- [Structure](#structure)
|
||||||
- [Structure Information](#structure-information)
|
- [Structure Information](#structure-information)
|
||||||
- [Static Files](#details-of-views)
|
- [Static Files](#details-of-views)
|
||||||
- [Scripts](#scripts-located-in-viewsassetsjs)
|
- [Scripts](#scripts-located-in-viewsassetsjs)
|
||||||
- [Future Additions](#future-additions)
|
- [Future Additions](#future-additions)
|
||||||
- [Beginner's Explanation](#vauge-explanation-for-beginners-with-external-proxies-and-hosting)
|
- [Beginner's Explanation](#vauge-explanation-for-beginners-with-external-proxies-and-hosting)
|
||||||
- [Hosting Providers](#list-of-some-good-hosting-options)
|
- [Hosting Providers](#list-of-some-good-hosting-options)
|
||||||
- [Domain Setup](#freenomdomain-steps)
|
- [Domain Setup](#freenomdomain-steps)
|
||||||
- [Cloudflare Setup](#cloudflare-steps)
|
- [Cloudflare Setup](#cloudflare-steps)
|
||||||
- [Workspace Configurations](#workspace-configurations)
|
- [Workspace Configurations](#workspace-configurations)
|
||||||
- [Detailed FAQ](#detailed-faq)
|
- [Detailed FAQ](#detailed-faq)
|
||||||
- [More Information](#more-information)
|
- [More Information](#more-information)
|
||||||
|
|
||||||
## How to Setup
|
## How to Setup
|
||||||
|
|
||||||
|
@ -81,8 +85,8 @@ The default place for the proxy when its started is `http://localhost:8080`, but
|
||||||
|
|
||||||
This website is hosted locally with Ultraviolet and Rammerhead built-in.
|
This website is hosted locally with Ultraviolet and Rammerhead built-in.
|
||||||
|
|
||||||
|
|
||||||
## Structure
|
## Structure
|
||||||
|
|
||||||
<details><summary>Web Pages</summary>
|
<details><summary>Web Pages</summary>
|
||||||
|
|
||||||
- `index.html`: The homepage of the site.
|
- `index.html`: The homepage of the site.
|
||||||
|
@ -109,15 +113,18 @@ This website is hosted locally with Ultraviolet and Rammerhead built-in.
|
||||||
</details>
|
</details>
|
||||||
|
|
||||||
### Structure Information
|
### Structure Information
|
||||||
|
|
||||||
- `/views/`: The physical site base of Holy Unblocker goes here where static assets are served.
|
- `/views/`: The physical site base of Holy Unblocker goes here where static assets are served.
|
||||||
- `/src/`: For future implementation of obfuscation and keyword removing features.
|
- `/src/`: For future implementation of obfuscation and keyword removing features.
|
||||||
|
|
||||||
#### Details of `/views/`
|
#### Details of `/views/`
|
||||||
|
|
||||||
- `/archive/` is used for game pages and vibeOS.
|
- `/archive/` is used for game pages and vibeOS.
|
||||||
- `/pages/` is used for the HTML for the site.
|
- `/pages/` is used for the HTML for the site.
|
||||||
- `/assets/` is used for storing various CSS, JS, image, and JSON files.
|
- `/assets/` is used for storing various CSS, JS, image, and JSON files.
|
||||||
|
|
||||||
#### Scripts located in `/views/assets/js/`
|
#### Scripts located in `/views/assets/js/`
|
||||||
|
|
||||||
- `bareTransport.js` is a locally installed version of the bare transport module which allows Ultraviolet to function.
|
- `bareTransport.js` is a locally installed version of the bare transport module which allows Ultraviolet to function.
|
||||||
- `card.js` adds a fancy visual effect to the box cards displayed on the welcome screen.
|
- `card.js` adds a fancy visual effect to the box cards displayed on the welcome screen.
|
||||||
- `common.js` is used on all pages and allows commonly used features to function.
|
- `common.js` is used on all pages and allows commonly used features to function.
|
||||||
|
@ -126,109 +133,114 @@ This website is hosted locally with Ultraviolet and Rammerhead built-in.
|
||||||
- `register-sw.js` creates and manages service workers that allow Ultraviolet to function, and also uses bare transport.
|
- `register-sw.js` creates and manages service workers that allow Ultraviolet to function, and also uses bare transport.
|
||||||
|
|
||||||
## Future Additions
|
## Future Additions
|
||||||
|
|
||||||
This will be our nonexhaustive todo list for Holy Unblocker LTS v6.x.x and above.
|
This will be our nonexhaustive todo list for Holy Unblocker LTS v6.x.x and above.
|
||||||
|
|
||||||
## Code Cleanup
|
## Code Cleanup
|
||||||
|
|
||||||
- [ ] Remove all current obfuscation in the source code. It needs to be dynamically obfuscated if anything, or not obfuscated at all. This option will be a config option on the server side before rendering with Express for a performance focus. Meta elements will have an additonal attribute indicating if they should be moved. This is to ensure a SEO source can be served by config or a source focused on pure censorship evasion.
|
- [ ] Remove all current obfuscation in the source code. It needs to be dynamically obfuscated if anything, or not obfuscated at all. This option will be a config option on the server side before rendering with Express for a performance focus. Meta elements will have an additonal attribute indicating if they should be moved. This is to ensure a SEO source can be served by config or a source focused on pure censorship evasion.
|
||||||
- [ ] Optimize the stylesheets and the HTML layout. Add more proper commenting and redivide the code so that it's less hard on the eyes.
|
- [ ] Optimize the stylesheets and the HTML layout. Add more proper commenting and redivide the code so that it's less hard on the eyes.
|
||||||
- [ ] Optimize the JS. This time it won't be in one line and will be somewhat thoroughly commented.
|
- [ ] Optimize the JS. This time it won't be in one line and will be somewhat thoroughly commented.
|
||||||
- [ ] Restructure navigation scripts to ensure updated proxy functionality is sanitized and effective
|
- [ ] Restructure navigation scripts to ensure updated proxy functionality is sanitized and effective
|
||||||
- [x] Particles.js automatically adjusting per display size - done
|
- [x] Particles.js automatically adjusting per display size - done
|
||||||
- [x] Fix routes.mjs throwing with incorrect paths - done
|
- [x] Fix routes.mjs throwing with incorrect paths - done
|
||||||
- [x] Create test script - done
|
- [x] Create test script - done
|
||||||
- [x] XSS and fingerprinting protection (may need updates) - done
|
- [x] XSS and fingerprinting protection (may need updates) - done
|
||||||
- [x] Update games navigation JS and page/change to JSON object system - done
|
- [x] Update games navigation JS and page/change to JSON object system - done
|
||||||
- [ ] Ensure all the original submodules get added back to HU-Archive
|
- [ ] Ensure all the original submodules get added back to HU-Archive
|
||||||
- [x] Mobile support - (welcome screen only, partial/needs work)
|
- [x] Mobile support - (welcome screen only, partial/needs work)
|
||||||
- [ ] SEO overhaul adapted from the v2 SEO Guide format
|
- [ ] SEO overhaul adapted from the v2 SEO Guide format
|
||||||
- [ ] Randomize the __uv$config global, and optionally randomize the UV prefix and URL encoding via cookies
|
- [ ] Randomize the \_\_uv$config global, and optionally randomize the UV prefix and URL encoding via cookies
|
||||||
|
|
||||||
## Proxy/Site Functionality
|
## Proxy/Site Functionality
|
||||||
- [x] Ensure Ultraviolet is updated to support bare-mux and wisp - done
|
|
||||||
- [x] Add Rammerhead support - done
|
- [x] Ensure Ultraviolet is updated to support bare-mux and wisp - done
|
||||||
- [x] Fix slow Ultraviolet speeds despite being local; something on the backend?? - done
|
- [x] Add Rammerhead support - done
|
||||||
- [x] Fix Ultraviolet on Firefox - (partial/needs work)
|
- [x] Fix slow Ultraviolet speeds despite being local; something on the backend?? - done
|
||||||
- [ ] Adapt Applications page to use either Rammerhead or UV (for Reddit, YouTube, Discord)
|
- [x] Fix Ultraviolet on Firefox - (partial/needs work)
|
||||||
- [x] libcurl, epoxy and all that fun stuff - done
|
- [ ] Adapt Applications page to use either Rammerhead or UV (for Reddit, YouTube, Discord)
|
||||||
- [x] socks5/tor routing option that can be configured (enabled) via either a cookie or pathname as a settings meny option - done
|
- [x] libcurl, epoxy and all that fun stuff - done
|
||||||
- [ ] Update games page content
|
- [x] socks5/tor routing option that can be configured (enabled) via either a cookie or pathname as a settings meny option - done
|
||||||
- [ ] Update settings menu again to make more room for more features
|
- [ ] Update games page content
|
||||||
- [x] Update csel.js (after Setting menu redesign) to support custom transports, icon swap, routing - done
|
- [ ] Update settings menu again to make more room for more features
|
||||||
- [x] Update csel.js to support network based adblocking (partial/needs work)
|
- [x] Update csel.js (after Setting menu redesign) to support custom transports, icon swap, routing - done
|
||||||
- [ ] Add a "website self-destruct" button to the settings menu
|
- [x] Update csel.js to support network based adblocking (partial/needs work)
|
||||||
- [ ] Flesh out and rework the UV / bare client error page
|
- [ ] Add a "website self-destruct" button to the settings menu
|
||||||
- [ ] Update sw.js to support workerware (https://github.com/MercuryWorkshop/workerware)
|
- [ ] Flesh out and rework the UV / bare client error page
|
||||||
- [ ] Omnibox autoupdate script (for the Google/Bing style auto suggest feature)
|
- [ ] Update sw.js to support workerware (https://github.com/MercuryWorkshop/workerware)
|
||||||
- [ ] Games library will feature 10000 items; 5000 flash games and 5000 other game types
|
- [ ] Omnibox autoupdate script (for the Google/Bing style auto suggest feature)
|
||||||
|
- [ ] Games library will feature 10000 items; 5000 flash games and 5000 other game types
|
||||||
|
|
||||||
## Site Redesign
|
## Site Redesign
|
||||||
- [x] Landing Cards - done
|
|
||||||
- [x] Change fonts to cleaner look
|
|
||||||
- [ ] Add more AOS interactions on scroll or hover
|
|
||||||
- [ ] Add subtle noise to background elements
|
|
||||||
- [ ] Update colors + add themes
|
|
||||||
- [ ] Toggle elements
|
|
||||||
- [ ] Other card options
|
|
||||||
- [ ] Radial blur elements
|
|
||||||
- [ ] Code standard examples
|
|
||||||
- [ ] Horizontal/general movement on scroll with AOS
|
|
||||||
- [ ] Showcase dev dependencies
|
|
||||||
- [ ] Update icons
|
|
||||||
- [x] Landing Page - (partial/needs work)
|
|
||||||
- [x] Settings Menu - (partial/needs work)
|
|
||||||
- [ ] More Dropdown Menu
|
|
||||||
- [ ] Web Proxies page
|
|
||||||
- [ ] Application page
|
|
||||||
- [ ] Hosting page
|
|
||||||
- [ ] Resources page
|
|
||||||
- [ ] Games Library page
|
|
||||||
- [ ] Emulators Library page
|
|
||||||
- [ ] Emu Library page
|
|
||||||
- [ ] Web Games page
|
|
||||||
- [ ] Flash Games page
|
|
||||||
- [ ] Documentation page
|
|
||||||
- [ ] FAQ page
|
|
||||||
- [ ] Credits page
|
|
||||||
- [ ] TOS page
|
|
||||||
- [x] Footer Design - (partial/needs work)
|
|
||||||
- [x] Header Design - (partial/needs work)
|
|
||||||
|
|
||||||
|
- [x] Landing Cards - done
|
||||||
|
- [x] Change fonts to cleaner look
|
||||||
|
- [ ] Add more AOS interactions on scroll or hover
|
||||||
|
- [ ] Add subtle noise to background elements
|
||||||
|
- [ ] Update colors + add themes
|
||||||
|
- [ ] Toggle elements
|
||||||
|
- [ ] Other card options
|
||||||
|
- [ ] Radial blur elements
|
||||||
|
- [ ] Code standard examples
|
||||||
|
- [ ] Horizontal/general movement on scroll with AOS
|
||||||
|
- [ ] Showcase dev dependencies
|
||||||
|
- [ ] Update icons
|
||||||
|
- [x] Landing Page - (partial/needs work)
|
||||||
|
- [x] Settings Menu - (partial/needs work)
|
||||||
|
- [ ] More Dropdown Menu
|
||||||
|
- [ ] Web Proxies page
|
||||||
|
- [ ] Application page
|
||||||
|
- [ ] Hosting page
|
||||||
|
- [ ] Resources page
|
||||||
|
- [ ] Games Library page
|
||||||
|
- [ ] Emulators Library page
|
||||||
|
- [ ] Emu Library page
|
||||||
|
- [ ] Web Games page
|
||||||
|
- [ ] Flash Games page
|
||||||
|
- [ ] Documentation page
|
||||||
|
- [ ] FAQ page
|
||||||
|
- [ ] Credits page
|
||||||
|
- [ ] TOS page
|
||||||
|
- [x] Footer Design - (partial/needs work)
|
||||||
|
- [x] Header Design - (partial/needs work)
|
||||||
|
|
||||||
## Community Requests
|
## Community Requests
|
||||||
- [ ] Add [Quake WASM](https://github.com/GMH-Code/Quake-WASM)
|
|
||||||
- [ ] Celeste WASM
|
- [ ] Add [Quake WASM](https://github.com/GMH-Code/Quake-WASM)
|
||||||
- [ ] Doom WASM
|
- [ ] Celeste WASM
|
||||||
|
- [ ] Doom WASM
|
||||||
|
|
||||||
## Changelog
|
## Changelog
|
||||||
|
|
||||||
- Added wisp support
|
- Added wisp support
|
||||||
- Fixed AD config setting being opt-out; ads are not implemented in the project however
|
- Fixed AD config setting being opt-out; ads are not implemented in the project however
|
||||||
- Added Rammerhead support (locally)
|
- Added Rammerhead support (locally)
|
||||||
- Drastically updated visuals across the service and refactored stylesheets
|
- Drastically updated visuals across the service and refactored stylesheets
|
||||||
- Bumped games page functionality
|
- Bumped games page functionality
|
||||||
- Updated randomization scripts to ES6 syntax and implemented the alternative to RegEx string replacement
|
- Updated randomization scripts to ES6 syntax and implemented the alternative to RegEx string replacement
|
||||||
- Helmet for express implemented into backend
|
- Helmet for express implemented into backend
|
||||||
- Improved component handling via templates.mjs along with deletion of obsolete files that previously handled this standard in a poor format
|
- Improved component handling via templates.mjs along with deletion of obsolete files that previously handled this standard in a poor format
|
||||||
- Fixed oddly slow speeds with Ultraviolet (as well as a general version bump to support epoxy-tls and bare-mux)
|
- Fixed oddly slow speeds with Ultraviolet (as well as a general version bump to support epoxy-tls and bare-mux)
|
||||||
- Implemented testing scripts for an improved GitHub actions workflow by doing a quick test on proxy + site functionality
|
- Implemented testing scripts for an improved GitHub actions workflow by doing a quick test on proxy + site functionality
|
||||||
- Greatly optimized client-side scripts across the site with a new standard, and generally reworked to no longer leave global variables
|
- Greatly optimized client-side scripts across the site with a new standard, and generally reworked to no longer leave global variables
|
||||||
- Changes to server.mjs with path logic and error handling
|
- Changes to server.mjs with path logic and error handling
|
||||||
- Updated standards for common scripts
|
- Updated standards for common scripts
|
||||||
- libcurl and bare-as-module support added
|
- libcurl and bare-as-module support added
|
||||||
- Deleted 5 JS scripts and moved lots of data into JSON files. Big reorganization. Games menu core scripts now nested inside of common.js utilizing a JSON system
|
- Deleted 5 JS scripts and moved lots of data into JSON files. Big reorganization. Games menu core scripts now nested inside of common.js utilizing a JSON system
|
||||||
- Massive updates to the Settings menu visually and functionality wise; added Bare-Mux support for swapping transports to work with Ultraviolet, default icons and selective adblocking + Tor on any proxy instances
|
- Massive updates to the Settings menu visually and functionality wise; added Bare-Mux support for swapping transports to work with Ultraviolet, default icons and selective adblocking + Tor on any proxy instances
|
||||||
- CSS Has been partially restructured for mobile support, and is now properly arranged into clearly labeled sections (for the most part)
|
- CSS Has been partially restructured for mobile support, and is now properly arranged into clearly labeled sections (for the most part)
|
||||||
- Incorporated makeshift domain blacklisting functionality into Ultraviolet, currently used for blocking ads if ads are disabled in settings
|
- Incorporated makeshift domain blacklisting functionality into Ultraviolet, currently used for blocking ads if ads are disabled in settings
|
||||||
- Fleshed out the SEO with more descriptions and better labeling
|
- Fleshed out the SEO with more descriptions and better labeling
|
||||||
- Switched to Fastify for serving content from the backend; a separate Express backend file is kept in case it's still needed
|
- Switched to Fastify for serving content from the backend; a separate Express backend file is kept in case it's still needed
|
||||||
- Rammerhead is now locally built into the HU LTS repository
|
- Rammerhead is now locally built into the HU LTS repository
|
||||||
- Simplified the HU LTS setup process and added more default npm commands
|
- Simplified the HU LTS setup process and added more default npm commands
|
||||||
|
|
||||||
## Vague Explanation for Beginners With External Proxies and Hosting
|
## Vague Explanation for Beginners With External Proxies and Hosting
|
||||||
|
|
||||||
You will first want to host your proxies locally or externally. OUTDATED
|
You will first want to host your proxies locally or externally. OUTDATED
|
||||||
|
|
||||||
#### List of some good hosting options:
|
#### List of some good hosting options:
|
||||||
|
|
||||||
- <a href="#">Oracle Cloud</a> (Free, Paid, Dedicated)
|
- <a href="#">Oracle Cloud</a> (Free, Paid, Dedicated)
|
||||||
- <a href="https://repl.it">Repl.it</a> (Free)
|
- <a href="https://repl.it">Repl.it</a> (Free)
|
||||||
- <a href="https://azure.microsoft.com">Azure</a> (Free and Paid)
|
- <a href="https://azure.microsoft.com">Azure</a> (Free and Paid)
|
||||||
|
@ -248,14 +260,16 @@ This is an example of DNS records involving Heroku. Self-hosting will require `A
|
||||||
As stated previously, Holy Unblocker is hosted locally with Ultraviolet.
|
As stated previously, Holy Unblocker is hosted locally with Ultraviolet.
|
||||||
|
|
||||||
#### Freenom/Domain Steps
|
#### Freenom/Domain Steps
|
||||||
|
|
||||||
For beginners, Freenom is a good provider for obtaining domains for free. However, Freenom only provides their TLDs (`.cf`, `.ml`, `.gq`, `.ga`, and `.tk`) for free, which can be easily blocked.
|
For beginners, Freenom is a good provider for obtaining domains for free. However, Freenom only provides their TLDs (`.cf`, `.ml`, `.gq`, `.ga`, and `.tk`) for free, which can be easily blocked.
|
||||||
|
|
||||||
- Get some Freenom domains then add them to your Heroku instance (Personal > [App Name] > Settings > Domains)
|
- Get some Freenom domains then add them to your Heroku instance (Personal > [App Name] > Settings > Domains)
|
||||||
Add a domain for both `www.example.cf` and `example.cf` with .cf being interchangeable with other Freenom domain names.
|
Add a domain for both `www.example.cf` and `example.cf` with .cf being interchangeable with other Freenom domain names.
|
||||||
- If you prefer to obtain premium domains (TLDs) then use <a href="https://porkbun.com">Porkbun</a>, which offers domains for amazing prices. Literally a `.net` domain normally costs around $10. On Porkbun for the first year it costs $3 so its definitely a deal.
|
- If you prefer to obtain premium domains (TLDs) then use <a href="https://porkbun.com">Porkbun</a>, which offers domains for amazing prices. Literally a `.net` domain normally costs around $10. On Porkbun for the first year it costs $3 so its definitely a deal.
|
||||||
|
|
||||||
#### Cloudflare Steps
|
#### Cloudflare Steps
|
||||||
- Use Cloudflare (make an account), add your site (Freenom Domain or other) and then add your various DNS targets to Cloudflare. Make sure you add Cloudflare's Nameservers which will be given later when you are adding your site.
|
|
||||||
|
- Use Cloudflare (make an account), add your site (Freenom Domain or other) and then add your various DNS targets to Cloudflare. Make sure you add Cloudflare's Nameservers which will be given later when you are adding your site.
|
||||||
|
|
||||||
Make sure they are CNAME although A records also work and try to follow this structure:
|
Make sure they are CNAME although A records also work and try to follow this structure:
|
||||||
|
|
||||||
|
@ -266,13 +280,12 @@ Make sure they are CNAME although A records also work and try to follow this str
|
||||||
|
|
||||||
**Below are if you want external proxies also with your site:**
|
**Below are if you want external proxies also with your site:**
|
||||||
|
|
||||||
`CNAME | a | your-womginx-instance-here.herokudns.com`
|
`CNAME | a | your-womginx-instance-here.herokudns.com`
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Make sure HTTPS is forced and have SSL set to Flexible for some services. Otherwise you can have SSL set to Full.
|
Make sure HTTPS is forced and have SSL set to Flexible for some services. Otherwise you can have SSL set to Full.
|
||||||
|
|
||||||
#### Workspace Configurations
|
#### Workspace Configurations
|
||||||
|
|
||||||
Preferably if you have your own device use Visual Studio Code. Pretty much the best option you can get but obviously this is an opinion. Also make sure you have <a href="https://nodejs.org/">Node.JS</a> installed on your machine.
|
Preferably if you have your own device use Visual Studio Code. Pretty much the best option you can get but obviously this is an opinion. Also make sure you have <a href="https://nodejs.org/">Node.JS</a> installed on your machine.
|
||||||
|
|
||||||
Not going to go too in depth with this part but first fork this repository. The clone it locally through a Terminal of some sort depending on what OS you are on. Make sure you navigate to the folder you want to set this up in.
|
Not going to go too in depth with this part but first fork this repository. The clone it locally through a Terminal of some sort depending on what OS you are on. Make sure you navigate to the folder you want to set this up in.
|
||||||
|
@ -294,16 +307,19 @@ node_modules
|
||||||
Now you have your following workspace environment setup. To deploy the following workspace you just created you will need to look up depending on your hosting provider.
|
Now you have your following workspace environment setup. To deploy the following workspace you just created you will need to look up depending on your hosting provider.
|
||||||
|
|
||||||
For an online IDE that you can use on your school computer and/or chromebook use GitPod. Basically the equivalent of Visual Studio Code but with in-browser support.
|
For an online IDE that you can use on your school computer and/or chromebook use GitPod. Basically the equivalent of Visual Studio Code but with in-browser support.
|
||||||
|
|
||||||
- Make an account: `https://gitpod.io/`
|
- Make an account: `https://gitpod.io/`
|
||||||
- Fork this repo and enter in this URL to setup your workspace: `https://gitpod.io#https://github.com/YourNameHere/Holy-Unblocker/`
|
- Fork this repo and enter in this URL to setup your workspace: `https://gitpod.io#https://github.com/YourNameHere/Holy-Unblocker/`
|
||||||
|
|
||||||
Use the same steps above by running `npm install` in your repository and adding a `.gitignore` in your root directory specifying to exclude `node_modules`.
|
Use the same steps above by running `npm install` in your repository and adding a `.gitignore` in your root directory specifying to exclude `node_modules`.
|
||||||
|
|
||||||
## Detailed FAQ
|
## Detailed FAQ
|
||||||
|
|
||||||
<details>
|
<details>
|
||||||
<summary>Quick FAQ</summary>
|
<summary>Quick FAQ</summary>
|
||||||
|
|
||||||
#### Where can I find the games for this repo? (404 errors, etc.)
|
#### Where can I find the games for this repo? (404 errors, etc.)
|
||||||
|
|
||||||
Due to piracy concerns, size, etc. this has been moved over <a href="https://github.com/QuiteAFancyEmerald/HU-Archive">here</a>. EmuLibrary is not featured in the public version.
|
Due to piracy concerns, size, etc. this has been moved over <a href="https://github.com/QuiteAFancyEmerald/HU-Archive">here</a>. EmuLibrary is not featured in the public version.
|
||||||
|
|
||||||
**Why is the site I am on not working correctly or having CAPTCHA errors?**
|
**Why is the site I am on not working correctly or having CAPTCHA errors?**
|
||||||
|
@ -319,6 +335,7 @@ If you still have any questions feel free to ask them in the discord linked here
|
||||||
</details>
|
</details>
|
||||||
|
|
||||||
### Why are official domains now numbered? Is this project maintained again?
|
### Why are official domains now numbered? Is this project maintained again?
|
||||||
|
|
||||||
Yes, this project is active again for LTS support! However, the approach is now much simpler to ensure functionality: traffic will be focused on a single domain. More than ever, this project serves as a proof of concept for the brave souls willing to innovate in the web proxy service space.
|
Yes, this project is active again for LTS support! However, the approach is now much simpler to ensure functionality: traffic will be focused on a single domain. More than ever, this project serves as a proof of concept for the brave souls willing to innovate in the web proxy service space.
|
||||||
|
|
||||||
<details><summary>Former Closing Message (Original - 2022)</summary>
|
<details><summary>Former Closing Message (Original - 2022)</summary>
|
||||||
|
@ -329,7 +346,7 @@ The main change of thought is that I’m finally just putting an end right now d
|
||||||
|
|
||||||
Some things I’ll be keeping secret since there are more reasons to this choice unless otherwise for those who don’t find this enough information. Good friends here will know that I’ve been super stressed about this choice for months now. Also regardless a good motivator for this choice is the fact that I’ll be graduating soon.
|
Some things I’ll be keeping secret since there are more reasons to this choice unless otherwise for those who don’t find this enough information. Good friends here will know that I’ve been super stressed about this choice for months now. Also regardless a good motivator for this choice is the fact that I’ll be graduating soon.
|
||||||
|
|
||||||
It’s possible that I may continue/come back for this in the future or keep it on GitHub only. I leave this here because even now I am still doubting myself about this change. But for now I’d check out other proxy sites like Incognito (Duce DOES a ton of updates frequently and he is the creator/developer of Ultraviolet so give him some love) :yayy_hopi:
|
It’s possible that I may continue/come back for this in the future or keep it on GitHub only. I leave this here because even now I am still doubting myself about this change. But for now I’d check out other proxy sites like Incognito (Duce DOES a ton of updates frequently and he is the creator/developer of Ultraviolet so give him some love) :yayy_hopi:
|
||||||
|
|
||||||
Check out his Patreon also! For current HU patrons you will not be billed next month and the HU Patreon will be archived so head over to Duce’s patron so he can purchase more domains for Incognito.
|
Check out his Patreon also! For current HU patrons you will not be billed next month and the HU Patreon will be archived so head over to Duce’s patron so he can purchase more domains for Incognito.
|
||||||
|
|
||||||
|
@ -338,8 +355,8 @@ Emerald :HuTaoHype:
|
||||||
|
|
||||||
</details>
|
</details>
|
||||||
|
|
||||||
|
|
||||||
## More Information
|
## More Information
|
||||||
|
|
||||||
This project is maintained by the Holy Unblocker LTS team and is an official flagship Titanium Network web proxy site.
|
This project is maintained by the Holy Unblocker LTS team and is an official flagship Titanium Network web proxy site.
|
||||||
|
|
||||||
- <a href="https://github.com/titaniumnetwork-dev/">https://github.com/titaniumnetwork-dev/</a>
|
- <a href="https://github.com/titaniumnetwork-dev/">https://github.com/titaniumnetwork-dev/</a>
|
||||||
|
@ -348,6 +365,7 @@ This project is maintained by the Holy Unblocker LTS team and is an official fla
|
||||||
View the official website for more detail and credits.
|
View the official website for more detail and credits.
|
||||||
|
|
||||||
### Web Proxy Sources:
|
### Web Proxy Sources:
|
||||||
|
|
||||||
This project currently uses Ultraviolet, Wisp, Womginx, and Rammerhead, linked below.
|
This project currently uses Ultraviolet, Wisp, Womginx, and Rammerhead, linked below.
|
||||||
|
|
||||||
- <a href="https://github.com/titaniumnetwork-dev/Ultraviolet">Ultraviolet</a>
|
- <a href="https://github.com/titaniumnetwork-dev/Ultraviolet">Ultraviolet</a>
|
||||||
|
@ -357,7 +375,6 @@ This project currently uses Ultraviolet, Wisp, Womginx, and Rammerhead, linked b
|
||||||
- <a href="https://github.com/MercuryWorkshop/bare-mux">Bare-Mux</a>
|
- <a href="https://github.com/MercuryWorkshop/bare-mux">Bare-Mux</a>
|
||||||
- <a href="https://github.com/tomphttp/bare-server-node">TOMP Bare Server</a>
|
- <a href="https://github.com/tomphttp/bare-server-node">TOMP Bare Server</a>
|
||||||
|
|
||||||
|
|
||||||
### Other Dependencies:
|
### Other Dependencies:
|
||||||
|
|
||||||
- <a href="https://github.com/tsparticles/tsparticles">tsparticles</a>
|
- <a href="https://github.com/tsparticles/tsparticles">tsparticles</a>
|
||||||
|
|
170
TODO.md
170
TODO.md
|
@ -2,97 +2,99 @@ This will be our nonexhaustive todo list for Holy Unblocker LTS v6.x.x and above
|
||||||
|
|
||||||
## Code Cleanup
|
## Code Cleanup
|
||||||
|
|
||||||
- [ ] Remove all current obfuscation in the source code. It needs to be dynamically obfuscated if anything, or not obfuscated at all. This option will be a config option on the server side before rendering with Express for a performance focus. Meta elements will have an additonal attribute indicating if they should be moved. This is to ensure a SEO source can be served by config or a source focused on pure censorship evasion.
|
- [ ] Remove all current obfuscation in the source code. It needs to be dynamically obfuscated if anything, or not obfuscated at all. This option will be a config option on the server side before rendering with Express for a performance focus. Meta elements will have an additonal attribute indicating if they should be moved. This is to ensure a SEO source can be served by config or a source focused on pure censorship evasion.
|
||||||
- [ ] Optimize the stylesheets and the HTML layout. Add more proper commenting and redivide the code so that it's less hard on the eyes.
|
- [ ] Optimize the stylesheets and the HTML layout. Add more proper commenting and redivide the code so that it's less hard on the eyes.
|
||||||
- [ ] Optimize the JS. This time it won't be in one line and will be somewhat thoroughly commented.
|
- [ ] Optimize the JS. This time it won't be in one line and will be somewhat thoroughly commented.
|
||||||
- [ ] Restructure navigation scripts to ensure updated proxy functionality is sanitized and effective
|
- [ ] Restructure navigation scripts to ensure updated proxy functionality is sanitized and effective
|
||||||
- [x] Particles.js automatically adjusting per display size - done
|
- [x] Particles.js automatically adjusting per display size - done
|
||||||
- [x] Fix routes.mjs throwing with incorrect paths - done
|
- [x] Fix routes.mjs throwing with incorrect paths - done
|
||||||
- [x] Create test script - done
|
- [x] Create test script - done
|
||||||
- [x] XSS and fingerprinting protection (may need updates) - done
|
- [x] XSS and fingerprinting protection (may need updates) - done
|
||||||
- [x] Update games navigation JS and page/change to JSON object system - done
|
- [x] Update games navigation JS and page/change to JSON object system - done
|
||||||
- [ ] Ensure all the original submodules get added back to HU-Archive
|
- [ ] Ensure all the original submodules get added back to HU-Archive
|
||||||
- [x] Mobile support - (welcome screen only, partial/needs work)
|
- [x] Mobile support - (welcome screen only, partial/needs work)
|
||||||
- [ ] SEO overhaul adapted from the v2 SEO Guide format
|
- [ ] SEO overhaul adapted from the v2 SEO Guide format
|
||||||
- [ ] Randomize the __uv$config global, and optionally randomize the UV prefix and URL encoding via cookies
|
- [ ] Randomize the \_\_uv$config global, and optionally randomize the UV prefix and URL encoding via cookies
|
||||||
|
|
||||||
## Proxy/Site Functionality
|
## Proxy/Site Functionality
|
||||||
- [x] Ensure Ultraviolet is updated to support bare-mux and wisp - done
|
|
||||||
- [x] Add Rammerhead support - done
|
- [x] Ensure Ultraviolet is updated to support bare-mux and wisp - done
|
||||||
- [x] Fix slow Ultraviolet speeds despite being local; something on the backend?? - done
|
- [x] Add Rammerhead support - done
|
||||||
- [x] Fix Ultraviolet on Firefox - (partial/needs work)
|
- [x] Fix slow Ultraviolet speeds despite being local; something on the backend?? - done
|
||||||
- [ ] Adapt Applications page to use either Rammerhead or UV (for Reddit, YouTube, Discord)
|
- [x] Fix Ultraviolet on Firefox - (partial/needs work)
|
||||||
- [x] libcurl, epoxy and all that fun stuff - done
|
- [ ] Adapt Applications page to use either Rammerhead or UV (for Reddit, YouTube, Discord)
|
||||||
- [x] socks5/tor routing option that can be configured (enabled) via either a cookie or pathname as a settings meny option - done
|
- [x] libcurl, epoxy and all that fun stuff - done
|
||||||
- [ ] Update games page content
|
- [x] socks5/tor routing option that can be configured (enabled) via either a cookie or pathname as a settings meny option - done
|
||||||
- [ ] Update settings menu again to make more room for more features
|
- [ ] Update games page content
|
||||||
- [x] Update csel.js (after Setting menu redesign) to support custom transports, icon swap, routing - done
|
- [ ] Update settings menu again to make more room for more features
|
||||||
- [x] Update csel.js to support network based adblocking (partial/needs work)
|
- [x] Update csel.js (after Setting menu redesign) to support custom transports, icon swap, routing - done
|
||||||
- [ ] Add a "website self-destruct" button to the settings menu
|
- [x] Update csel.js to support network based adblocking (partial/needs work)
|
||||||
- [ ] Flesh out and rework the UV / bare client error page
|
- [ ] Add a "website self-destruct" button to the settings menu
|
||||||
- [ ] Update sw.js to support workerware (https://github.com/MercuryWorkshop/workerware)
|
- [ ] Flesh out and rework the UV / bare client error page
|
||||||
- [ ] Omnibox autoupdate script (for the Google/Bing style auto suggest feature)
|
- [ ] Update sw.js to support workerware (https://github.com/MercuryWorkshop/workerware)
|
||||||
- [ ] Games library will feature 10000 items; 5000 flash games and 5000 other game types
|
- [ ] Omnibox autoupdate script (for the Google/Bing style auto suggest feature)
|
||||||
|
- [ ] Games library will feature 10000 items; 5000 flash games and 5000 other game types
|
||||||
|
|
||||||
## Site Redesign
|
## Site Redesign
|
||||||
- [x] Landing Cards - done
|
|
||||||
- [x] Change fonts to cleaner look
|
|
||||||
- [ ] Add more AOS interactions on scroll or hover
|
|
||||||
- [ ] Add subtle noise to background elements
|
|
||||||
- [ ] Update colors + add themes
|
|
||||||
- [ ] Toggle elements
|
|
||||||
- [ ] Other card options
|
|
||||||
- [ ] Radial blur elements
|
|
||||||
- [ ] Code standard examples
|
|
||||||
- [ ] Horizontal/general movement on scroll with AOS
|
|
||||||
- [ ] Showcase dev dependencies
|
|
||||||
- [ ] Update icons
|
|
||||||
- [x] Landing Page - (partial/needs work)
|
|
||||||
- [x] Settings Menu - (partial/needs work)
|
|
||||||
- [ ] More Dropdown Menu
|
|
||||||
- [ ] Web Proxies page
|
|
||||||
- [ ] Application page
|
|
||||||
- [ ] Hosting page
|
|
||||||
- [ ] Resources page
|
|
||||||
- [ ] Games Library page
|
|
||||||
- [ ] Emulators Library page
|
|
||||||
- [ ] Emu Library page
|
|
||||||
- [ ] Web Games page
|
|
||||||
- [ ] Flash Games page
|
|
||||||
- [ ] Documentation page
|
|
||||||
- [ ] FAQ page
|
|
||||||
- [ ] Credits page
|
|
||||||
- [ ] TOS page
|
|
||||||
- [x] Footer Design - (partial/needs work)
|
|
||||||
- [x] Header Design - (partial/needs work)
|
|
||||||
|
|
||||||
|
- [x] Landing Cards - done
|
||||||
|
- [x] Change fonts to cleaner look
|
||||||
|
- [ ] Add more AOS interactions on scroll or hover
|
||||||
|
- [ ] Add subtle noise to background elements
|
||||||
|
- [ ] Update colors + add themes
|
||||||
|
- [ ] Toggle elements
|
||||||
|
- [ ] Other card options
|
||||||
|
- [ ] Radial blur elements
|
||||||
|
- [ ] Code standard examples
|
||||||
|
- [ ] Horizontal/general movement on scroll with AOS
|
||||||
|
- [ ] Showcase dev dependencies
|
||||||
|
- [ ] Update icons
|
||||||
|
- [x] Landing Page - (partial/needs work)
|
||||||
|
- [x] Settings Menu - (partial/needs work)
|
||||||
|
- [ ] More Dropdown Menu
|
||||||
|
- [ ] Web Proxies page
|
||||||
|
- [ ] Application page
|
||||||
|
- [ ] Hosting page
|
||||||
|
- [ ] Resources page
|
||||||
|
- [ ] Games Library page
|
||||||
|
- [ ] Emulators Library page
|
||||||
|
- [ ] Emu Library page
|
||||||
|
- [ ] Web Games page
|
||||||
|
- [ ] Flash Games page
|
||||||
|
- [ ] Documentation page
|
||||||
|
- [ ] FAQ page
|
||||||
|
- [ ] Credits page
|
||||||
|
- [ ] TOS page
|
||||||
|
- [x] Footer Design - (partial/needs work)
|
||||||
|
- [x] Header Design - (partial/needs work)
|
||||||
|
|
||||||
## Community Requests
|
## Community Requests
|
||||||
- [ ] Add [Quake WASM](https://github.com/GMH-Code/Quake-WASM)
|
|
||||||
- [ ] Celeste WASM
|
- [ ] Add [Quake WASM](https://github.com/GMH-Code/Quake-WASM)
|
||||||
- [ ] Doom WASM
|
- [ ] Celeste WASM
|
||||||
|
- [ ] Doom WASM
|
||||||
|
|
||||||
## Changelog
|
## Changelog
|
||||||
|
|
||||||
- Added wisp support
|
- Added wisp support
|
||||||
- Fixed AD config setting being opt-out; ads are not implemented in the project however
|
- Fixed AD config setting being opt-out; ads are not implemented in the project however
|
||||||
- Added Rammerhead support (locally)
|
- Added Rammerhead support (locally)
|
||||||
- Drastically updated visuals across the service and refactored stylesheets
|
- Drastically updated visuals across the service and refactored stylesheets
|
||||||
- Bumped games page functionality
|
- Bumped games page functionality
|
||||||
- Updated randomization scripts to ES6 syntax and implemented the alternative to RegEx string replacement
|
- Updated randomization scripts to ES6 syntax and implemented the alternative to RegEx string replacement
|
||||||
- Helmet for express implemented into backend
|
- Helmet for express implemented into backend
|
||||||
- Improved component handling via templates.mjs along with deletion of obsolete files that previously handled this standard in a poor format
|
- Improved component handling via templates.mjs along with deletion of obsolete files that previously handled this standard in a poor format
|
||||||
- Fixed oddly slow speeds with Ultraviolet (as well as a general version bump to support epoxy-tls and bare-mux)
|
- Fixed oddly slow speeds with Ultraviolet (as well as a general version bump to support epoxy-tls and bare-mux)
|
||||||
- Implemented testing scripts for an improved GitHub actions workflow by doing a quick test on proxy + site functionality
|
- Implemented testing scripts for an improved GitHub actions workflow by doing a quick test on proxy + site functionality
|
||||||
- Greatly optimized client-side scripts across the site with a new standard, and generally reworked to no longer leave global variables
|
- Greatly optimized client-side scripts across the site with a new standard, and generally reworked to no longer leave global variables
|
||||||
- Changes to server.mjs with path logic and error handling
|
- Changes to server.mjs with path logic and error handling
|
||||||
- Updated standards for common scripts
|
- Updated standards for common scripts
|
||||||
- libcurl and bare-as-module support added
|
- libcurl and bare-as-module support added
|
||||||
- Deleted 5 JS scripts and moved lots of data into JSON files. Big reorganization. Games menu core scripts now nested inside of common.js utilizing a JSON system
|
- Deleted 5 JS scripts and moved lots of data into JSON files. Big reorganization. Games menu core scripts now nested inside of common.js utilizing a JSON system
|
||||||
- Massive updates to the Settings menu visually and functionality wise; added Bare-Mux support for swapping transports to work with Ultraviolet, default icons and selective adblocking + Tor on any proxy instances
|
- Massive updates to the Settings menu visually and functionality wise; added Bare-Mux support for swapping transports to work with Ultraviolet, default icons and selective adblocking + Tor on any proxy instances
|
||||||
- CSS Has been partially restructured for mobile support, and is now properly arranged into clearly labeled sections (for the most part)
|
- CSS Has been partially restructured for mobile support, and is now properly arranged into clearly labeled sections (for the most part)
|
||||||
- Incorporated makeshift domain blacklisting functionality into Ultraviolet, currently used for blocking ads if ads are disabled in settings
|
- Incorporated makeshift domain blacklisting functionality into Ultraviolet, currently used for blocking ads if ads are disabled in settings
|
||||||
- Fleshed out the SEO with more descriptions and better labeling
|
- Fleshed out the SEO with more descriptions and better labeling
|
||||||
- Switched to Fastify for serving content from the backend; a separate Express backend file is kept in case it's still needed
|
- Switched to Fastify for serving content from the backend; a separate Express backend file is kept in case it's still needed
|
||||||
- Rammerhead is now locally built into the HU LTS repository
|
- Rammerhead is now locally built into the HU LTS repository
|
||||||
- Simplified the HU LTS setup process and added more default npm commands
|
- Simplified the HU LTS setup process and added more default npm commands
|
||||||
|
|
|
@ -1,3 +1,3 @@
|
||||||
(async () => {
|
(async () => {
|
||||||
await import("./src/server.mjs");
|
await import('./src/server.mjs');
|
||||||
})();
|
})();
|
||||||
|
|
|
@ -1,22 +1,22 @@
|
||||||
module.exports = {
|
module.exports = {
|
||||||
apps: [
|
apps: [
|
||||||
{
|
{
|
||||||
name: "HolyUB",
|
name: 'HolyUB',
|
||||||
script: "./backend.js",
|
script: './backend.js',
|
||||||
env: {
|
env: {
|
||||||
PORT: 8080,
|
PORT: 8080,
|
||||||
NODE_ENV: "development",
|
NODE_ENV: 'development',
|
||||||
},
|
},
|
||||||
env_production: {
|
env_production: {
|
||||||
PORT: 8080,
|
PORT: 8080,
|
||||||
NODE_ENV: "production",
|
NODE_ENV: 'production',
|
||||||
},
|
},
|
||||||
instances: "1",
|
instances: '1',
|
||||||
exec_interpreter: "babel-node",
|
exec_interpreter: 'babel-node',
|
||||||
exec_mode: "fork",
|
exec_mode: 'fork',
|
||||||
autorestart: true,
|
autorestart: true,
|
||||||
exp_backoff_restart_delay: 100,
|
exp_backoff_restart_delay: 100,
|
||||||
cron_restart: "*/10 * * * *",
|
cron_restart: '*/10 * * * *',
|
||||||
kill_timeout: 3000,
|
kill_timeout: 3000,
|
||||||
watch: false,
|
watch: false,
|
||||||
},
|
},
|
||||||
|
|
16
prettier.config.js
Normal file
16
prettier.config.js
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
module.exports = {
|
||||||
|
printWidth: 80, // Wrap lines at 80 characters
|
||||||
|
tabWidth: 2, // Use 2 spaces per indentation level
|
||||||
|
useTabs: false, // Use spaces instead of tabs
|
||||||
|
semi: true, // Add a semicolon at the end of every statement
|
||||||
|
singleQuote: true, // Use single quotes instead of double quotes
|
||||||
|
quoteProps: 'as-needed', // Only add quotes around object properties where required
|
||||||
|
jsxSingleQuote: false, // Use double quotes in JSX
|
||||||
|
trailingComma: 'es5', // Add trailing commas where valid in ES5 (objects, arrays, etc.)
|
||||||
|
bracketSpacing: true, // Print spaces between brackets in object literals
|
||||||
|
jsxBracketSameLine: false, // Put the `>` of a multi-line JSX element at the end of the last line
|
||||||
|
arrowParens: 'always', // Always include parentheses around arrow function arguments
|
||||||
|
htmlWhitespaceSensitivity: 'css', // Respect the default value of CSS display property
|
||||||
|
endOfLine: 'lf', // Use line feed only (\n) for newlines
|
||||||
|
embeddedLanguageFormatting: 'auto', // Format embedded code if Prettier can automatically identify it
|
||||||
|
};
|
|
@ -1,10 +1,10 @@
|
||||||
// This file is solely used for the automatically run GitHub job, which checks to
|
// This file is solely used for the automatically run GitHub job, which checks to
|
||||||
// see if all HU LTS code is working properly (at least on an Ubuntu machine).
|
// see if all HU LTS code is working properly (at least on an Ubuntu machine).
|
||||||
|
|
||||||
const axios = require("axios");
|
const axios = require('axios');
|
||||||
const puppeteer = require("puppeteer");
|
const puppeteer = require('puppeteer');
|
||||||
|
|
||||||
const testEndpoint = async url => {
|
const testEndpoint = async (url) => {
|
||||||
try {
|
try {
|
||||||
const response = await axios.get(url);
|
const response = await axios.get(url);
|
||||||
return response.status === 200;
|
return response.status === 200;
|
||||||
|
@ -29,58 +29,58 @@ const testGeneratedUrl = async (url, headers) => {
|
||||||
|
|
||||||
const testServerResponse = async () => {
|
const testServerResponse = async () => {
|
||||||
const endpoints = [
|
const endpoints = [
|
||||||
"http://localhost:8080/",
|
'http://localhost:8080/',
|
||||||
"http://localhost:8080/test-404",
|
'http://localhost:8080/test-404',
|
||||||
"http://localhost:8080/browsing",
|
'http://localhost:8080/browsing',
|
||||||
"http://localhost:8080/rammerhead",
|
'http://localhost:8080/rammerhead',
|
||||||
"http://localhost:8080/ultraviolet",
|
'http://localhost:8080/ultraviolet',
|
||||||
"http://localhost:8080/documentation",
|
'http://localhost:8080/documentation',
|
||||||
"http://localhost:8080/questions",
|
'http://localhost:8080/questions',
|
||||||
"http://localhost:8080/s",
|
'http://localhost:8080/s',
|
||||||
"http://localhost:8080/credits",
|
'http://localhost:8080/credits',
|
||||||
"http://localhost:8080/bookmarklets",
|
'http://localhost:8080/bookmarklets',
|
||||||
"http://localhost:8080/terms",
|
'http://localhost:8080/terms',
|
||||||
"http://localhost:8080/games",
|
'http://localhost:8080/games',
|
||||||
"http://localhost:8080/web-games",
|
'http://localhost:8080/web-games',
|
||||||
"http://localhost:8080/emulators",
|
'http://localhost:8080/emulators',
|
||||||
"http://localhost:8080/flash-games",
|
'http://localhost:8080/flash-games',
|
||||||
"http://localhost:8080/retro-games",
|
'http://localhost:8080/retro-games',
|
||||||
"http://localhost:8080/youtube",
|
'http://localhost:8080/youtube',
|
||||||
"http://localhost:8080/apps",
|
'http://localhost:8080/apps',
|
||||||
"http://localhost:8080/flash",
|
'http://localhost:8080/flash',
|
||||||
"http://localhost:8080/webretro",
|
'http://localhost:8080/webretro',
|
||||||
"http://localhost:8080/vibe-os",
|
'http://localhost:8080/vibe-os',
|
||||||
"http://localhost:8080/assets/js/particlesjs/particles.js",
|
'http://localhost:8080/assets/js/particlesjs/particles.js',
|
||||||
"http://localhost:8080/assets/js/bareTransport.js",
|
'http://localhost:8080/assets/js/bareTransport.js',
|
||||||
"http://localhost:8080/assets/js/card.js",
|
'http://localhost:8080/assets/js/card.js',
|
||||||
"http://localhost:8080/assets/js/common-16451543478.js",
|
'http://localhost:8080/assets/js/common-16451543478.js',
|
||||||
"http://localhost:8080/assets/js/csel.js",
|
'http://localhost:8080/assets/js/csel.js',
|
||||||
"http://localhost:8080/assets/js/register-sw.js",
|
'http://localhost:8080/assets/js/register-sw.js',
|
||||||
"http://localhost:8080/assets/json/emu-nav.json",
|
'http://localhost:8080/assets/json/emu-nav.json',
|
||||||
"http://localhost:8080/assets/json/blacklist.json",
|
'http://localhost:8080/assets/json/blacklist.json',
|
||||||
"http://localhost:8080/assets/json/emulib-nav.json",
|
'http://localhost:8080/assets/json/emulib-nav.json',
|
||||||
"http://localhost:8080/assets/json/flash-nav.json",
|
'http://localhost:8080/assets/json/flash-nav.json',
|
||||||
"http://localhost:8080/assets/json/h5-nav.json",
|
'http://localhost:8080/assets/json/h5-nav.json',
|
||||||
"http://localhost:8080/assets/json/links.json",
|
'http://localhost:8080/assets/json/links.json',
|
||||||
"http://localhost:8080/baremux/index.js",
|
'http://localhost:8080/baremux/index.js',
|
||||||
"http://localhost:8080/baremux/worker.js",
|
'http://localhost:8080/baremux/worker.js',
|
||||||
"http://localhost:8080/epoxy/index.mjs",
|
'http://localhost:8080/epoxy/index.mjs',
|
||||||
"http://localhost:8080/uv/uv.bundle.js",
|
'http://localhost:8080/uv/uv.bundle.js',
|
||||||
"http://localhost:8080/uv/sw.js",
|
'http://localhost:8080/uv/sw.js',
|
||||||
"http://localhost:8080/uv/uv.config.js",
|
'http://localhost:8080/uv/uv.config.js',
|
||||||
"http://localhost:8080/uv/workerware.js",
|
'http://localhost:8080/uv/workerware.js',
|
||||||
"http://localhost:8080/uv/WWError.js"
|
'http://localhost:8080/uv/WWError.js',
|
||||||
];
|
];
|
||||||
|
|
||||||
const results = await Promise.all(endpoints.map(testEndpoint));
|
const results = await Promise.all(endpoints.map(testEndpoint));
|
||||||
const allPassed = results.every((result) => result);
|
const allPassed = results.every((result) => result);
|
||||||
|
|
||||||
if (allPassed) {
|
if (allPassed) {
|
||||||
console.log("All endpoints responded with status code 200. Test passed.");
|
console.log('All endpoints responded with status code 200. Test passed.');
|
||||||
await testCommonJSOnPage();
|
await testCommonJSOnPage();
|
||||||
} else {
|
} else {
|
||||||
console.error(
|
console.error(
|
||||||
"One or more endpoints failed to respond with status code 200. Test failed."
|
'One or more endpoints failed to respond with status code 200. Test failed.'
|
||||||
);
|
);
|
||||||
process.exitCode = 1;
|
process.exitCode = 1;
|
||||||
}
|
}
|
||||||
|
@ -89,9 +89,9 @@ const testServerResponse = async () => {
|
||||||
const testCommonJSOnPage = async () => {
|
const testCommonJSOnPage = async () => {
|
||||||
const browser = await puppeteer.launch({
|
const browser = await puppeteer.launch({
|
||||||
args: [
|
args: [
|
||||||
"--enable-features=NetworkService",
|
'--enable-features=NetworkService',
|
||||||
"--enable-features=ServiceWorker",
|
'--enable-features=ServiceWorker',
|
||||||
"--enable-features=InsecureOrigins",
|
'--enable-features=InsecureOrigins',
|
||||||
],
|
],
|
||||||
headless: true,
|
headless: true,
|
||||||
ignoreHTTPSErrors: true,
|
ignoreHTTPSErrors: true,
|
||||||
|
@ -102,73 +102,75 @@ const testCommonJSOnPage = async () => {
|
||||||
const getHeaders = async () => {
|
const getHeaders = async () => {
|
||||||
const headers = {};
|
const headers = {};
|
||||||
|
|
||||||
headers["User-Agent"] = await page.evaluate(() => navigator.userAgent);
|
headers['User-Agent'] = await page.evaluate(() => navigator.userAgent);
|
||||||
headers["Referer"] = await page.evaluate(() => window.location.href);
|
headers['Referer'] = await page.evaluate(() => window.location.href);
|
||||||
|
|
||||||
return headers;
|
return headers;
|
||||||
};
|
};
|
||||||
|
|
||||||
const testRammerhead = async () => {
|
const testRammerhead = async () => {
|
||||||
await page.goto("http://localhost:8080/rammerhead");
|
await page.goto('http://localhost:8080/rammerhead');
|
||||||
|
|
||||||
const testResults = await page.evaluate(async () => {
|
const testResults = await page.evaluate(async () => {
|
||||||
const results = {};
|
const results = {};
|
||||||
|
|
||||||
await new Promise((resolve) => {
|
await new Promise((resolve) => {
|
||||||
if (document.readyState === "complete") {
|
if (document.readyState === 'complete') {
|
||||||
resolve();
|
resolve();
|
||||||
} else {
|
} else {
|
||||||
window.addEventListener("load", resolve);
|
window.addEventListener('load', resolve);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// Locate the omnibox element on the Rammerhead page.
|
// Locate the omnibox element on the Rammerhead page.
|
||||||
let omnibox = document.getElementById("pr-rh");
|
let omnibox = document.getElementById('pr-rh');
|
||||||
omnibox = omnibox && omnibox.querySelector("input[type=text]");
|
omnibox = omnibox && omnibox.querySelector('input[type=text]');
|
||||||
|
|
||||||
if (omnibox) {
|
if (omnibox) {
|
||||||
try {
|
try {
|
||||||
// Send an artificial input to the omnibox. The omnibox will create
|
// Send an artificial input to the omnibox. The omnibox will create
|
||||||
// a proxy URL and leave it as the input value in response.
|
// a proxy URL and leave it as the input value in response.
|
||||||
const urlPath = "example.com";
|
const urlPath = 'example.com';
|
||||||
omnibox.value = urlPath;
|
omnibox.value = urlPath;
|
||||||
await omnibox.dispatchEvent(
|
await omnibox.dispatchEvent(
|
||||||
new KeyboardEvent("keydown", {code: "Validator Test"})
|
new KeyboardEvent('keydown', { code: 'Validator Test' })
|
||||||
);
|
);
|
||||||
|
|
||||||
// Wait up to 5 seconds for the omnibox to finish updating.
|
// Wait up to 5 seconds for the omnibox to finish updating.
|
||||||
const loadUrl = new Promise(resolve => {
|
const loadUrl = new Promise((resolve) => {
|
||||||
if (omnibox.value !== urlPath) resolve(omnibox.value);
|
if (omnibox.value !== urlPath) resolve(omnibox.value);
|
||||||
else omnibox.addEventListener("change", () => resolve(omnibox.value));
|
else
|
||||||
}),
|
omnibox.addEventListener('change', () =>
|
||||||
timeout = new Promise(resolve => {
|
resolve(omnibox.value)
|
||||||
setTimeout(() => resolve(omnibox.value), 40000);
|
);
|
||||||
}),
|
}),
|
||||||
|
timeout = new Promise((resolve) => {
|
||||||
// Record the proxy URL that the omnibox left here.
|
setTimeout(() => resolve(omnibox.value), 40000);
|
||||||
rammerheadUrl = await Promise.race([loadUrl, timeout]);
|
}),
|
||||||
console.log("Generated Rammerhead URL:", rammerheadUrl);
|
// Record the proxy URL that the omnibox left here.
|
||||||
results.rammerhead = rammerheadUrl ? rammerheadUrl : "failure";
|
rammerheadUrl = await Promise.race([loadUrl, timeout]);
|
||||||
|
console.log('Generated Rammerhead URL:', rammerheadUrl);
|
||||||
|
results.rammerhead = rammerheadUrl ? rammerheadUrl : 'failure';
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
results.rammerhead = "failure: " + e.message;
|
results.rammerhead = 'failure: ' + e.message;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
results.goProx = "not defined";
|
results.goProx = 'not defined';
|
||||||
}
|
}
|
||||||
|
|
||||||
return results;
|
return results;
|
||||||
});
|
});
|
||||||
|
|
||||||
console.log("Rammerhead test results:", testResults);
|
console.log('Rammerhead test results:', testResults);
|
||||||
|
|
||||||
const headers = await getHeaders();
|
const headers = await getHeaders();
|
||||||
const rammerheadTestPassed =
|
const rammerheadTestPassed =
|
||||||
testResults.rammerhead !== "failure" &&
|
testResults.rammerhead !== 'failure' &&
|
||||||
(await testGeneratedUrl(testResults.rammerhead, headers));
|
(await testGeneratedUrl(testResults.rammerhead, headers));
|
||||||
|
|
||||||
console.log(
|
console.log(
|
||||||
`Rammerhead test result: ${
|
`Rammerhead test result: ${
|
||||||
rammerheadTestPassed ? "success" : "failure"
|
rammerheadTestPassed ? 'success' : 'failure'
|
||||||
}`
|
}`
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -211,90 +213,96 @@ xx xx
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const testUltraviolet = async () => {
|
const testUltraviolet = async () => {
|
||||||
await page.goto("http://localhost:8080/ultraviolet");
|
await page.goto('http://localhost:8080/ultraviolet');
|
||||||
|
|
||||||
const testResults = await page.evaluate(async () => {
|
const testResults = await page.evaluate(async () => {
|
||||||
const results = [{}, {}];
|
const results = [{}, {}];
|
||||||
|
|
||||||
await new Promise((resolve) => {
|
await new Promise((resolve) => {
|
||||||
|
const waitForDocument = () =>
|
||||||
|
document.readyState === 'complete'
|
||||||
|
? resolve()
|
||||||
|
: window.addEventListener('load', resolve);
|
||||||
|
|
||||||
const waitForDocument = () => document.readyState === "complete"
|
// Wait until a service worker is registered before continuing.
|
||||||
? resolve()
|
// Also make sure the document is loaded.
|
||||||
: window.addEventListener("load", resolve);
|
const waitForWorker = async () =>
|
||||||
|
setTimeout(async () => {
|
||||||
// Wait until a service worker is registered before continuing.
|
(await navigator.serviceWorker.getRegistrations()).length >= 1
|
||||||
// Also make sure the document is loaded.
|
? waitForDocument()
|
||||||
const waitForWorker = async () => setTimeout(async () => {
|
: waitForWorker();
|
||||||
(await navigator.serviceWorker.getRegistrations()).length >= 1
|
}, 1000);
|
||||||
? waitForDocument()
|
|
||||||
: waitForWorker()
|
|
||||||
}, 1000);
|
|
||||||
|
|
||||||
waitForWorker();
|
waitForWorker();
|
||||||
});
|
});
|
||||||
|
|
||||||
// Locate the omnibox element on the Ultraviolet page.
|
// Locate the omnibox element on the Ultraviolet page.
|
||||||
let omnibox = document.getElementById("pr-uv");
|
let omnibox = document.getElementById('pr-uv');
|
||||||
omnibox = omnibox && omnibox.querySelector("input[type=text]");
|
omnibox = omnibox && omnibox.querySelector('input[type=text]');
|
||||||
|
|
||||||
if (omnibox) {
|
if (omnibox) {
|
||||||
// For the hacky URL test, use the URL page's EXACT title.
|
// For the hacky URL test, use the URL page's EXACT title.
|
||||||
const website = {
|
const website = {
|
||||||
path: "example.com",
|
path: 'example.com',
|
||||||
title: "Example Domain"
|
title: 'Example Domain',
|
||||||
};
|
};
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// Send an artificial input to the omnibox. The omnibox will create
|
// Send an artificial input to the omnibox. The omnibox will create
|
||||||
// a proxy URL and leave it as the input value in response.
|
// a proxy URL and leave it as the input value in response.
|
||||||
omnibox.value = website.path;
|
omnibox.value = website.path;
|
||||||
await omnibox.dispatchEvent(
|
await omnibox.dispatchEvent(
|
||||||
new KeyboardEvent("keydown", {code: "Validator Test"})
|
new KeyboardEvent('keydown', { code: 'Validator Test' })
|
||||||
);
|
);
|
||||||
|
|
||||||
// Record the proxy URL that the omnibox left here.
|
// Record the proxy URL that the omnibox left here.
|
||||||
const generatedUrl = omnibox.value;
|
const generatedUrl = omnibox.value;
|
||||||
console.log("Generated Ultraviolet URL:", generatedUrl);
|
console.log('Generated Ultraviolet URL:', generatedUrl);
|
||||||
results[0].ultraviolet = generatedUrl ? generatedUrl : "failure";
|
results[0].ultraviolet = generatedUrl ? generatedUrl : 'failure';
|
||||||
|
|
||||||
// Test to see if the document title for example.com has loaded,
|
// Test to see if the document title for example.com has loaded,
|
||||||
// by appending an IFrame to the document and grabbing its content.
|
// by appending an IFrame to the document and grabbing its content.
|
||||||
const testGeneratedUrlHacky = async (url) => {
|
const testGeneratedUrlHacky = async (url) => {
|
||||||
let result = false;
|
let result = false;
|
||||||
const exampleIFrame = document.createElement("iframe");
|
const exampleIFrame = document.createElement('iframe');
|
||||||
const waitForDocument = new Promise(resolve => {
|
const waitForDocument = new Promise((resolve) => {
|
||||||
document.documentElement.appendChild(exampleIFrame);
|
document.documentElement.appendChild(exampleIFrame);
|
||||||
exampleIFrame.addEventListener("load", () => {
|
exampleIFrame.addEventListener('load', () => {
|
||||||
result = exampleIFrame.contentWindow.document.title === website.title;
|
result =
|
||||||
|
exampleIFrame.contentWindow.document.title ===
|
||||||
|
website.title;
|
||||||
resolve();
|
resolve();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
exampleIFrame.src = url;
|
exampleIFrame.src = url;
|
||||||
exampleIFrame.style.display = "none";
|
exampleIFrame.style.display = 'none';
|
||||||
await waitForDocument;
|
await waitForDocument;
|
||||||
return result;
|
return result;
|
||||||
};
|
};
|
||||||
|
|
||||||
results[1].uvTestPassed = await testGeneratedUrlHacky(results[0].ultraviolet);
|
results[1].uvTestPassed = await testGeneratedUrlHacky(
|
||||||
|
results[0].ultraviolet
|
||||||
|
);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
results[0].ultraviolet = "failure: " + e.message;
|
results[0].ultraviolet = 'failure: ' + e.message;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
results[0].goProx = "not defined";
|
results[0].goProx = 'not defined';
|
||||||
}
|
}
|
||||||
|
|
||||||
return results;
|
return results;
|
||||||
});
|
});
|
||||||
|
|
||||||
console.log("Ultraviolet test results:", testResults[0]);
|
console.log('Ultraviolet test results:', testResults[0]);
|
||||||
|
|
||||||
if (testResults[0].ultraviolet && testResults[0].ultraviolet !== "failure") {
|
if (
|
||||||
|
testResults[0].ultraviolet &&
|
||||||
|
testResults[0].ultraviolet !== 'failure'
|
||||||
|
) {
|
||||||
const uvTestPassed = testResults[1].uvTestPassed;
|
const uvTestPassed = testResults[1].uvTestPassed;
|
||||||
console.log(
|
console.log(
|
||||||
`Ultraviolet test result: ${uvTestPassed ? "success" : "failure"}`
|
`Ultraviolet test result: ${uvTestPassed ? 'success' : 'failure'}`
|
||||||
);
|
);
|
||||||
return uvTestPassed;
|
return uvTestPassed;
|
||||||
} else {
|
} else {
|
||||||
|
@ -308,14 +316,14 @@ xx xx
|
||||||
const ultravioletPassed = await testUltraviolet();
|
const ultravioletPassed = await testUltraviolet();
|
||||||
|
|
||||||
if (rammerheadPassed && ultravioletPassed) {
|
if (rammerheadPassed && ultravioletPassed) {
|
||||||
console.log("Both tests passed.");
|
console.log('Both tests passed.');
|
||||||
process.exitCode = 0;
|
process.exitCode = 0;
|
||||||
} else {
|
} else {
|
||||||
console.error("Tests failed.");
|
console.error('Tests failed.');
|
||||||
process.exitCode = 1;
|
process.exitCode = 1;
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("Error in testCommonJSOnPage:", error.message);
|
console.error('Error in testCommonJSOnPage:', error.message);
|
||||||
process.exitCode = 1;
|
process.exitCode = 1;
|
||||||
} finally {
|
} finally {
|
||||||
await browser.close();
|
await browser.close();
|
||||||
|
|
121
run-command.mjs
121
run-command.mjs
|
@ -7,129 +7,136 @@ import ecosystem from './ecosystem.config.js';
|
||||||
// Some necessary constants are copied over from /src/server.mjs.
|
// Some necessary constants are copied over from /src/server.mjs.
|
||||||
|
|
||||||
const config = Object.freeze(
|
const config = Object.freeze(
|
||||||
JSON.parse(await readFile(new URL("./src/config.json", import.meta.url)))
|
JSON.parse(await readFile(new URL('./src/config.json', import.meta.url)))
|
||||||
),
|
),
|
||||||
ecosystemConfig = Object.freeze(
|
ecosystemConfig = Object.freeze(
|
||||||
ecosystem.apps.find(app => app.name === "HolyUB") || ecosystem.apps[0]
|
ecosystem.apps.find((app) => app.name === 'HolyUB') || ecosystem.apps[0]
|
||||||
);
|
);
|
||||||
|
|
||||||
const serverUrl = (base => {
|
const serverUrl = ((base) => {
|
||||||
try {
|
try {
|
||||||
base = new URL(config.host);
|
base = new URL(config.host);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
base = new URL("http://a");
|
base = new URL('http://a');
|
||||||
base.host = config.host;
|
base.host = config.host;
|
||||||
}
|
}
|
||||||
base.port = ecosystemConfig[ config.production ? "env_production" : "env" ].PORT;
|
base.port =
|
||||||
|
ecosystemConfig[config.production ? 'env_production' : 'env'].PORT;
|
||||||
return Object.freeze(base);
|
return Object.freeze(base);
|
||||||
})();
|
})();
|
||||||
|
|
||||||
const shutdown = fileURLToPath(new URL("./src/.shutdown", import.meta.url));
|
const shutdown = fileURLToPath(new URL('./src/.shutdown', import.meta.url));
|
||||||
|
|
||||||
// Run each command line argument passed after node run-command.mjs.
|
// Run each command line argument passed after node run-command.mjs.
|
||||||
// Commands are defined in the switch case statement below.
|
// Commands are defined in the switch case statement below.
|
||||||
for (let i = 2; i < process.argv.length; i++)
|
for (let i = 2; i < process.argv.length; i++)
|
||||||
switch (process.argv[i]) {
|
switch (process.argv[i]) {
|
||||||
// Commmand to boot up the server. Use PM2 to run if production is true in the
|
// Commmand to boot up the server. Use PM2 to run if production is true in the
|
||||||
// config file.
|
// config file.
|
||||||
case "start":
|
case 'start':
|
||||||
if (config.production)
|
if (config.production)
|
||||||
exec("npx pm2 start ecosystem.config.js --env production",
|
exec(
|
||||||
|
'npx pm2 start ecosystem.config.js --env production',
|
||||||
(error, stdout) => {
|
(error, stdout) => {
|
||||||
if (error) throw error;
|
if (error) throw error;
|
||||||
console.log(stdout);
|
console.log(stdout);
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
// Handle setup on Windows differently from platforms with POSIX-compliant shells.
|
// Handle setup on Windows differently from platforms with POSIX-compliant shells.
|
||||||
// This should run the server as a background process.
|
// This should run the server as a background process.
|
||||||
else if (process.platform === "win32")
|
else if (process.platform === 'win32')
|
||||||
exec('START /MIN "" node backend.js', (error, stdout) => {
|
exec('START /MIN "" node backend.js', (error, stdout) => {
|
||||||
if (error) throw error;
|
if (error) throw error;
|
||||||
console.log(stdout);
|
console.log(stdout);
|
||||||
});
|
});
|
||||||
// The following approach (and similar approaches) will not work on Windows,
|
// The following approach (and similar approaches) will not work on Windows,
|
||||||
// because exiting this program will also terminate backend.js on Windows.
|
// because exiting this program will also terminate backend.js on Windows.
|
||||||
else {
|
else {
|
||||||
const server = fork(
|
const server = fork(
|
||||||
fileURLToPath(new URL("./backend.js", import.meta.url)),
|
fileURLToPath(new URL('./backend.js', import.meta.url)),
|
||||||
{detached: true}
|
{ detached: true }
|
||||||
);
|
);
|
||||||
server.unref();
|
server.unref();
|
||||||
server.disconnect();
|
server.disconnect();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// Stop the server. Make a temporary file that the server will check for if told
|
// Stop the server. Make a temporary file that the server will check for if told
|
||||||
// to shut down. This is done by sending a GET request to the server.
|
// to shut down. This is done by sending a GET request to the server.
|
||||||
case "stop": {
|
case 'stop': {
|
||||||
await writeFile(shutdown, "");
|
await writeFile(shutdown, '');
|
||||||
let timeoutId = undefined;
|
let timeoutId = undefined;
|
||||||
try {
|
try {
|
||||||
// Give the server 5 seconds to respond, otherwise cancel this and throw an
|
// Give the server 5 seconds to respond, otherwise cancel this and throw an
|
||||||
// error to the console. The fetch request will also throw an error immediately
|
// error to the console. The fetch request will also throw an error immediately
|
||||||
// if checking the server on localhost and the port is unused.
|
// if checking the server on localhost and the port is unused.
|
||||||
const response = await Promise.race([
|
const response = await Promise.race([
|
||||||
fetch(new URL("/test-shutdown", serverUrl)),
|
fetch(new URL('/test-shutdown', serverUrl)),
|
||||||
new Promise(resolve => {
|
new Promise((resolve) => {
|
||||||
timeoutId = setTimeout(() => {
|
timeoutId = setTimeout(() => {
|
||||||
resolve("Error");
|
resolve('Error');
|
||||||
}, 5000);
|
}, 5000);
|
||||||
})
|
}),
|
||||||
]);
|
]);
|
||||||
clearTimeout(timeoutId);
|
clearTimeout(timeoutId);
|
||||||
if (response === "Error") throw new Error("Server is unresponsive.");
|
if (response === 'Error') throw new Error('Server is unresponsive.');
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
// Check if this is the error thrown by the fetch request for an unused port.
|
// Check if this is the error thrown by the fetch request for an unused port.
|
||||||
// Don't print the unused port error, since nothing has actually broken.
|
// Don't print the unused port error, since nothing has actually broken.
|
||||||
if (e instanceof TypeError) clearTimeout(timeoutId);
|
if (e instanceof TypeError) clearTimeout(timeoutId);
|
||||||
else console.error(e);
|
else console.error(e);
|
||||||
await unlink(shutdown);
|
await unlink(shutdown);
|
||||||
}
|
}
|
||||||
// Do not run this if Node will be killed later in this script. It will fail.
|
// Do not run this if Node will be killed later in this script. It will fail.
|
||||||
if (config.production && !process.argv.slice(i + 1).includes("kill"))
|
if (config.production && !process.argv.slice(i + 1).includes('kill'))
|
||||||
exec("npx pm2 stop ecosystem.config.js", (error, stdout) => {
|
exec('npx pm2 stop ecosystem.config.js', (error, stdout) => {
|
||||||
if (error) throw error;
|
if (error) throw error;
|
||||||
console.log(stdout);
|
console.log(stdout);
|
||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case "build": {
|
case 'build': {
|
||||||
const dist = fileURLToPath(new URL("./views/dist", import.meta.url));
|
const dist = fileURLToPath(new URL('./views/dist', import.meta.url));
|
||||||
await rm(dist, {force: true, recursive: true});
|
await rm(dist, { force: true, recursive: true });
|
||||||
await mkdir(dist);
|
await mkdir(dist);
|
||||||
await build({
|
await build({
|
||||||
entryPoints: [
|
entryPoints: [
|
||||||
"./views/uv/**/*.js",
|
'./views/uv/**/*.js',
|
||||||
"./views/assets/js/**/*.js",
|
'./views/assets/js/**/*.js',
|
||||||
"./views/assets/css/**/*.css"
|
'./views/assets/css/**/*.css',
|
||||||
],
|
],
|
||||||
platform: "browser",
|
platform: 'browser',
|
||||||
sourcemap: true,
|
sourcemap: true,
|
||||||
bundle: true,
|
bundle: true,
|
||||||
minify: true,
|
minify: true,
|
||||||
external: ["*.png", "*.jpg", "*.jpeg", "*.webp", "*.svg"],
|
external: ['*.png', '*.jpg', '*.jpeg', '*.webp', '*.svg'],
|
||||||
outdir: dist
|
outdir: dist,
|
||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Kill all node processes and fully reset PM2. To be used for debugging.
|
// Kill all node processes and fully reset PM2. To be used for debugging.
|
||||||
// Using npx pm2 monit, or npx pm2 list in the terminal will also bring up
|
// Using npx pm2 monit, or npx pm2 list in the terminal will also bring up
|
||||||
// more PM2 debugging tools.
|
// more PM2 debugging tools.
|
||||||
case "kill":
|
case 'kill':
|
||||||
if (process.platform === "win32")
|
if (process.platform === 'win32')
|
||||||
exec("( npx pm2 delete ecosystem.config.js ) ; taskkill /F /IM node*",
|
exec(
|
||||||
(error, stdout) => {console.log(stdout)}
|
'( npx pm2 delete ecosystem.config.js ) ; taskkill /F /IM node*',
|
||||||
|
(error, stdout) => {
|
||||||
|
console.log(stdout);
|
||||||
|
}
|
||||||
);
|
);
|
||||||
else exec("npx pm2 delete ecosystem.config.js; pkill node",
|
else
|
||||||
(error, stdout) => {console.log(stdout)}
|
exec(
|
||||||
|
'npx pm2 delete ecosystem.config.js; pkill node',
|
||||||
|
(error, stdout) => {
|
||||||
|
console.log(stdout);
|
||||||
|
}
|
||||||
);
|
);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// No default case.
|
// No default case.
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
process.exitCode = 0;
|
process.exitCode = 0;
|
||||||
|
|
|
@ -18,7 +18,5 @@
|
||||||
"splash": [
|
"splash": [
|
||||||
"This version is the public LTS build of the web proxy service project and may be hosted unofficially. Check your domain or jo­in the <a id='tnlink' target='_blank'>T­N Dis­co­rd</a> for official pr­iva️te site lin­ks for your safety."
|
"This version is the public LTS build of the web proxy service project and may be hosted unofficially. Check your domain or jo­in the <a id='tnlink' target='_blank'>T­N Dis­co­rd</a> for official pr­iva️te site lin­ks for your safety."
|
||||||
],
|
],
|
||||||
"version": [
|
"version": ["6.3.7"]
|
||||||
"6.3.7"
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
|
|
176
src/express.mjs
176
src/express.mjs
|
@ -1,89 +1,85 @@
|
||||||
import { paintSource, tryReadFile } from "./randomization.mjs";
|
import { paintSource, tryReadFile } from './randomization.mjs';
|
||||||
import loadTemplates from "./templates.mjs";
|
import loadTemplates from './templates.mjs';
|
||||||
import pkg from "./routes.mjs";
|
import pkg from './routes.mjs';
|
||||||
import { readFile } from "fs/promises";
|
import { readFile } from 'fs/promises';
|
||||||
import path from "path";
|
import path from 'path';
|
||||||
import express from "express";
|
import express from 'express';
|
||||||
import helmet from "helmet";
|
import helmet from 'helmet';
|
||||||
import http from "http";
|
import http from 'http';
|
||||||
import createRammerhead from "rammerhead/src/server/index.js";
|
import createRammerhead from 'rammerhead/src/server/index.js';
|
||||||
import wisp from "wisp-server-node";
|
import wisp from 'wisp-server-node';
|
||||||
import { epoxyPath } from "@mercuryworkshop/epoxy-transport";
|
import { epoxyPath } from '@mercuryworkshop/epoxy-transport';
|
||||||
import { libcurlPath } from "@mercuryworkshop/libcurl-transport";
|
import { libcurlPath } from '@mercuryworkshop/libcurl-transport';
|
||||||
import { bareModulePath } from "@mercuryworkshop/bare-as-module3";
|
import { bareModulePath } from '@mercuryworkshop/bare-as-module3';
|
||||||
import { baremuxPath } from "@mercuryworkshop/bare-mux/node";
|
import { baremuxPath } from '@mercuryworkshop/bare-mux/node';
|
||||||
import { uvPath } from "@titaniumnetwork-dev/ultraviolet";
|
import { uvPath } from '@titaniumnetwork-dev/ultraviolet';
|
||||||
// import { createBareServer } from "@tomphttp/bare-server-node";
|
// import { createBareServer } from "@tomphttp/bare-server-node";
|
||||||
|
|
||||||
const config = JSON.parse(
|
const config = JSON.parse(
|
||||||
await readFile(new URL("./config.json", import.meta.url))
|
await readFile(new URL('./config.json', import.meta.url))
|
||||||
),
|
),
|
||||||
{ pages, text404 } = pkg,
|
{ pages, text404 } = pkg,
|
||||||
__dirname = path.resolve(),
|
__dirname = path.resolve(),
|
||||||
port = process.env.PORT || config.port,
|
port = process.env.PORT || config.port,
|
||||||
app = express(),
|
app = express(),
|
||||||
router = express.Router(),
|
router = express.Router(),
|
||||||
// bare = createBareServer("/bare/"),
|
// bare = createBareServer("/bare/"),
|
||||||
rh = createRammerhead();
|
rh = createRammerhead();
|
||||||
|
|
||||||
const rammerheadScopes = [
|
const rammerheadScopes = [
|
||||||
"/rammerhead.js",
|
'/rammerhead.js',
|
||||||
"/hammerhead.js",
|
'/hammerhead.js',
|
||||||
"/transport-worker.js",
|
'/transport-worker.js',
|
||||||
"/task.js",
|
'/task.js',
|
||||||
"/iframe-task.js",
|
'/iframe-task.js',
|
||||||
"/worker-hammerhead.js",
|
'/worker-hammerhead.js',
|
||||||
"/messaging",
|
'/messaging',
|
||||||
"/sessionexists",
|
'/sessionexists',
|
||||||
"/deletesession",
|
'/deletesession',
|
||||||
"/newsession",
|
'/newsession',
|
||||||
"/editsession",
|
'/editsession',
|
||||||
"/needpassword",
|
'/needpassword',
|
||||||
"/syncLocalStorage",
|
'/syncLocalStorage',
|
||||||
"/api/shuffleDict",
|
'/api/shuffleDict',
|
||||||
"/mainport",
|
'/mainport',
|
||||||
];
|
];
|
||||||
|
|
||||||
const rammerheadSession = /^\/[a-z0-9]{32}/,
|
const rammerheadSession = /^\/[a-z0-9]{32}/,
|
||||||
|
shouldRouteRh = (req) => {
|
||||||
shouldRouteRh = req => {
|
const url = new URL(req.url, 'http://0.0.0.0');
|
||||||
const url = new URL(req.url, "http://0.0.0.0");
|
return (
|
||||||
return (
|
rammerheadScopes.includes(url.pathname) ||
|
||||||
rammerheadScopes.includes(url.pathname) ||
|
rammerheadSession.test(url.pathname)
|
||||||
rammerheadSession.test(url.pathname)
|
);
|
||||||
);
|
},
|
||||||
},
|
routeRhRequest = (req, res) => {
|
||||||
|
rh.emit('request', req, res);
|
||||||
routeRhRequest = (req, res) => {
|
},
|
||||||
rh.emit("request", req, res);
|
routeRhUpgrade = (req, socket, head) => {
|
||||||
},
|
rh.emit('upgrade', req, socket, head);
|
||||||
|
},
|
||||||
routeRhUpgrade = (req, socket, head) => {
|
server = http.createServer((req, res) => {
|
||||||
rh.emit("upgrade", req, socket, head);
|
/*
|
||||||
},
|
|
||||||
|
|
||||||
server = http.createServer((req, res) => {
|
|
||||||
/*
|
|
||||||
if (bare.shouldRoute(req)) {
|
if (bare.shouldRoute(req)) {
|
||||||
bare.routeRequest(req, res);
|
bare.routeRequest(req, res);
|
||||||
} else
|
} else
|
||||||
*/
|
*/
|
||||||
if (shouldRouteRh(req)) {
|
if (shouldRouteRh(req)) {
|
||||||
routeRhRequest(req, res);
|
routeRhRequest(req, res);
|
||||||
} else {
|
} else {
|
||||||
app(req, res);
|
app(req, res);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
server.on("upgrade", (req, socket, head) => {
|
server.on('upgrade', (req, socket, head) => {
|
||||||
/*
|
/*
|
||||||
if (bare.shouldRoute(req)) {
|
if (bare.shouldRoute(req)) {
|
||||||
bare.routeUpgrade(req, socket, head);
|
bare.routeUpgrade(req, socket, head);
|
||||||
} else
|
} else
|
||||||
*/
|
*/
|
||||||
if (shouldRouteRh(req)) {
|
if (shouldRouteRh(req)) {
|
||||||
routeRhUpgrade(req, socket, head);
|
routeRhUpgrade(req, socket, head);
|
||||||
} else if (req.url.endsWith("/wisp/")) {
|
} else if (req.url.endsWith('/wisp/')) {
|
||||||
wisp.routeRequest(req, socket, head);
|
wisp.routeRequest(req, socket, head);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -99,33 +95,35 @@ app.use(
|
||||||
// This takes one of those files and displays it for a site visitor.
|
// This takes one of those files and displays it for a site visitor.
|
||||||
// Query strings like /?j are converted into paths like /views/hidden.html
|
// Query strings like /?j are converted into paths like /views/hidden.html
|
||||||
// back here. Which query string converts to what is defined in routes.mjs.
|
// back here. Which query string converts to what is defined in routes.mjs.
|
||||||
router.get("/", async (req, res) =>
|
router.get('/', async (req, res) =>
|
||||||
res.send(
|
res.send(
|
||||||
paintSource(
|
paintSource(
|
||||||
loadTemplates(
|
loadTemplates(
|
||||||
tryReadFile(
|
tryReadFile(
|
||||||
path.join(__dirname,
|
path.join(
|
||||||
"views",
|
__dirname,
|
||||||
// Return the error page if the query is not found in
|
'views',
|
||||||
// routes.mjs. Also set index as the default page.
|
// Return the error page if the query is not found in
|
||||||
"/?".indexOf(req.url) ? pages[Object.keys(req.query)[0]] || "error.html" : pages.index
|
// routes.mjs. Also set index as the default page.
|
||||||
)
|
'/?'.indexOf(req.url)
|
||||||
)
|
? pages[Object.keys(req.query)[0]] || 'error.html'
|
||||||
)
|
: pages.index
|
||||||
|
)
|
||||||
)
|
)
|
||||||
|
)
|
||||||
)
|
)
|
||||||
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
app.use(router);
|
app.use(router);
|
||||||
app.use(express.static(path.join(__dirname, "views")));
|
app.use(express.static(path.join(__dirname, 'views')));
|
||||||
app.use("/uv/", express.static(uvPath));
|
app.use('/uv/', express.static(uvPath));
|
||||||
app.use("/epoxy/", express.static(epoxyPath));
|
app.use('/epoxy/', express.static(epoxyPath));
|
||||||
app.use("/libcurl/", express.static(libcurlPath));
|
app.use('/libcurl/', express.static(libcurlPath));
|
||||||
app.use("/bareasmodule/", express.static(bareModulePath));
|
app.use('/bareasmodule/', express.static(bareModulePath));
|
||||||
app.use("/baremux/", express.static(baremuxPath));
|
app.use('/baremux/', express.static(baremuxPath));
|
||||||
|
|
||||||
app.disable("x-powered-by");
|
app.disable('x-powered-by');
|
||||||
|
|
||||||
// Redundant code since 404 is handled elsewhere; left here as insurance.
|
// Redundant code since 404 is handled elsewhere; left here as insurance.
|
||||||
app.use((req, res) => {
|
app.use((req, res) => {
|
||||||
|
@ -133,4 +131,4 @@ app.use((req, res) => {
|
||||||
});
|
});
|
||||||
|
|
||||||
server.listen(port);
|
server.listen(port);
|
||||||
console.log("Holy Unblocker is listening on port " + port + ".");
|
console.log('Holy Unblocker is listening on port ' + port + '.');
|
||||||
|
|
|
@ -1,15 +1,15 @@
|
||||||
import pkg from "./routes.mjs";
|
import pkg from './routes.mjs';
|
||||||
import { existsSync, readFileSync } from "fs";
|
import { existsSync, readFileSync } from 'fs';
|
||||||
export { paintSource, preloaded404, tryReadFile };
|
export { paintSource, preloaded404, tryReadFile };
|
||||||
const {
|
const {
|
||||||
cookingInserts,
|
cookingInserts,
|
||||||
vegetables,
|
vegetables,
|
||||||
charRandom,
|
charRandom,
|
||||||
splashRandom,
|
splashRandom,
|
||||||
cacheBustList,
|
cacheBustList,
|
||||||
VersionValue,
|
VersionValue,
|
||||||
text404,
|
text404,
|
||||||
} = pkg;
|
} = pkg;
|
||||||
|
|
||||||
// Below are lots of function definitions used to obfuscate the website.
|
// Below are lots of function definitions used to obfuscate the website.
|
||||||
// This makes the website harder to properly categorize, as its source code
|
// This makes the website harder to properly categorize, as its source code
|
||||||
|
@ -19,29 +19,29 @@ const randomListItem = (lis) => () => lis[(Math.random() * lis.length) | 0],
|
||||||
getRandomChar = randomListItem(charRandom),
|
getRandomChar = randomListItem(charRandom),
|
||||||
insertCharset = (str) => str.replace(charset, getRandomChar),
|
insertCharset = (str) => str.replace(charset, getRandomChar),
|
||||||
getRandomSplash = randomListItem(splashRandom),
|
getRandomSplash = randomListItem(splashRandom),
|
||||||
hutaoInsert = (str) => str.replaceAll("<!--HUTAOWOA-->", getRandomSplash),
|
hutaoInsert = (str) => str.replaceAll('<!--HUTAOWOA-->', getRandomSplash),
|
||||||
versionInsert = (str) => str.replaceAll("<!-- VERSION -->", VersionValue),
|
versionInsert = (str) => str.replaceAll('<!-- VERSION -->', VersionValue),
|
||||||
getCookingText = () =>
|
getCookingText = () =>
|
||||||
`<span style="display:none" data-fact="${randomListItem(vegetables)()}">${randomListItem(cookingInserts)()}</span>`,
|
`<span style="display:none" data-fact="${randomListItem(vegetables)()}">${randomListItem(cookingInserts)()}</span>`,
|
||||||
insertCooking = (str) =>
|
insertCooking = (str) =>
|
||||||
str.replaceAll(
|
str.replaceAll(
|
||||||
"<!-- IMPORTANT-HUTAOCOOKINGINSERT-DONOTDELETE -->",
|
'<!-- IMPORTANT-HUTAOCOOKINGINSERT-DONOTDELETE -->',
|
||||||
getCookingText
|
getCookingText
|
||||||
),
|
),
|
||||||
// This one isn't for obfuscation; it's just for dealing with cache issues.
|
// This one isn't for obfuscation; it's just for dealing with cache issues.
|
||||||
cacheBusting = (str) => {
|
cacheBusting = (str) => {
|
||||||
for (let item of Object.entries(cacheBustList))
|
for (let item of Object.entries(cacheBustList))
|
||||||
str = str.replaceAll(item[0], item[1]);
|
str = str.replaceAll(item[0], item[1]);
|
||||||
return str;
|
return str;
|
||||||
},
|
},
|
||||||
// Apply the final obfuscation changes to an entire file.
|
// Apply the final obfuscation changes to an entire file.
|
||||||
paintSource = (str) =>
|
paintSource = (str) =>
|
||||||
insertCharset(hutaoInsert(versionInsert(insertCooking(cacheBusting(str))))),
|
insertCharset(hutaoInsert(versionInsert(insertCooking(cacheBusting(str))))),
|
||||||
// Use this instead of text404 for a preloaded error page.
|
// Use this instead of text404 for a preloaded error page.
|
||||||
preloaded404 = paintSource(text404),
|
preloaded404 = paintSource(text404),
|
||||||
// Grab the text content of a file. Ensure the file is a string.
|
// Grab the text content of a file. Ensure the file is a string.
|
||||||
tryReadFile = (file) =>
|
tryReadFile = (file) =>
|
||||||
existsSync(file + "") ? readFileSync(file + "", "utf8") : preloaded404;
|
existsSync(file + '') ? readFileSync(file + '', 'utf8') : preloaded404;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
// All of this is now old code.
|
// All of this is now old code.
|
||||||
|
|
|
@ -1,75 +1,75 @@
|
||||||
import { readFileSync } from "fs";
|
import { readFileSync } from 'fs';
|
||||||
import path from "path";
|
import path from 'path';
|
||||||
import { readFile } from "fs/promises";
|
import { readFile } from 'fs/promises';
|
||||||
|
|
||||||
const insert = JSON.parse(
|
const insert = JSON.parse(
|
||||||
await readFile(new URL("./data.json", import.meta.url))
|
await readFile(new URL('./data.json', import.meta.url))
|
||||||
);
|
);
|
||||||
|
|
||||||
const __dirname = path.resolve();
|
const __dirname = path.resolve();
|
||||||
|
|
||||||
const text404 = readFileSync(
|
const text404 = readFileSync(
|
||||||
path.normalize(__dirname + "/views/error.html"),
|
path.normalize(__dirname + '/views/error.html'),
|
||||||
"utf8"
|
'utf8'
|
||||||
);
|
);
|
||||||
|
|
||||||
const pages = {
|
const pages = {
|
||||||
index: "index.html",
|
index: 'index.html',
|
||||||
"manifest.json": "manifest.json",
|
'manifest.json': 'manifest.json',
|
||||||
"test-404": "error.html",
|
'test-404': 'error.html',
|
||||||
/* Main */
|
/* Main */
|
||||||
documentation: "docs.html",
|
documentation: 'docs.html',
|
||||||
questions: "faq.html",
|
questions: 'faq.html',
|
||||||
s: "pages/frame.html",
|
s: 'pages/frame.html',
|
||||||
browsing: "pages/surf.html",
|
browsing: 'pages/surf.html',
|
||||||
credits: "pages/nav/credits.html",
|
credits: 'pages/nav/credits.html',
|
||||||
bookmarklets: "pages/nav/bookmarklets.html",
|
bookmarklets: 'pages/nav/bookmarklets.html',
|
||||||
terms: "pages/nav/terms.html",
|
terms: 'pages/nav/terms.html',
|
||||||
/* Games */
|
/* Games */
|
||||||
games: "pages/nav/gtools.html",
|
games: 'pages/nav/gtools.html',
|
||||||
"web-games": "pages/nav/games5.html",
|
'web-games': 'pages/nav/games5.html',
|
||||||
emulators: "pages/nav/emulators.html",
|
emulators: 'pages/nav/emulators.html',
|
||||||
"flash-games": "pages/nav/flash.html",
|
'flash-games': 'pages/nav/flash.html',
|
||||||
"retro-games": "pages/nav/emulibrary.html",
|
'retro-games': 'pages/nav/emulibrary.html',
|
||||||
/* Proxies */
|
/* Proxies */
|
||||||
ultraviolet: "pages/proxnav/ultraviolet.html",
|
ultraviolet: 'pages/proxnav/ultraviolet.html',
|
||||||
rammerhead: "pages/proxnav/rammerhead.html",
|
rammerhead: 'pages/proxnav/rammerhead.html',
|
||||||
/* Proxy Presets */
|
/* Proxy Presets */
|
||||||
youtube: "pages/proxnav/preset/youtube.html",
|
youtube: 'pages/proxnav/preset/youtube.html',
|
||||||
apps: "pages/proxnav/preset/applications.html",
|
apps: 'pages/proxnav/preset/applications.html',
|
||||||
/* Misc */
|
/* Misc */
|
||||||
flash: "archive/gfiles/flash/index.html",
|
flash: 'archive/gfiles/flash/index.html',
|
||||||
webretro: "archive/gfiles/rarch/index.html",
|
webretro: 'archive/gfiles/rarch/index.html',
|
||||||
"vibe-os": "archive/vibeOS/index.html",
|
'vibe-os': 'archive/vibeOS/index.html',
|
||||||
};
|
};
|
||||||
|
|
||||||
const externalPages = {
|
const externalPages = {
|
||||||
github: {
|
github: {
|
||||||
default: "https://github.com/QuiteAFancyEmerald/Holy-Unblocker",
|
default: 'https://github.com/QuiteAFancyEmerald/Holy-Unblocker',
|
||||||
aos: "https://github.com/michalsnik/aos",
|
aos: 'https://github.com/michalsnik/aos',
|
||||||
"bare-module": "https://github.com/motortruck1221/bare-as-module3",
|
'bare-module': 'https://github.com/motortruck1221/bare-as-module3',
|
||||||
"bare-mux": "https://github.com/MercuryWorkshop/bare-mux",
|
'bare-mux': 'https://github.com/MercuryWorkshop/bare-mux',
|
||||||
epoxy: "https://github.com/MercuryWorkshop/epoxy-tls",
|
epoxy: 'https://github.com/MercuryWorkshop/epoxy-tls',
|
||||||
fastify: "https://github.com/fastify/fastify",
|
fastify: 'https://github.com/fastify/fastify',
|
||||||
"font-awesome": "https://github.com/FortAwesome/Font-Awesome",
|
'font-awesome': 'https://github.com/FortAwesome/Font-Awesome',
|
||||||
"libcurl-js": "https://github.com/ading2210/libcurl.js",
|
'libcurl-js': 'https://github.com/ading2210/libcurl.js',
|
||||||
"nord-theme": "https://github.com/nordtheme",
|
'nord-theme': 'https://github.com/nordtheme',
|
||||||
ultraviolet: "https://github.com/titaniumnetwork-dev/Ultraviolet",
|
ultraviolet: 'https://github.com/titaniumnetwork-dev/Ultraviolet',
|
||||||
wisp: "https://github.com/MercuryWorkshop/wisp-protocol"
|
wisp: 'https://github.com/MercuryWorkshop/wisp-protocol',
|
||||||
},
|
},
|
||||||
"titaniumnetwork-documentation": "https://docs.titaniumnetwork.org",
|
'titaniumnetwork-documentation': 'https://docs.titaniumnetwork.org',
|
||||||
"rammerhead-discord": "https://discord.gg/VNT4E7gN5Y"
|
'rammerhead-discord': 'https://discord.gg/VNT4E7gN5Y',
|
||||||
};
|
};
|
||||||
|
|
||||||
const cookingInserts = insert.content,
|
const cookingInserts = insert.content,
|
||||||
vegetables = insert.keywords,
|
vegetables = insert.keywords,
|
||||||
charRandom = insert.chars,
|
charRandom = insert.chars,
|
||||||
splashRandom = insert.splash,
|
splashRandom = insert.splash,
|
||||||
VersionValue = insert.version,
|
VersionValue = insert.version,
|
||||||
cacheBustList = {
|
cacheBustList = {
|
||||||
"styles.css": "styles-1644738239.css",
|
'styles.css': 'styles-1644738239.css',
|
||||||
"common.js": "common-16451543478.js",
|
'common.js': 'common-16451543478.js',
|
||||||
};
|
};
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
pages,
|
pages,
|
||||||
|
|
225
src/server.mjs
225
src/server.mjs
|
@ -1,15 +1,15 @@
|
||||||
import Fastify from 'fastify';
|
import Fastify from 'fastify';
|
||||||
import { createServer } from 'node:http';
|
import { createServer } from 'node:http';
|
||||||
import wisp from 'wisp-server-node';
|
import wisp from 'wisp-server-node';
|
||||||
import createRammerhead from "../lib/rammerhead/src/server/index.js";
|
import createRammerhead from '../lib/rammerhead/src/server/index.js';
|
||||||
import { epoxyPath } from "@mercuryworkshop/epoxy-transport";
|
import { epoxyPath } from '@mercuryworkshop/epoxy-transport';
|
||||||
import { libcurlPath } from "@mercuryworkshop/libcurl-transport";
|
import { libcurlPath } from '@mercuryworkshop/libcurl-transport';
|
||||||
import { bareModulePath } from "@mercuryworkshop/bare-as-module3";
|
import { bareModulePath } from '@mercuryworkshop/bare-as-module3';
|
||||||
import { baremuxPath } from "@mercuryworkshop/bare-mux/node";
|
import { baremuxPath } from '@mercuryworkshop/bare-mux/node';
|
||||||
import { uvPath } from "@titaniumnetwork-dev/ultraviolet";
|
import { uvPath } from '@titaniumnetwork-dev/ultraviolet';
|
||||||
import fastifyHelmet from '@fastify/helmet';
|
import fastifyHelmet from '@fastify/helmet';
|
||||||
import fastifyStatic from '@fastify/static';
|
import fastifyStatic from '@fastify/static';
|
||||||
import pageRoutes from "./routes.mjs";
|
import pageRoutes from './routes.mjs';
|
||||||
import { readFile } from 'node:fs/promises';
|
import { readFile } from 'node:fs/promises';
|
||||||
import path from 'node:path';
|
import path from 'node:path';
|
||||||
import { paintSource, preloaded404, tryReadFile } from './randomization.mjs';
|
import { paintSource, preloaded404, tryReadFile } from './randomization.mjs';
|
||||||
|
@ -19,10 +19,10 @@ import { existsSync, unlinkSync } from 'node:fs';
|
||||||
import ecosystem from '../ecosystem.config.js';
|
import ecosystem from '../ecosystem.config.js';
|
||||||
|
|
||||||
const config = Object.freeze(
|
const config = Object.freeze(
|
||||||
JSON.parse(await readFile(new URL("./config.json", import.meta.url)))
|
JSON.parse(await readFile(new URL('./config.json', import.meta.url)))
|
||||||
),
|
),
|
||||||
ecosystemConfig = Object.freeze(
|
ecosystemConfig = Object.freeze(
|
||||||
ecosystem.apps.find(app => app.name === "HolyUB") || ecosystem.apps[0]
|
ecosystem.apps.find((app) => app.name === 'HolyUB') || ecosystem.apps[0]
|
||||||
),
|
),
|
||||||
{ pages, externalPages } = pageRoutes,
|
{ pages, externalPages } = pageRoutes,
|
||||||
__dirname = path.resolve();
|
__dirname = path.resolve();
|
||||||
|
@ -30,71 +30,71 @@ const config = Object.freeze(
|
||||||
// Record the server's location as a URL object, including its host and port.
|
// Record the server's location as a URL object, including its host and port.
|
||||||
// The host can be modified at /src/config.json, whereas the ports can be modified
|
// The host can be modified at /src/config.json, whereas the ports can be modified
|
||||||
// at /ecosystem.config.js.
|
// at /ecosystem.config.js.
|
||||||
const serverUrl = (base => {
|
const serverUrl = ((base) => {
|
||||||
try {
|
try {
|
||||||
base = new URL(config.host);
|
base = new URL(config.host);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
base = new URL("http://a");
|
base = new URL('http://a');
|
||||||
base.host = config.host;
|
base.host = config.host;
|
||||||
}
|
}
|
||||||
base.port = ecosystemConfig[ config.production ? "env_production" : "env" ].PORT;
|
base.port =
|
||||||
|
ecosystemConfig[config.production ? 'env_production' : 'env'].PORT;
|
||||||
return Object.freeze(base);
|
return Object.freeze(base);
|
||||||
})();
|
})();
|
||||||
console.log(serverUrl);
|
console.log(serverUrl);
|
||||||
|
|
||||||
// The server will check for the existence of this file when a shutdown is requested.
|
// The server will check for the existence of this file when a shutdown is requested.
|
||||||
// The shutdown script in run-command.js will temporarily produce this file.
|
// The shutdown script in run-command.js will temporarily produce this file.
|
||||||
const shutdown = fileURLToPath(new URL("./.shutdown", import.meta.url));
|
const shutdown = fileURLToPath(new URL('./.shutdown', import.meta.url));
|
||||||
|
|
||||||
const rh = createRammerhead();
|
const rh = createRammerhead();
|
||||||
const rammerheadScopes = [
|
const rammerheadScopes = [
|
||||||
"/rammerhead.js",
|
'/rammerhead.js',
|
||||||
"/hammerhead.js",
|
'/hammerhead.js',
|
||||||
"/transport-worker.js",
|
'/transport-worker.js',
|
||||||
"/task.js",
|
'/task.js',
|
||||||
"/iframe-task.js",
|
'/iframe-task.js',
|
||||||
"/worker-hammerhead.js",
|
'/worker-hammerhead.js',
|
||||||
"/messaging",
|
'/messaging',
|
||||||
"/sessionexists",
|
'/sessionexists',
|
||||||
"/deletesession",
|
'/deletesession',
|
||||||
"/newsession",
|
'/newsession',
|
||||||
"/editsession",
|
'/editsession',
|
||||||
"/needpassword",
|
'/needpassword',
|
||||||
"/syncLocalStorage",
|
'/syncLocalStorage',
|
||||||
"/api/shuffleDict",
|
'/api/shuffleDict',
|
||||||
"/mainport",
|
'/mainport',
|
||||||
];
|
];
|
||||||
|
|
||||||
const rammerheadSession = /^\/[a-z0-9]{32}/,
|
const rammerheadSession = /^\/[a-z0-9]{32}/,
|
||||||
shouldRouteRh = req => {
|
shouldRouteRh = (req) => {
|
||||||
try {
|
try {
|
||||||
const url = new URL(req.url, serverUrl);
|
const url = new URL(req.url, serverUrl);
|
||||||
return (
|
return (
|
||||||
rammerheadScopes.includes(url.pathname) ||
|
rammerheadScopes.includes(url.pathname) ||
|
||||||
rammerheadSession.test(url.pathname)
|
rammerheadSession.test(url.pathname)
|
||||||
);
|
);
|
||||||
} catch (e) {return false}
|
} catch (e) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
},
|
},
|
||||||
routeRhRequest = (req, res) => {
|
routeRhRequest = (req, res) => {
|
||||||
rh.emit("request", req, res);
|
rh.emit('request', req, res);
|
||||||
},
|
},
|
||||||
routeRhUpgrade = (req, socket, head) => {
|
routeRhUpgrade = (req, socket, head) => {
|
||||||
rh.emit("upgrade", req, socket, head);
|
rh.emit('upgrade', req, socket, head);
|
||||||
};
|
};
|
||||||
|
|
||||||
// Create a server factory for RH, and wisp (and bare if you please).
|
// Create a server factory for RH, and wisp (and bare if you please).
|
||||||
const serverFactory = (handler) => {
|
const serverFactory = (handler) => {
|
||||||
return createServer()
|
return createServer()
|
||||||
.on('request', (req, res) => {
|
.on('request', (req, res) => {
|
||||||
if (shouldRouteRh(req))
|
if (shouldRouteRh(req)) routeRhRequest(req, res);
|
||||||
routeRhRequest(req, res);
|
|
||||||
else handler(req, res);
|
else handler(req, res);
|
||||||
})
|
})
|
||||||
.on('upgrade', (req, socket, head) => {
|
.on('upgrade', (req, socket, head) => {
|
||||||
if (shouldRouteRh(req))
|
if (shouldRouteRh(req)) routeRhUpgrade(req, socket, head);
|
||||||
routeRhUpgrade(req, socket, head);
|
else if (req.url.endsWith('/wisp/')) wisp.routeRequest(req, socket, head);
|
||||||
else if (req.url.endsWith('/wisp/'))
|
|
||||||
wisp.routeRequest(req, socket, head);
|
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -103,145 +103,150 @@ const app = Fastify({
|
||||||
ignoreDuplicateSlashes: true,
|
ignoreDuplicateSlashes: true,
|
||||||
ignoreTrailingSlash: true,
|
ignoreTrailingSlash: true,
|
||||||
logger: false,
|
logger: false,
|
||||||
serverFactory: serverFactory
|
serverFactory: serverFactory,
|
||||||
});
|
});
|
||||||
|
|
||||||
// Apply Helmet middleware for security
|
// Apply Helmet middleware for security
|
||||||
app.register(fastifyHelmet, {
|
app.register(fastifyHelmet, {
|
||||||
contentSecurityPolicy: false, // Disable CSP
|
contentSecurityPolicy: false, // Disable CSP
|
||||||
xPoweredBy: false
|
xPoweredBy: false,
|
||||||
});
|
});
|
||||||
|
|
||||||
// Assign server file paths to different paths, for serving content on the website.
|
// Assign server file paths to different paths, for serving content on the website.
|
||||||
app.register(fastifyStatic, {
|
app.register(fastifyStatic, {
|
||||||
root: fileURLToPath(new URL("../views/pages", import.meta.url)),
|
root: fileURLToPath(new URL('../views/pages', import.meta.url)),
|
||||||
decorateReply: false
|
decorateReply: false,
|
||||||
});
|
});
|
||||||
|
|
||||||
app.register(fastifyStatic, {
|
app.register(fastifyStatic, {
|
||||||
root: fileURLToPath(new URL("../views/assets", import.meta.url)),
|
root: fileURLToPath(new URL('../views/assets', import.meta.url)),
|
||||||
prefix: "/assets/",
|
prefix: '/assets/',
|
||||||
decorateReply: false
|
decorateReply: false,
|
||||||
});
|
});
|
||||||
|
|
||||||
app.register(fastifyStatic, {
|
app.register(fastifyStatic, {
|
||||||
root: fileURLToPath(new URL("../views/archive", import.meta.url)),
|
root: fileURLToPath(new URL('../views/archive', import.meta.url)),
|
||||||
prefix: "/arcade/",
|
prefix: '/arcade/',
|
||||||
decorateReply: false
|
decorateReply: false,
|
||||||
});
|
});
|
||||||
|
|
||||||
app.register(fastifyStatic, {
|
app.register(fastifyStatic, {
|
||||||
root: fileURLToPath(new URL(
|
root: fileURLToPath(
|
||||||
// Use the pre-compiled, minified scripts instead, if enabled in config.
|
new URL(
|
||||||
config.minifyScripts ? "../views/dist/assets/js" : "../views/assets/js",
|
// Use the pre-compiled, minified scripts instead, if enabled in config.
|
||||||
import.meta.url
|
config.minifyScripts ? '../views/dist/assets/js' : '../views/assets/js',
|
||||||
)),
|
import.meta.url
|
||||||
prefix: "/assets/js/",
|
)
|
||||||
decorateReply: false
|
),
|
||||||
|
prefix: '/assets/js/',
|
||||||
|
decorateReply: false,
|
||||||
});
|
});
|
||||||
|
|
||||||
app.register(fastifyStatic, {
|
app.register(fastifyStatic, {
|
||||||
root: fileURLToPath(new URL(
|
root: fileURLToPath(
|
||||||
// Use the pre-compiled, minified stylesheets instead, if enabled in config.
|
new URL(
|
||||||
config.minifyScripts ? "../views/dist/assets/css" : "../views/assets/css",
|
// Use the pre-compiled, minified stylesheets instead, if enabled in config.
|
||||||
import.meta.url
|
config.minifyScripts ? '../views/dist/assets/css' : '../views/assets/css',
|
||||||
)),
|
import.meta.url
|
||||||
prefix: "/assets/css/",
|
)
|
||||||
decorateReply: false
|
),
|
||||||
|
prefix: '/assets/css/',
|
||||||
|
decorateReply: false,
|
||||||
});
|
});
|
||||||
|
|
||||||
// This combines scripts from the official UV repository with local UV scripts into
|
// This combines scripts from the official UV repository with local UV scripts into
|
||||||
// one directory path. Local versions of files override the official versions.
|
// one directory path. Local versions of files override the official versions.
|
||||||
app.register(fastifyStatic, {
|
app.register(fastifyStatic, {
|
||||||
root: [
|
root: [
|
||||||
fileURLToPath(new URL(
|
fileURLToPath(
|
||||||
// Use the pre-compiled, minified scripts instead, if enabled in config.
|
new URL(
|
||||||
config.minifyScripts ? "../views/dist/uv" : "../views/uv",
|
// Use the pre-compiled, minified scripts instead, if enabled in config.
|
||||||
import.meta.url
|
config.minifyScripts ? '../views/dist/uv' : '../views/uv',
|
||||||
)),
|
import.meta.url
|
||||||
uvPath
|
)
|
||||||
|
),
|
||||||
|
uvPath,
|
||||||
],
|
],
|
||||||
prefix: "/uv/",
|
prefix: '/uv/',
|
||||||
decorateReply: false
|
decorateReply: false,
|
||||||
});
|
});
|
||||||
|
|
||||||
// Register proxy paths to the website.
|
// Register proxy paths to the website.
|
||||||
app.register(fastifyStatic, {
|
app.register(fastifyStatic, {
|
||||||
root: epoxyPath,
|
root: epoxyPath,
|
||||||
prefix: "/epoxy/",
|
prefix: '/epoxy/',
|
||||||
decorateReply: false
|
decorateReply: false,
|
||||||
});
|
});
|
||||||
|
|
||||||
app.register(fastifyStatic, {
|
app.register(fastifyStatic, {
|
||||||
root: libcurlPath,
|
root: libcurlPath,
|
||||||
prefix: "/libcurl/",
|
prefix: '/libcurl/',
|
||||||
decorateReply: false
|
decorateReply: false,
|
||||||
});
|
});
|
||||||
|
|
||||||
app.register(fastifyStatic, {
|
app.register(fastifyStatic, {
|
||||||
root: bareModulePath,
|
root: bareModulePath,
|
||||||
prefix: "/bareasmodule/",
|
prefix: '/bareasmodule/',
|
||||||
decorateReply: false
|
decorateReply: false,
|
||||||
});
|
});
|
||||||
|
|
||||||
app.register(fastifyStatic, {
|
app.register(fastifyStatic, {
|
||||||
root: baremuxPath,
|
root: baremuxPath,
|
||||||
prefix: "/baremux/",
|
prefix: '/baremux/',
|
||||||
decorateReply: false
|
decorateReply: false,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
// All website files are stored in the /views directory.
|
// All website files are stored in the /views directory.
|
||||||
// This takes one of those files and displays it for a site visitor.
|
// This takes one of those files and displays it for a site visitor.
|
||||||
// Paths like /browsing are converted into paths like /views/pages/surf.html
|
// Paths like /browsing are converted into paths like /views/pages/surf.html
|
||||||
// back here. Which path converts to what is defined in routes.mjs.
|
// back here. Which path converts to what is defined in routes.mjs.
|
||||||
app.get("/:path", (req, reply) => {
|
app.get('/:path', (req, reply) => {
|
||||||
|
// Testing for future features that need cookies to deliver alternate source files.
|
||||||
// Testing for future features that need cookies to deliver alternate source files.
|
if (req.raw.rawHeaders.includes('Cookie'))
|
||||||
if (req.raw.rawHeaders.includes("Cookie"))
|
console.log(req.raw.rawHeaders[req.raw.rawHeaders.indexOf('Cookie') + 1]);
|
||||||
console.log(req.raw.rawHeaders[ req.raw.rawHeaders.indexOf("Cookie") + 1 ]);
|
|
||||||
|
|
||||||
const reqPath = req.params.path;
|
const reqPath = req.params.path;
|
||||||
|
|
||||||
if (reqPath in externalPages) {
|
if (reqPath in externalPages) {
|
||||||
let externalRoute = externalPages[reqPath];
|
let externalRoute = externalPages[reqPath];
|
||||||
if (typeof externalRoute !== "string") externalRoute = externalRoute.default;
|
if (typeof externalRoute !== 'string')
|
||||||
|
externalRoute = externalRoute.default;
|
||||||
return reply.redirect(externalRoute);
|
return reply.redirect(externalRoute);
|
||||||
}
|
}
|
||||||
|
|
||||||
// If a GET request is sent to /test-shutdown and a script-generated shutdown file
|
// If a GET request is sent to /test-shutdown and a script-generated shutdown file
|
||||||
// is present, gracefully shut the server down.
|
// is present, gracefully shut the server down.
|
||||||
if (reqPath === "test-shutdown" && existsSync(shutdown)) {
|
if (reqPath === 'test-shutdown' && existsSync(shutdown)) {
|
||||||
console.log("Holy Unblocker is shutting down.");
|
console.log('Holy Unblocker is shutting down.');
|
||||||
app.close();
|
app.close();
|
||||||
unlinkSync(shutdown);
|
unlinkSync(shutdown);
|
||||||
process.exitCode = 0;
|
process.exitCode = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return the error page if the query is not found in routes.mjs.
|
// Return the error page if the query is not found in routes.mjs.
|
||||||
if (reqPath && !(reqPath in pages))
|
if (reqPath && !(reqPath in pages))
|
||||||
return reply.code(404).type("text/html").send(preloaded404);
|
return reply.code(404).type('text/html').send(preloaded404);
|
||||||
|
|
||||||
reply.type("text/html").send(
|
reply.type('text/html').send(
|
||||||
paintSource(
|
paintSource(
|
||||||
loadTemplates(
|
loadTemplates(
|
||||||
tryReadFile(
|
tryReadFile(
|
||||||
path.join(
|
path.join(
|
||||||
__dirname,
|
__dirname,
|
||||||
"views",
|
'views',
|
||||||
// Set the index the as the default page.
|
// Set the index the as the default page.
|
||||||
reqPath ? pages[reqPath] : pages.index
|
reqPath ? pages[reqPath] : pages.index
|
||||||
)
|
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
);
|
)
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
app.get("/github/:redirect", (req, reply) => {
|
app.get('/github/:redirect', (req, reply) => {
|
||||||
if (req.params.redirect in externalPages.github)
|
if (req.params.redirect in externalPages.github)
|
||||||
reply.redirect(externalPages.github[req.params.redirect]);
|
reply.redirect(externalPages.github[req.params.redirect]);
|
||||||
else reply.code(404).type("text/html").send(preloaded404);
|
else reply.code(404).type('text/html').send(preloaded404);
|
||||||
});
|
});
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -256,7 +261,7 @@ app.get("/assets/js/uv/uv.config.js", (req, reply) => {
|
||||||
|
|
||||||
// Set an error page for invalid paths outside the query string system.
|
// Set an error page for invalid paths outside the query string system.
|
||||||
app.setNotFoundHandler((req, reply) => {
|
app.setNotFoundHandler((req, reply) => {
|
||||||
reply.code(404).type("text/html").send(preloaded404);
|
reply.code(404).type('text/html').send(preloaded404);
|
||||||
});
|
});
|
||||||
|
|
||||||
app.listen({ port: serverUrl.port, host: serverUrl.hostname });
|
app.listen({ port: serverUrl.port, host: serverUrl.hostname });
|
||||||
|
|
|
@ -1,36 +1,25 @@
|
||||||
import { tryReadFile } from "./randomization.mjs";
|
import { tryReadFile } from './randomization.mjs';
|
||||||
import path from "path";
|
import path from 'path';
|
||||||
export { loadTemplates as default };
|
export { loadTemplates as default };
|
||||||
|
|
||||||
const __dirname = path.resolve() + "/views/pages/misc/deobf";
|
const __dirname = path.resolve() + '/views/pages/misc/deobf';
|
||||||
|
|
||||||
const header = tryReadFile(
|
const header = tryReadFile(path.normalize(__dirname + '/header.html')),
|
||||||
path.normalize(__dirname + "/header.html")
|
footer = tryReadFile(path.normalize(__dirname + '/footer.html')),
|
||||||
),
|
documentation = tryReadFile(path.normalize(__dirname + '/docs.html')),
|
||||||
footer = tryReadFile(
|
faq = tryReadFile(path.normalize(__dirname + '/faq.html')),
|
||||||
path.normalize(__dirname + "/footer.html")
|
terms = tryReadFile(path.normalize(__dirname + '/tos.html')),
|
||||||
),
|
settings = tryReadFile(path.normalize(__dirname + '/settings.html')),
|
||||||
documentation = tryReadFile(
|
|
||||||
path.normalize(__dirname + "/docs.html")
|
|
||||||
),
|
|
||||||
faq = tryReadFile(
|
|
||||||
path.normalize(__dirname + "/faq.html")
|
|
||||||
),
|
|
||||||
terms = tryReadFile(
|
|
||||||
path.normalize(__dirname + "/tos.html")
|
|
||||||
),
|
|
||||||
settings = tryReadFile(
|
|
||||||
path.normalize(__dirname + "/settings.html")
|
|
||||||
),
|
|
||||||
loadTemplates = (str) =>
|
loadTemplates = (str) =>
|
||||||
str.replace("<!--HEADER-->", header)
|
str
|
||||||
.replace("<!--FOOTER-->", footer)
|
.replace('<!--HEADER-->', header)
|
||||||
|
.replace('<!--FOOTER-->', footer)
|
||||||
|
|
||||||
// Used only on docs.html
|
// Used only on docs.html
|
||||||
.replace("<!--DOCS-->", documentation)
|
.replace('<!--DOCS-->', documentation)
|
||||||
// Used only on faq.html
|
// Used only on faq.html
|
||||||
.replace("<!--FAQ-->", faq)
|
.replace('<!--FAQ-->', faq)
|
||||||
// Used only on terms.html
|
// Used only on terms.html
|
||||||
.replace("<!--TOS-->", terms)
|
.replace('<!--TOS-->', terms)
|
||||||
// Used only on header.html
|
// Used only on header.html
|
||||||
.replace("<!--SETTINGS-->", settings);
|
.replace('<!--SETTINGS-->', settings);
|
||||||
|
|
|
@ -6,12 +6,12 @@
|
||||||
/* HU CSS
|
/* HU CSS
|
||||||
/* ----------------------------------------------- */
|
/* ----------------------------------------------- */
|
||||||
|
|
||||||
@import url("https://fonts.googleapis.com/css?family=Lato:400,700,400italic");
|
@import url('https://fonts.googleapis.com/css?family=Lato:400,700,400italic');
|
||||||
@import url("https://fonts.googleapis.com/css?family=Montserrat+Alternates");
|
@import url('https://fonts.googleapis.com/css?family=Montserrat+Alternates');
|
||||||
@import url("https://fonts.googleapis.com/css?family=Titillium+Web:400,600,700");
|
@import url('https://fonts.googleapis.com/css?family=Titillium+Web:400,600,700');
|
||||||
@import url('https://fonts.googleapis.com/css2?family=Figtree:ital,wght@0,300..900;1,300..900&display=swap');
|
@import url('https://fonts.googleapis.com/css2?family=Figtree:ital,wght@0,300..900;1,300..900&display=swap');
|
||||||
@import url('https://fonts.googleapis.com/css2?family=Source+Code+Pro:ital,wght@0,200..900;1,200..900&display=swap');
|
@import url('https://fonts.googleapis.com/css2?family=Source+Code+Pro:ital,wght@0,200..900;1,200..900&display=swap');
|
||||||
@import url("https://unpkg.com/@fortawesome/fontawesome-free@5.15.4/css/all.min.css");
|
@import url('https://unpkg.com/@fortawesome/fontawesome-free@5.15.4/css/all.min.css');
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Nord Theme (https://nordtheme.com)
|
Nord Theme (https://nordtheme.com)
|
||||||
|
@ -73,14 +73,13 @@ see https://raw.githubusercontent.com/arcticicestudio/nord-docs/develop/assets/i
|
||||||
--dark: #303030;
|
--dark: #303030;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* -----------------------------------------------
|
/* -----------------------------------------------
|
||||||
/* HU Page Layout / General Styling
|
/* HU Page Layout / General Styling
|
||||||
/* ----------------------------------------------- */
|
/* ----------------------------------------------- */
|
||||||
|
|
||||||
html {
|
html {
|
||||||
color: white;
|
color: white;
|
||||||
font-family: "Figtree", sans-serif;
|
font-family: 'Figtree', sans-serif;
|
||||||
font-weight: 300;
|
font-weight: 300;
|
||||||
scroll-behavior: smooth;
|
scroll-behavior: smooth;
|
||||||
}
|
}
|
||||||
|
@ -114,7 +113,7 @@ h3,
|
||||||
h4,
|
h4,
|
||||||
h5,
|
h5,
|
||||||
h6 {
|
h6 {
|
||||||
font-family: "Figtree", sans-serif;
|
font-family: 'Figtree', sans-serif;
|
||||||
font-weight: 900;
|
font-weight: 900;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -159,11 +158,11 @@ details[open] summary {
|
||||||
}
|
}
|
||||||
|
|
||||||
.font2 {
|
.font2 {
|
||||||
font-family: "Titillium Web", sans-serif;
|
font-family: 'Titillium Web', sans-serif;
|
||||||
}
|
}
|
||||||
|
|
||||||
.font3 {
|
.font3 {
|
||||||
font-family: "Lato", sans-serif;
|
font-family: 'Lato', sans-serif;
|
||||||
}
|
}
|
||||||
|
|
||||||
.notbold {
|
.notbold {
|
||||||
|
@ -240,9 +239,10 @@ details[open] summary {
|
||||||
/* To change the top padding on the footer, change the 3 vw values here to the same thing. */
|
/* To change the top padding on the footer, change the 3 vw values here to the same thing. */
|
||||||
|
|
||||||
#footer {
|
#footer {
|
||||||
font-family: "Lato", sans-serif;
|
font-family: 'Lato', sans-serif;
|
||||||
padding-top: 15vw;
|
padding-top: 15vw;
|
||||||
background: url("/assets/img/waves.svg"), linear-gradient(to bottom, transparent 0 15vw, #1d2029 15vw 100%);
|
background: url('/assets/img/waves.svg'),
|
||||||
|
linear-gradient(to bottom, transparent 0 15vw, #1d2029 15vw 100%);
|
||||||
background-repeat: no-repeat;
|
background-repeat: no-repeat;
|
||||||
background-size: 100vw auto;
|
background-size: 100vw auto;
|
||||||
position: relative;
|
position: relative;
|
||||||
|
@ -258,12 +258,12 @@ details[open] summary {
|
||||||
color: white;
|
color: white;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* -----------------------------------------------
|
/* -----------------------------------------------
|
||||||
/* Icons and Branding
|
/* Icons and Branding
|
||||||
/* ----------------------------------------------- */
|
/* ----------------------------------------------- */
|
||||||
|
|
||||||
.brand-logo-container, .new {
|
.brand-logo-container,
|
||||||
|
.new {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center; /* Align items vertically */
|
align-items: center; /* Align items vertically */
|
||||||
}
|
}
|
||||||
|
@ -275,7 +275,7 @@ details[open] summary {
|
||||||
line-height: 30px;
|
line-height: 30px;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
margin-right: 20px; /* Adjust margin as needed */
|
margin-right: 20px; /* Adjust margin as needed */
|
||||||
font-family: "Figtree", sans-serif;
|
font-family: 'Figtree', sans-serif;
|
||||||
font-weight: 900;
|
font-weight: 900;
|
||||||
letter-spacing: 1px;
|
letter-spacing: 1px;
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
|
@ -304,7 +304,7 @@ details[open] summary {
|
||||||
}
|
}
|
||||||
|
|
||||||
.new::after {
|
.new::after {
|
||||||
content: "";
|
content: '';
|
||||||
padding: 22.75px 25px;
|
padding: 22.75px 25px;
|
||||||
margin-left: 8px;
|
margin-left: 8px;
|
||||||
background-image: url('/assets/img/new.svg');
|
background-image: url('/assets/img/new.svg');
|
||||||
|
@ -312,7 +312,6 @@ details[open] summary {
|
||||||
font-size: 0;
|
font-size: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* -----------------------------------------------
|
/* -----------------------------------------------
|
||||||
/* Navigation Bar and Menus (Header Contents)
|
/* Navigation Bar and Menus (Header Contents)
|
||||||
/* ----------------------------------------------- */
|
/* ----------------------------------------------- */
|
||||||
|
@ -370,7 +369,7 @@ details[open] summary {
|
||||||
cursor: auto;
|
cursor: auto;
|
||||||
padding: 15px 25px;
|
padding: 15px 25px;
|
||||||
margin-top: 10px;
|
margin-top: 10px;
|
||||||
font-family: "Titillium Web", sans-serif;
|
font-family: 'Titillium Web', sans-serif;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* "More" Navigation Menu */
|
/* "More" Navigation Menu */
|
||||||
|
@ -409,7 +408,8 @@ details[open] summary {
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
.dropdown-parent:focus-within .dropdown-settings:not(:is(:has(.close-settings-btn:active))) {
|
.dropdown-parent:focus-within
|
||||||
|
.dropdown-settings:not(:is(:has(.close-settings-btn:active))) {
|
||||||
display: flex; /* Flexbox to center content */
|
display: flex; /* Flexbox to center content */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -435,7 +435,7 @@ details[open] summary {
|
||||||
color: #eceff4;
|
color: #eceff4;
|
||||||
font-family: 'Figtree', sans-serif;
|
font-family: 'Figtree', sans-serif;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
backdrop-filter: blur(10px); /* Frosted glass effect */
|
backdrop-filter: blur(10px); /* Frosted glass effect */
|
||||||
-webkit-backdrop-filter: blur(10px); /* For Safari */
|
-webkit-backdrop-filter: blur(10px); /* For Safari */
|
||||||
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1); /* Optional: Add some shadow for depth */
|
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1); /* Optional: Add some shadow for depth */
|
||||||
|
@ -443,7 +443,7 @@ details[open] summary {
|
||||||
|
|
||||||
.settings-header {
|
.settings-header {
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
margin-bottom: 20px;
|
margin-bottom: 20px;
|
||||||
}
|
}
|
||||||
|
@ -458,12 +458,15 @@ details[open] summary {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
font-size: 24px;
|
font-size: 24px;
|
||||||
font-weight: 100;
|
font-weight: 100;
|
||||||
margin-left: auto;
|
margin-left: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
.close-settings-btn:hover {
|
.close-settings-btn:hover {
|
||||||
color: lightgray;
|
color: lightgray;
|
||||||
transition: background-color 0.3s ease, color 0.3s ease, transform 0.3s ease;
|
transition:
|
||||||
|
background-color 0.3s ease,
|
||||||
|
color 0.3s ease,
|
||||||
|
transform 0.3s ease;
|
||||||
transform: scale(1.05);
|
transform: scale(1.05);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -472,14 +475,15 @@ details[open] summary {
|
||||||
gap: 40px; /* Space between left and right columns */
|
gap: 40px; /* Space between left and right columns */
|
||||||
}
|
}
|
||||||
|
|
||||||
.csel-container-left, .settings-right-column {
|
.csel-container-left,
|
||||||
|
.settings-right-column {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
gap: 15px; /* Space between items within columns */
|
gap: 15px; /* Space between items within columns */
|
||||||
}
|
}
|
||||||
|
|
||||||
.csel-container-left {
|
.csel-container-left {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
max-width: 400px; /* Adjusted to fit content without gaps */
|
max-width: 400px; /* Adjusted to fit content without gaps */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -514,7 +518,7 @@ details[open] summary {
|
||||||
flex: 1; /* Take up available space */
|
flex: 1; /* Take up available space */
|
||||||
}
|
}
|
||||||
|
|
||||||
.radio-group input[type="radio"] {
|
.radio-group input[type='radio'] {
|
||||||
accent-color: #88c0d0;
|
accent-color: #88c0d0;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
width: 20px; /* Adjust size for better appearance */
|
width: 20px; /* Adjust size for better appearance */
|
||||||
|
@ -547,7 +551,7 @@ details[open] summary {
|
||||||
|
|
||||||
.switch::after {
|
.switch::after {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
content: "";
|
content: '';
|
||||||
height: 14px;
|
height: 14px;
|
||||||
width: 14px;
|
width: 14px;
|
||||||
left: 3px;
|
left: 3px;
|
||||||
|
@ -580,7 +584,9 @@ select:hover {
|
||||||
background-color: #4c566a;
|
background-color: #4c566a;
|
||||||
}
|
}
|
||||||
|
|
||||||
.default-badge, .bare-badge, .beta-badge {
|
.default-badge,
|
||||||
|
.bare-badge,
|
||||||
|
.beta-badge {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
padding: 2px 5px;
|
padding: 2px 5px;
|
||||||
border-radius: 5px;
|
border-radius: 5px;
|
||||||
|
@ -605,11 +611,11 @@ select:hover {
|
||||||
|
|
||||||
.cloakform {
|
.cloakform {
|
||||||
display: flex;
|
display: flex;
|
||||||
gap: 10px;
|
gap: 10px;
|
||||||
margin-bottom: 15px;
|
margin-bottom: 15px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.cloakform input[type="text"] {
|
.cloakform input[type='text'] {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
background-color: #3b4252;
|
background-color: #3b4252;
|
||||||
border: 1px solid #4c566a;
|
border: 1px solid #4c566a;
|
||||||
|
@ -619,7 +625,7 @@ select:hover {
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
}
|
}
|
||||||
|
|
||||||
.cloakform input[type="button"] {
|
.cloakform input[type='button'] {
|
||||||
background-color: #5e81ac;
|
background-color: #5e81ac;
|
||||||
border: none;
|
border: none;
|
||||||
border-radius: 5px;
|
border-radius: 5px;
|
||||||
|
@ -628,18 +634,18 @@ select:hover {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
.cloakform input[type="button"]:hover {
|
.cloakform input[type='button']:hover {
|
||||||
background-color: #81a1c1;
|
background-color: #81a1c1;
|
||||||
}
|
}
|
||||||
|
|
||||||
input[type="text"] {
|
input[type='text'] {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
padding: 10px;
|
padding: 10px;
|
||||||
background-color: #3b4252;
|
background-color: #3b4252;
|
||||||
border: 1px solid #4c566a;
|
border: 1px solid #4c566a;
|
||||||
border-radius: 5px;
|
border-radius: 5px;
|
||||||
color: #eceff4;
|
color: #eceff4;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
}
|
}
|
||||||
|
|
||||||
#csel {
|
#csel {
|
||||||
|
@ -649,7 +655,7 @@ input[type="text"] {
|
||||||
gap: 15px;
|
gap: 15px;
|
||||||
}
|
}
|
||||||
|
|
||||||
#csel input:not([type=checkbox]),
|
#csel input:not([type='checkbox']),
|
||||||
#csel select {
|
#csel select {
|
||||||
outline: none;
|
outline: none;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
|
@ -659,20 +665,26 @@ input[type="text"] {
|
||||||
margin: 5px 0;
|
margin: 5px 0;
|
||||||
background-color: var(--nord1);
|
background-color: var(--nord1);
|
||||||
border: 1px solid var(--nord9);
|
border: 1px solid var(--nord9);
|
||||||
transition: background-color 0.3s ease, color 0.3s ease, transform 0.3s ease;
|
transition:
|
||||||
|
background-color 0.3s ease,
|
||||||
|
color 0.3s ease,
|
||||||
|
transform 0.3s ease;
|
||||||
}
|
}
|
||||||
|
|
||||||
#csel input[type=text]:focus {
|
#csel input[type='text']:focus {
|
||||||
box-shadow: inset 0 0 5px 0 var(--nord3);
|
box-shadow: inset 0 0 5px 0 var(--nord3);
|
||||||
transition: box-shadow 0.15s ease-out;
|
transition: box-shadow 0.15s ease-out;
|
||||||
}
|
}
|
||||||
|
|
||||||
#csel input:is([type=submit], [type=button]):hover {
|
#csel input:is([type='submit'], [type='button']):hover {
|
||||||
transition: background-color 0.3s ease, color 0.3s ease, transform 0.3s ease;
|
transition:
|
||||||
|
background-color 0.3s ease,
|
||||||
|
color 0.3s ease,
|
||||||
|
transform 0.3s ease;
|
||||||
transform: scale(1.05);
|
transform: scale(1.05);
|
||||||
}
|
}
|
||||||
|
|
||||||
#csel input:is([type=submit], [type=button]):active {
|
#csel input:is([type='submit'], [type='button']):active {
|
||||||
background-color: #78b0c0;
|
background-color: #78b0c0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -692,10 +704,11 @@ input[type="text"] {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
gap: 10px;
|
gap: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
#hideads, #useonion {
|
#hideads,
|
||||||
|
#useonion {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
margin-left: 0;
|
margin-left: 0;
|
||||||
}
|
}
|
||||||
|
@ -771,7 +784,6 @@ input[type="text"] {
|
||||||
vertical-align: top;
|
vertical-align: top;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* -----------------------------------------------
|
/* -----------------------------------------------
|
||||||
/* Welcome Screen Content (i.e., Big Bold Words)
|
/* Welcome Screen Content (i.e., Big Bold Words)
|
||||||
/* ----------------------------------------------- */
|
/* ----------------------------------------------- */
|
||||||
|
@ -822,7 +834,12 @@ input[type="text"] {
|
||||||
border-radius: 12px;
|
border-radius: 12px;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
background-color: var(--nord0);
|
background-color: var(--nord0);
|
||||||
background-image: url("/assets/img/noise.png"), linear-gradient(145deg, rgba(34,38,47,0.9) 0%, rgba(34,38,47,0.9) 100%);
|
background-image: url('/assets/img/noise.png'),
|
||||||
|
linear-gradient(
|
||||||
|
145deg,
|
||||||
|
rgba(34, 38, 47, 0.9) 0%,
|
||||||
|
rgba(34, 38, 47, 0.9) 100%
|
||||||
|
);
|
||||||
background-blend-mode: overlay;
|
background-blend-mode: overlay;
|
||||||
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
|
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
|
||||||
}
|
}
|
||||||
|
@ -857,7 +874,9 @@ input[type="text"] {
|
||||||
background-color: var(--nord3);
|
background-color: var(--nord3);
|
||||||
}
|
}
|
||||||
|
|
||||||
.no-select, .comment, .mac-content br {
|
.no-select,
|
||||||
|
.comment,
|
||||||
|
.mac-content br {
|
||||||
user-select: none; /* Prevent text selection */
|
user-select: none; /* Prevent text selection */
|
||||||
-webkit-user-select: none; /* For Safari */
|
-webkit-user-select: none; /* For Safari */
|
||||||
-moz-user-select: none; /* For Firefox */
|
-moz-user-select: none; /* For Firefox */
|
||||||
|
@ -866,7 +885,7 @@ input[type="text"] {
|
||||||
|
|
||||||
.mac-content {
|
.mac-content {
|
||||||
color: var(--nord4);
|
color: var(--nord4);
|
||||||
font-family: "Source Code Pro", monospace;
|
font-family: 'Source Code Pro', monospace;
|
||||||
font-optical-sizing: auto;
|
font-optical-sizing: auto;
|
||||||
padding: 40px 0 0 80px;
|
padding: 40px 0 0 80px;
|
||||||
flex: 1;
|
flex: 1;
|
||||||
|
@ -882,24 +901,24 @@ input[type="text"] {
|
||||||
}
|
}
|
||||||
|
|
||||||
.cmd::before {
|
.cmd::before {
|
||||||
content: "$ ";
|
content: '$ ';
|
||||||
color: var(--nord4);
|
color: var(--nord4);
|
||||||
}
|
}
|
||||||
|
|
||||||
.cmd::after {
|
.cmd::after {
|
||||||
content: "\a";
|
content: '\a';
|
||||||
}
|
}
|
||||||
|
|
||||||
.url {
|
.url {
|
||||||
color: rgb(255, 136, 142);
|
color: rgb(255, 136, 142);
|
||||||
}
|
}
|
||||||
|
|
||||||
.comment {
|
.comment {
|
||||||
color: #616E88;
|
color: #616e88;
|
||||||
}
|
}
|
||||||
|
|
||||||
.comment::before {
|
.comment::before {
|
||||||
content: "# ";
|
content: '# ';
|
||||||
}
|
}
|
||||||
|
|
||||||
.homebutton {
|
.homebutton {
|
||||||
|
@ -924,7 +943,9 @@ input[type="text"] {
|
||||||
|
|
||||||
/* NOTE: Currently unused. */
|
/* NOTE: Currently unused. */
|
||||||
.hovermessage:hover {
|
.hovermessage:hover {
|
||||||
transition: color 0.3s ease-in, font-size 0s linear 0.3s;
|
transition:
|
||||||
|
color 0.3s ease-in,
|
||||||
|
font-size 0s linear 0.3s;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* NOTE: Currently unused. */
|
/* NOTE: Currently unused. */
|
||||||
|
@ -937,12 +958,14 @@ input[type="text"] {
|
||||||
/* NOTE: Currently unused. */
|
/* NOTE: Currently unused. */
|
||||||
.hovermessage:hover::before {
|
.hovermessage:hover::before {
|
||||||
font-size: 16px;
|
font-size: 16px;
|
||||||
transition: font-size 0s linear 0.3s, color 0.3s ease-in 0.3s;
|
transition:
|
||||||
|
font-size 0s linear 0.3s,
|
||||||
|
color 0.3s ease-in 0.3s;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* NOTE: Currently unused. */
|
/* NOTE: Currently unused. */
|
||||||
.buttonlink {
|
.buttonlink {
|
||||||
font-family: "Titillium Web", sans-serif;
|
font-family: 'Titillium Web', sans-serif;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
|
@ -1002,11 +1025,10 @@ input[type="text"] {
|
||||||
.text-center {
|
.text-center {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
}
|
}
|
||||||
iner
|
iner .splashstrokeheader {
|
||||||
.splashstrokeheader {
|
|
||||||
position: relative;
|
position: relative;
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
font-size: 36px;
|
font-size: 36px;
|
||||||
line-height: 1.2;
|
line-height: 1.2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1019,18 +1041,18 @@ iner
|
||||||
|
|
||||||
.hero-grid-container {
|
.hero-grid-container {
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
|
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
|
||||||
gap: 40px;
|
gap: 40px;
|
||||||
margin: 40px auto;
|
margin: 40px auto;
|
||||||
width: 90%;
|
width: 90%;
|
||||||
max-width: 1200px;
|
max-width: 1200px;
|
||||||
background-color: rgba(46, 52, 64, 0.2);
|
background-color: rgba(46, 52, 64, 0.2);
|
||||||
border-radius: 10px;
|
border-radius: 10px;
|
||||||
padding: 10px;
|
padding: 10px;
|
||||||
box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
|
box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
|
||||||
border: 1px solid rgba(255, 255, 255, 0.2);
|
border: 1px solid rgba(255, 255, 255, 0.2);
|
||||||
-webkit-backdrop-filter: blur(10px);
|
-webkit-backdrop-filter: blur(10px);
|
||||||
backdrop-filter: blur(10px);
|
backdrop-filter: blur(10px);
|
||||||
position: relative;
|
position: relative;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1038,7 +1060,7 @@ iner
|
||||||
text-align: center;
|
text-align: center;
|
||||||
position: relative;
|
position: relative;
|
||||||
width: 500px;
|
width: 500px;
|
||||||
margin: 0 auto;
|
margin: 0 auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
.carousel-title {
|
.carousel-title {
|
||||||
|
@ -1048,30 +1070,30 @@ iner
|
||||||
}
|
}
|
||||||
|
|
||||||
.carousel-wrapper {
|
.carousel-wrapper {
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
position: relative;
|
position: relative;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
padding: 10px 0;
|
padding: 10px 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.carousel {
|
.carousel {
|
||||||
display: flex;
|
display: flex;
|
||||||
width: auto;
|
width: auto;
|
||||||
animation: scroll 20s linear infinite;
|
animation: scroll 20s linear infinite;
|
||||||
}
|
}
|
||||||
|
|
||||||
.carousel-inner {
|
.carousel-inner {
|
||||||
display: flex;
|
display: flex;
|
||||||
width: auto;
|
width: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
.dependencylogo {
|
.dependencylogo {
|
||||||
flex: 0 0 auto;
|
flex: 0 0 auto;
|
||||||
margin: 0 15px;
|
margin: 0 15px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.dependencylogo img {
|
.dependencylogo img {
|
||||||
width: 50px;
|
width: 50px;
|
||||||
height: auto;
|
height: auto;
|
||||||
padding: 10px;
|
padding: 10px;
|
||||||
border-radius: 20px;
|
border-radius: 20px;
|
||||||
|
@ -1083,7 +1105,7 @@ iner
|
||||||
transform: translateX(0);
|
transform: translateX(0);
|
||||||
}
|
}
|
||||||
100% {
|
100% {
|
||||||
transform: translateX(-100%);
|
transform: translateX(-100%);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1098,20 +1120,28 @@ iner
|
||||||
}
|
}
|
||||||
|
|
||||||
.box-hero::after {
|
.box-hero::after {
|
||||||
content: "";
|
content: '';
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 0;
|
top: 0;
|
||||||
left: 0;
|
left: 0;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
background: url("/assets/img/noise.png") repeat, rgba(255, 255, 255, 0.03);
|
background:
|
||||||
opacity: var(--noise-opacity, 0.02);
|
url('/assets/img/noise.png') repeat,
|
||||||
|
rgba(255, 255, 255, 0.03);
|
||||||
|
opacity: var(--noise-opacity, 0.02);
|
||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
-webkit-mask-image: radial-gradient(circle, white 30%, transparent 50%);
|
-webkit-mask-image: radial-gradient(circle, white 30%, transparent 50%);
|
||||||
-webkit-mask-size: 800px 800px;
|
-webkit-mask-size: 800px 800px;
|
||||||
-webkit-mask-position: calc(var(--mouse-x) - 400px) calc(var(--mouse-y) - 400px);
|
-webkit-mask-position: calc(var(--mouse-x) - 400px)
|
||||||
|
calc(var(--mouse-y) - 400px);
|
||||||
-webkit-mask-repeat: no-repeat;
|
-webkit-mask-repeat: no-repeat;
|
||||||
mask-image: radial-gradient(closest-side, rgba(37, 35, 35, 0.377) 30%, rgba(255, 255, 255, 0.048) 70%, transparent 90%);
|
mask-image: radial-gradient(
|
||||||
|
closest-side,
|
||||||
|
rgba(37, 35, 35, 0.377) 30%,
|
||||||
|
rgba(255, 255, 255, 0.048) 70%,
|
||||||
|
transparent 90%
|
||||||
|
);
|
||||||
mask-size: 800px 800px;
|
mask-size: 800px 800px;
|
||||||
mask-position: calc(var(--mouse-x) - 400px) calc(var(--mouse-y) - 400px);
|
mask-position: calc(var(--mouse-x) - 400px) calc(var(--mouse-y) - 400px);
|
||||||
mask-repeat: no-repeat;
|
mask-repeat: no-repeat;
|
||||||
|
@ -1139,7 +1169,7 @@ iner
|
||||||
|
|
||||||
.hero-text-wrap {
|
.hero-text-wrap {
|
||||||
max-width: 53ch;
|
max-width: 53ch;
|
||||||
margin-right: 25%;
|
margin-right: 25%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.hero-text-wrap p {
|
.hero-text-wrap p {
|
||||||
|
@ -1151,13 +1181,13 @@ iner
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
.hero {
|
.hero {
|
||||||
width: 100%; /* Ensure the image takes full width of its container */
|
width: 100%; /* Ensure the image takes full width of its container */
|
||||||
max-width: 300px; /* Ensure the image doesn't exceed its container */
|
max-width: 300px; /* Ensure the image doesn't exceed its container */
|
||||||
height: auto;
|
height: auto;
|
||||||
border-radius: 50%;
|
border-radius: 50%;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1184,7 +1214,7 @@ iner
|
||||||
.grid-container {
|
.grid-container {
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-columns: 1fr;
|
grid-template-columns: 1fr;
|
||||||
gap: 80px;
|
gap: 80px;
|
||||||
margin: 80px;
|
margin: 80px;
|
||||||
margin-top: 300px;
|
margin-top: 300px;
|
||||||
padding: 0 20px; /* Add padding to prevent overflow */
|
padding: 0 20px; /* Add padding to prevent overflow */
|
||||||
|
@ -1205,20 +1235,28 @@ iner
|
||||||
}
|
}
|
||||||
|
|
||||||
.box-card::after {
|
.box-card::after {
|
||||||
content: "";
|
content: '';
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 0;
|
top: 0;
|
||||||
left: 0;
|
left: 0;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
background: url("/assets/img/noise.png") repeat, rgba(46, 52, 64, 0.03);
|
background:
|
||||||
opacity: var(--noise-opacity, 0.02);
|
url('/assets/img/noise.png') repeat,
|
||||||
|
rgba(46, 52, 64, 0.03);
|
||||||
|
opacity: var(--noise-opacity, 0.02);
|
||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
-webkit-mask-image: radial-gradient(circle, white 30%, transparent 50%);
|
-webkit-mask-image: radial-gradient(circle, white 30%, transparent 50%);
|
||||||
-webkit-mask-size: 800px 800px;
|
-webkit-mask-size: 800px 800px;
|
||||||
-webkit-mask-position: calc(var(--mouse-x) - 400px) calc(var(--mouse-y) - 400px);
|
-webkit-mask-position: calc(var(--mouse-x) - 400px)
|
||||||
|
calc(var(--mouse-y) - 400px);
|
||||||
-webkit-mask-repeat: no-repeat;
|
-webkit-mask-repeat: no-repeat;
|
||||||
mask-image: radial-gradient(closest-side, rgba(37, 35, 35, 0.377) 30%, rgba(255, 255, 255, 0.048) 70%, transparent 90%);
|
mask-image: radial-gradient(
|
||||||
|
closest-side,
|
||||||
|
rgba(37, 35, 35, 0.377) 30%,
|
||||||
|
rgba(255, 255, 255, 0.048) 70%,
|
||||||
|
transparent 90%
|
||||||
|
);
|
||||||
mask-size: 800px 800px;
|
mask-size: 800px 800px;
|
||||||
mask-position: calc(var(--mouse-x) - 400px) calc(var(--mouse-y) - 400px);
|
mask-position: calc(var(--mouse-x) - 400px) calc(var(--mouse-y) - 400px);
|
||||||
mask-repeat: no-repeat;
|
mask-repeat: no-repeat;
|
||||||
|
@ -1235,8 +1273,8 @@ iner
|
||||||
.box-card .content {
|
.box-card .content {
|
||||||
width: calc(95% - min(30%, 180px) - 32px);
|
width: calc(95% - min(30%, 180px) - 32px);
|
||||||
margin-right: 20px;
|
margin-right: 20px;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
overflow-wrap: break-word
|
overflow-wrap: break-word;
|
||||||
}
|
}
|
||||||
|
|
||||||
.image-container {
|
.image-container {
|
||||||
|
@ -1244,7 +1282,7 @@ iner
|
||||||
right: 5%;
|
right: 5%;
|
||||||
top: 50%;
|
top: 50%;
|
||||||
transform: translateY(-50%);
|
transform: translateY(-50%);
|
||||||
width: 30%;
|
width: 30%;
|
||||||
max-width: 180px; /* Add a max-width to prevent it from getting too large */
|
max-width: 180px; /* Add a max-width to prevent it from getting too large */
|
||||||
height: auto;
|
height: auto;
|
||||||
background-color: var(--nord0m3);
|
background-color: var(--nord0m3);
|
||||||
|
@ -1391,10 +1429,6 @@ iner
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
.box-large {
|
.box-large {
|
||||||
width: 80vw;
|
width: 80vw;
|
||||||
margin: 20px auto;
|
margin: 20px auto;
|
||||||
|
@ -1406,7 +1440,7 @@ iner
|
||||||
|
|
||||||
.box-error {
|
.box-error {
|
||||||
margin: 40vh 0;
|
margin: 40vh 0;
|
||||||
font-family: "Lato", sans-serif;
|
font-family: 'Lato', sans-serif;
|
||||||
}
|
}
|
||||||
|
|
||||||
.box-error h1 {
|
.box-error h1 {
|
||||||
|
@ -1437,13 +1471,12 @@ iner
|
||||||
margin-bottom: 8px;
|
margin-bottom: 8px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* -----------------------------------------------
|
/* -----------------------------------------------
|
||||||
/* Documentation and FAQ Pages
|
/* Documentation and FAQ Pages
|
||||||
/* ----------------------------------------------- */
|
/* ----------------------------------------------- */
|
||||||
|
|
||||||
#documentation {
|
#documentation {
|
||||||
font-family: "Lato", sans-serif;
|
font-family: 'Lato', sans-serif;
|
||||||
}
|
}
|
||||||
|
|
||||||
#documentation code {
|
#documentation code {
|
||||||
|
@ -1498,8 +1531,8 @@ iner
|
||||||
}
|
}
|
||||||
|
|
||||||
.ad::before {
|
.ad::before {
|
||||||
content: "Advertisement";
|
content: 'Advertisement';
|
||||||
font-family: "Titillium Web", sans-serif;
|
font-family: 'Titillium Web', sans-serif;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
z-index: -1;
|
z-index: -1;
|
||||||
left: 50%;
|
left: 50%;
|
||||||
|
@ -1527,21 +1560,21 @@ iner
|
||||||
border-radius: 5px;
|
border-radius: 5px;
|
||||||
padding: 10px 12px;
|
padding: 10px 12px;
|
||||||
color: white;
|
color: white;
|
||||||
font-family: "Montserrat Alternates", sans-serif;
|
font-family: 'Montserrat Alternates', sans-serif;
|
||||||
font-size: 20px;
|
font-size: 20px;
|
||||||
margin: 3px;
|
margin: 3px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.pr-form input[type=text] {
|
.pr-form input[type='text'] {
|
||||||
max-width: 700px;
|
max-width: 700px;
|
||||||
width: calc(100% - 44px);
|
width: calc(100% - 44px);
|
||||||
}
|
}
|
||||||
|
|
||||||
.pr-form input[type=text]:focus {
|
.pr-form input[type='text']:focus {
|
||||||
animation: glowshadow 2s linear infinite;
|
animation: glowshadow 2s linear infinite;
|
||||||
}
|
}
|
||||||
|
|
||||||
.pr-form input[type=text]::placeholder {
|
.pr-form input[type='text']::placeholder {
|
||||||
color: var(--gray);
|
color: var(--gray);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1604,7 +1637,6 @@ iner
|
||||||
background-color: #111;
|
background-color: #111;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* -----------------------------------------------
|
/* -----------------------------------------------
|
||||||
/* HU Games Directory
|
/* HU Games Directory
|
||||||
/* ----------------------------------------------- */
|
/* ----------------------------------------------- */
|
||||||
|
@ -1616,7 +1648,7 @@ iner
|
||||||
/* Games list for non-flash games */
|
/* Games list for non-flash games */
|
||||||
|
|
||||||
.glist {
|
.glist {
|
||||||
font-family: "Lato", sans-serif;
|
font-family: 'Lato', sans-serif;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-wrap: wrap;
|
flex-wrap: wrap;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
|
@ -1660,7 +1692,7 @@ iner
|
||||||
/* Flash Games Search Bar */
|
/* Flash Games Search Bar */
|
||||||
|
|
||||||
#fsearchbar {
|
#fsearchbar {
|
||||||
font-family: "Lato", sans-serif;
|
font-family: 'Lato', sans-serif;
|
||||||
font-size: 16px;
|
font-size: 16px;
|
||||||
background-color: var(--nord0);
|
background-color: var(--nord0);
|
||||||
outline: none;
|
outline: none;
|
||||||
|
@ -1678,7 +1710,7 @@ iner
|
||||||
/* Flash Games List */
|
/* Flash Games List */
|
||||||
|
|
||||||
.flist {
|
.flist {
|
||||||
font-family: "Lato", sans-serif;
|
font-family: 'Lato', sans-serif;
|
||||||
background-color: var(--nord0);
|
background-color: var(--nord0);
|
||||||
width: 400px;
|
width: 400px;
|
||||||
height: calc(100vh - 92px);
|
height: calc(100vh - 92px);
|
||||||
|
@ -1713,7 +1745,6 @@ iner
|
||||||
margin: 40px 0 32px;
|
margin: 40px 0 32px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* -----------------------------------------------
|
/* -----------------------------------------------
|
||||||
/* CSS Animations
|
/* CSS Animations
|
||||||
/* ----------------------------------------------- */
|
/* ----------------------------------------------- */
|
||||||
|
@ -1753,7 +1784,10 @@ iner
|
||||||
}
|
}
|
||||||
|
|
||||||
.pulse:hover {
|
.pulse:hover {
|
||||||
transition: background-color 0.3s ease, color 0.3s ease, transform 0.3s ease;
|
transition:
|
||||||
|
background-color 0.3s ease,
|
||||||
|
color 0.3s ease,
|
||||||
|
transform 0.3s ease;
|
||||||
transform: scale(1.05);
|
transform: scale(1.05);
|
||||||
-webkit-font-smoothing: subpixel-antialiased;
|
-webkit-font-smoothing: subpixel-antialiased;
|
||||||
}
|
}
|
||||||
|
@ -1785,7 +1819,7 @@ iner
|
||||||
}
|
}
|
||||||
|
|
||||||
.glowbutton::after {
|
.glowbutton::after {
|
||||||
content: "";
|
content: '';
|
||||||
border-radius: inherit;
|
border-radius: inherit;
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
|
@ -1806,10 +1840,11 @@ iner
|
||||||
.glowbutton:active::after {
|
.glowbutton:active::after {
|
||||||
background: linear-gradient(90deg, var(--nord7), var(--nord8), var(--nord7));
|
background: linear-gradient(90deg, var(--nord7), var(--nord8), var(--nord7));
|
||||||
background-size: 100px auto;
|
background-size: 100px auto;
|
||||||
animation: glowshadow 2s linear infinite, glowbg 2s linear infinite;
|
animation:
|
||||||
|
glowshadow 2s linear infinite,
|
||||||
|
glowbg 2s linear infinite;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* -----------------------------------------------
|
/* -----------------------------------------------
|
||||||
/* Mobile Support
|
/* Mobile Support
|
||||||
/* ----------------------------------------------- */
|
/* ----------------------------------------------- */
|
||||||
|
@ -1842,9 +1877,11 @@ iner
|
||||||
|
|
||||||
.mnavebutton::before,
|
.mnavebutton::before,
|
||||||
.mnavebutton::after {
|
.mnavebutton::after {
|
||||||
content: "";
|
content: '';
|
||||||
position: absolute;
|
position: absolute;
|
||||||
transition: transform 0.2s ease-out, top 0.2s ease-out;
|
transition:
|
||||||
|
transform 0.2s ease-out,
|
||||||
|
top 0.2s ease-out;
|
||||||
}
|
}
|
||||||
|
|
||||||
.mnavebutton {
|
.mnavebutton {
|
||||||
|
@ -1882,7 +1919,6 @@ iner
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* -----------------------------------------------
|
/* -----------------------------------------------
|
||||||
/* CSS Media Queries (largely for mobile support)
|
/* CSS Media Queries (largely for mobile support)
|
||||||
/* ----------------------------------------------- */
|
/* ----------------------------------------------- */
|
||||||
|
@ -1953,7 +1989,7 @@ iner
|
||||||
#banner {
|
#banner {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
.mnave {
|
.mnave {
|
||||||
display: none !important;
|
display: none !important;
|
||||||
}
|
}
|
||||||
|
@ -2051,7 +2087,6 @@ iner
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (max-width: 600px) {
|
@media (max-width: 600px) {
|
||||||
|
|
||||||
#header {
|
#header {
|
||||||
padding: 15px 30px;
|
padding: 15px 30px;
|
||||||
}
|
}
|
||||||
|
@ -2065,7 +2100,8 @@ iner
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.navbar, .navbar-1 {
|
.navbar,
|
||||||
|
.navbar-1 {
|
||||||
font-size: 11px;
|
font-size: 11px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2116,13 +2152,15 @@ iner
|
||||||
margin-top: 7px;
|
margin-top: 7px;
|
||||||
}
|
}
|
||||||
|
|
||||||
#csel input:not([type=checkbox]), #csel select {
|
#csel input:not([type='checkbox']),
|
||||||
|
#csel select {
|
||||||
padding: 7px 8px;
|
padding: 7px 8px;
|
||||||
margin: 3.5px 1.75px;
|
margin: 3.5px 1.75px;
|
||||||
font-size: 11px;
|
font-size: 11px;
|
||||||
}
|
}
|
||||||
|
|
||||||
#csel .cseltitle ~ input:not([type=checkbox]), #csel select {
|
#csel .cseltitle ~ input:not([type='checkbox']),
|
||||||
|
#csel select {
|
||||||
width: calc(100% - 94.5px);
|
width: calc(100% - 94.5px);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2134,7 +2172,8 @@ iner
|
||||||
width: 60vw;
|
width: 60vw;
|
||||||
}
|
}
|
||||||
|
|
||||||
.hero, .image-container {
|
.hero,
|
||||||
|
.image-container {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2206,4 +2245,4 @@ iner
|
||||||
.splashend > h1 {
|
.splashend > h1 {
|
||||||
font-size: 1.625em;
|
font-size: 1.625em;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -7,35 +7,31 @@
|
||||||
// Encase everything in a new scope so that variables are not accidentally
|
// Encase everything in a new scope so that variables are not accidentally
|
||||||
// attached to the global scope.
|
// attached to the global scope.
|
||||||
(() => {
|
(() => {
|
||||||
|
// Track the cursor position with respect to the top left of the card.
|
||||||
|
// The "this" keyword gets the element that invoked the event listener.
|
||||||
|
const handleMouseMove = (element) => {
|
||||||
|
element.addEventListener('mousemove', (e) => {
|
||||||
|
const rect = element.getBoundingClientRect();
|
||||||
|
const x = e.clientX - rect.left;
|
||||||
|
const y = e.clientY - rect.top;
|
||||||
|
|
||||||
// Track the cursor position with respect to the top left of the card.
|
element.style.setProperty('--mouse-x', `${x}px`);
|
||||||
// The "this" keyword gets the element that invoked the event listener.
|
element.style.setProperty('--mouse-y', `${y}px`);
|
||||||
const handleMouseMove = element => {
|
});
|
||||||
element.addEventListener("mousemove", e => {
|
},
|
||||||
const rect = element.getBoundingClientRect();
|
// Reset the cursor tracking variables when the cursor leaves the card.
|
||||||
const x = e.clientX - rect.left;
|
handleMouseLeave = (element) => {
|
||||||
const y = e.clientY - rect.top;
|
element.addEventListener('mouseleave', () => {
|
||||||
|
element.style.setProperty('--mouse-x', `50%`);
|
||||||
|
element.style.setProperty('--mouse-y', `50%`);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
// Get the box card elements and add the event listeners to them.
|
||||||
|
shimmerEffects = document.querySelectorAll('.box-card, .box-hero');
|
||||||
|
|
||||||
element.style.setProperty("--mouse-x", `${x}px`);
|
// Attach CSS variables, mouse-x and mouse-y, to elements that will be
|
||||||
element.style.setProperty("--mouse-y", `${y}px`);
|
// given shimmer effects, by adding or modifying the style attribute.
|
||||||
});
|
// CSS calculates and renders the actual shimmer effect from there.
|
||||||
},
|
shimmerEffects.forEach(handleMouseMove);
|
||||||
|
shimmerEffects.forEach(handleMouseLeave);
|
||||||
// Reset the cursor tracking variables when the cursor leaves the card.
|
})();
|
||||||
handleMouseLeave = element => {
|
|
||||||
element.addEventListener("mouseleave", () => {
|
|
||||||
element.style.setProperty("--mouse-x", `50%`);
|
|
||||||
element.style.setProperty("--mouse-y", `50%`);
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
// Get the box card elements and add the event listeners to them.
|
|
||||||
shimmerEffects = document.querySelectorAll(".box-card, .box-hero");
|
|
||||||
|
|
||||||
// Attach CSS variables, mouse-x and mouse-y, to elements that will be
|
|
||||||
// given shimmer effects, by adding or modifying the style attribute.
|
|
||||||
// CSS calculates and renders the actual shimmer effect from there.
|
|
||||||
shimmerEffects.forEach(handleMouseMove);
|
|
||||||
shimmerEffects.forEach(handleMouseLeave);
|
|
||||||
|
|
||||||
})();
|
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -5,150 +5,168 @@
|
||||||
/* Settings Menu
|
/* Settings Menu
|
||||||
/* ----------------------------------------------- */
|
/* ----------------------------------------------- */
|
||||||
|
|
||||||
|
|
||||||
// Encase everything in a new scope so that variables are not accidentally
|
// Encase everything in a new scope so that variables are not accidentally
|
||||||
// attached to the global scope.
|
// attached to the global scope.
|
||||||
(() => {
|
(() => {
|
||||||
|
// Determine the expiration date of a new cookie.
|
||||||
|
let date = new Date();
|
||||||
|
date.setFullYear(date.getFullYear() + 100);
|
||||||
|
date = date.toUTCString();
|
||||||
|
|
||||||
// Determine the expiration date of a new cookie.
|
// All cookies should be secure and are intended to work in iframes.
|
||||||
let date = new Date();
|
const setCookie = (name, value) => {
|
||||||
date.setFullYear(date.getFullYear() + 100);
|
document.cookie =
|
||||||
date = date.toUTCString();
|
name +
|
||||||
|
`=${encodeURIComponent(value)}; expires=${date}; SameSite=None; Secure;`;
|
||||||
|
},
|
||||||
|
removeCookie = (name) => {
|
||||||
|
document.cookie =
|
||||||
|
name +
|
||||||
|
'=; expires=Thu, 01 Jan 1970 00:00:01 GMT; SameSite=None; Secure;';
|
||||||
|
},
|
||||||
|
readCookie = async (name) => {
|
||||||
|
// Get the first cookie that has the same name.
|
||||||
|
for (let cookie of document.cookie.split('; '))
|
||||||
|
if (!cookie.indexOf(name + '='))
|
||||||
|
// Return the cookie's stored content.
|
||||||
|
return decodeURIComponent(cookie.slice(name.length + 1));
|
||||||
|
},
|
||||||
|
// Customize the page's title.
|
||||||
|
pageTitle = (value) => {
|
||||||
|
let tag =
|
||||||
|
document.getElementsByTagName('title')[0] ||
|
||||||
|
document.createElement('title');
|
||||||
|
tag.innerHTML = value;
|
||||||
|
document.head.appendChild(tag);
|
||||||
|
},
|
||||||
|
// Set the page's favicon to a new URL.
|
||||||
|
pageIcon = (value) => {
|
||||||
|
let tag =
|
||||||
|
document.querySelector("link[rel*='icon']") ||
|
||||||
|
document.createElement('link');
|
||||||
|
tag.rel = 'icon';
|
||||||
|
tag.href = value;
|
||||||
|
document.head.appendChild(tag);
|
||||||
|
},
|
||||||
|
// Make a small stylesheet to override a setting from the main stylesheet.
|
||||||
|
pageShowAds = () => {
|
||||||
|
let advertising = document.createElement('style');
|
||||||
|
advertising.id = 'advertising';
|
||||||
|
advertising.innerText = '.ad { display:block; }';
|
||||||
|
(
|
||||||
|
document.head ||
|
||||||
|
document.body ||
|
||||||
|
document.documentElement ||
|
||||||
|
document
|
||||||
|
).appendChild(advertising);
|
||||||
|
},
|
||||||
|
// Remove the stylesheet made by the function above, if it exists.
|
||||||
|
pageHideAds = () => {
|
||||||
|
(document.getElementById('advertising') || new Text()).remove();
|
||||||
|
},
|
||||||
|
// These titles and icons are used as autofill templates by settings.html.
|
||||||
|
// The icon URLs and tab titles may need to be updated over time.
|
||||||
|
presetIcons = Object.freeze({
|
||||||
|
'': ' \n ',
|
||||||
|
Google: 'Google \n https://www.google.com/favicon.ico',
|
||||||
|
Bing: 'Bing \n https://www.bing.com/sa/simg/favicon-trans-bg-blue-mg-28.ico',
|
||||||
|
'Google Drive':
|
||||||
|
'Home - Google Drive \n https://ssl.gstatic.com/images/branding/product/2x/drive_2020q4_48dp.png',
|
||||||
|
Gmail:
|
||||||
|
'Inbox - Gmail \n https://ssl.gstatic.com/ui/v1/icons/mail/rfr/gmail.ico',
|
||||||
|
}),
|
||||||
|
// Choose the default transport mode, for proxying, based on the browser.
|
||||||
|
// Firefox is not supported by epoxy yet, which is why this is implemented.
|
||||||
|
defaultMode = /(?:Chrome|AppleWebKit)\//.test(navigator.userAgent)
|
||||||
|
? 'epoxy'
|
||||||
|
: 'libcurl';
|
||||||
|
|
||||||
// All cookies should be secure and are intended to work in iframes.
|
// Load a custom page title and favicon if it was previously stored.
|
||||||
const setCookie = (name, value) => {
|
readCookie('HBTitle').then((s) => {
|
||||||
document.cookie = name + `=${encodeURIComponent(value)}; expires=${date}; SameSite=None; Secure;`;
|
s != undefined && pageTitle(s);
|
||||||
},
|
});
|
||||||
|
readCookie('HBIcon').then((s) => {
|
||||||
|
s != undefined && pageIcon(s);
|
||||||
|
});
|
||||||
|
|
||||||
removeCookie = name => {
|
// Load the UV transport mode that was last used, or use the default.
|
||||||
document.cookie = name + "=; expires=Thu, 01 Jan 1970 00:00:01 GMT; SameSite=None; Secure;";
|
readCookie('HBTransport').then((s) => {
|
||||||
},
|
let transportMode = document.querySelector(
|
||||||
|
`#uv-transport-list input[value="${s || defaultMode}"]`
|
||||||
|
);
|
||||||
|
if (transportMode) transportMode.click();
|
||||||
|
});
|
||||||
|
|
||||||
readCookie = async name => {
|
// Ads are disabled by default. Load ads if ads were enabled previously.
|
||||||
for (let cookie of document.cookie.split("; "))
|
// Change !== to === here if ads should be enabled by default.
|
||||||
// Get the first cookie that has the same name.
|
readCookie('HBHideAds').then((s) => {
|
||||||
if (!cookie.indexOf(name + "="))
|
s !== 'false'
|
||||||
// Return the cookie's stored content.
|
? pageHideAds()
|
||||||
return decodeURIComponent(cookie.slice(name.length + 1));
|
: pageShowAds(((document.getElementById('hideads') || {}).checked = 0));
|
||||||
},
|
});
|
||||||
|
|
||||||
// Customize the page's title.
|
// Tor is disabled by default. Enable Tor if it was enabled previously.
|
||||||
pageTitle = value => {
|
readCookie('HBUseOnion').then((s) => {
|
||||||
let tag = document.getElementsByTagName("title")[0] || document.createElement("title");
|
if (s === 'true') {
|
||||||
tag.innerHTML = value;
|
let torCheck = document.getElementById('useonion') || {
|
||||||
document.head.appendChild(tag);
|
dispatchEvent: () => {},
|
||||||
},
|
};
|
||||||
|
torCheck.checked = 1;
|
||||||
// Set the page's favicon to a new URL.
|
torCheck.dispatchEvent(new Event('change'));
|
||||||
pageIcon = value => {
|
|
||||||
let tag = document.querySelector("link[rel*='icon']") || document.createElement("link");
|
|
||||||
tag.rel = "icon";
|
|
||||||
tag.href = value;
|
|
||||||
document.head.appendChild(tag);
|
|
||||||
},
|
|
||||||
|
|
||||||
// Make a small stylesheet to override a setting from the main stylesheet.
|
|
||||||
pageShowAds = () => {
|
|
||||||
let advertising = document.createElement("style");
|
|
||||||
advertising.id = "advertising";
|
|
||||||
advertising.innerText = ".ad { display:block; }";
|
|
||||||
(document.head || document.body || document.documentElement || document).appendChild(advertising);
|
|
||||||
},
|
|
||||||
|
|
||||||
// Remove the stylesheet made by the function above, if it exists.
|
|
||||||
pageHideAds = () => {
|
|
||||||
(document.getElementById("advertising")||new Text()).remove();
|
|
||||||
},
|
|
||||||
|
|
||||||
// These titles and icons are used as autofill templates by settings.html.
|
|
||||||
// The icon URLs and tab titles may need to be updated over time.
|
|
||||||
presetIcons = Object.freeze({
|
|
||||||
"": " \n ",
|
|
||||||
"Google": "Google \n https://www.google.com/favicon.ico",
|
|
||||||
"Bing": "Bing \n https://www.bing.com/sa/simg/favicon-trans-bg-blue-mg-28.ico",
|
|
||||||
"Google Drive": "Home - Google Drive \n https://ssl.gstatic.com/images/branding/product/2x/drive_2020q4_48dp.png",
|
|
||||||
"Gmail": "Inbox - Gmail \n https://ssl.gstatic.com/ui/v1/icons/mail/rfr/gmail.ico"
|
|
||||||
}),
|
|
||||||
|
|
||||||
// Choose the default transport mode, for proxying, based on the browser.
|
|
||||||
// Firefox is not supported by epoxy yet, which is why this is implemented.
|
|
||||||
defaultMode = /(?:Chrome|AppleWebKit)\//.test(navigator.userAgent)
|
|
||||||
? "epoxy"
|
|
||||||
: "libcurl";
|
|
||||||
|
|
||||||
|
|
||||||
// Load a custom page title and favicon if it was previously stored.
|
|
||||||
readCookie("HBTitle").then(s => {(s != undefined) && pageTitle(s)});
|
|
||||||
readCookie("HBIcon").then(s => {(s != undefined) && pageIcon(s)});
|
|
||||||
|
|
||||||
// Load the UV transport mode that was last used, or use the default.
|
|
||||||
readCookie("HBTransport").then(s => {
|
|
||||||
let transportMode =
|
|
||||||
document.querySelector(`#uv-transport-list input[value="${
|
|
||||||
s || defaultMode
|
|
||||||
}"]`);
|
|
||||||
if (transportMode) transportMode.click();
|
|
||||||
});
|
|
||||||
|
|
||||||
// Ads are disabled by default. Load ads if ads were enabled previously.
|
|
||||||
// Change !== to === here if ads should be enabled by default.
|
|
||||||
readCookie("HBHideAds").then(s => {(s !== "false") ? pageHideAds() : pageShowAds((document.getElementById("hideads") || {}).checked = 0)});
|
|
||||||
|
|
||||||
// Tor is disabled by default. Enable Tor if it was enabled previously.
|
|
||||||
readCookie("HBUseOnion").then(s => {if (s === "true") {
|
|
||||||
let torCheck = document.getElementById("useonion") ||
|
|
||||||
{dispatchEvent: () => {}};
|
|
||||||
torCheck.checked = 1;
|
|
||||||
torCheck.dispatchEvent(new Event("change"));
|
|
||||||
}});
|
|
||||||
|
|
||||||
|
|
||||||
// All code below is used by the Settings UI in the navigation bar.
|
|
||||||
if (document.getElementById("csel")) {
|
|
||||||
const attachEventListener = (selector, ...args) => (
|
|
||||||
document.getElementById(selector) ||
|
|
||||||
document.querySelector(selector)
|
|
||||||
).addEventListener(...args),
|
|
||||||
focusElement =
|
|
||||||
document.getElementsByClassName("dropdown-settings")[0].parentElement.querySelector("a[href='#']");
|
|
||||||
|
|
||||||
attachEventListener(".dropdown-settings .close-settings-btn", "click",
|
|
||||||
() => {document.activeElement.blur()}
|
|
||||||
);
|
|
||||||
|
|
||||||
// Allow users to set a custom title with the UI.
|
|
||||||
attachEventListener("titleform", "submit", e => {
|
|
||||||
e.preventDefault();
|
|
||||||
e = e.target.firstElementChild;
|
|
||||||
if (e.value) {
|
|
||||||
pageTitle(e.value);
|
|
||||||
setCookie("HBTitle", e.value);
|
|
||||||
e.value = "";
|
|
||||||
} else if (confirm("Reset the title to default?")) {
|
|
||||||
// Allow users to reset the title to default if nothing is entered.
|
|
||||||
focusElement.focus();
|
|
||||||
removeCookie("HBTitle");
|
|
||||||
pageTitle("Holy Unblocker LTS");
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// Allow users to set a custom favicon with the UI.
|
// All code below is used by the Settings UI in the navigation bar.
|
||||||
attachEventListener("iconform", "submit", e => {
|
if (document.getElementById('csel')) {
|
||||||
e.preventDefault();
|
const attachEventListener = (selector, ...args) =>
|
||||||
e = e.target.firstElementChild;
|
(
|
||||||
if (e.value) {
|
document.getElementById(selector) || document.querySelector(selector)
|
||||||
pageIcon(e.value);
|
).addEventListener(...args),
|
||||||
setCookie("HBIcon", e.value);
|
focusElement = document
|
||||||
e.value = "";
|
.getElementsByClassName('dropdown-settings')[0]
|
||||||
} else if (confirm("Reset the icon to default?")) {
|
.parentElement.querySelector("a[href='#']");
|
||||||
// Allow users to reset the favicon to default if nothing is entered.
|
|
||||||
focusElement.focus();
|
|
||||||
removeCookie("HBIcon");
|
|
||||||
pageIcon("assets/img/icon.png");
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
/*
|
attachEventListener(
|
||||||
|
'.dropdown-settings .close-settings-btn',
|
||||||
|
'click',
|
||||||
|
() => {
|
||||||
|
document.activeElement.blur();
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
// Allow users to set a custom title with the UI.
|
||||||
|
attachEventListener('titleform', 'submit', (e) => {
|
||||||
|
e.preventDefault();
|
||||||
|
e = e.target.firstElementChild;
|
||||||
|
if (e.value) {
|
||||||
|
pageTitle(e.value);
|
||||||
|
setCookie('HBTitle', e.value);
|
||||||
|
e.value = '';
|
||||||
|
} else if (confirm('Reset the title to default?')) {
|
||||||
|
// Allow users to reset the title to default if nothing is entered.
|
||||||
|
focusElement.focus();
|
||||||
|
removeCookie('HBTitle');
|
||||||
|
pageTitle('Holy Unblocker LTS');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Allow users to set a custom favicon with the UI.
|
||||||
|
attachEventListener('iconform', 'submit', (e) => {
|
||||||
|
e.preventDefault();
|
||||||
|
e = e.target.firstElementChild;
|
||||||
|
if (e.value) {
|
||||||
|
pageIcon(e.value);
|
||||||
|
setCookie('HBIcon', e.value);
|
||||||
|
e.value = '';
|
||||||
|
} else if (confirm('Reset the icon to default?')) {
|
||||||
|
// Allow users to reset the favicon to default if nothing is entered.
|
||||||
|
focusElement.focus();
|
||||||
|
removeCookie('HBIcon');
|
||||||
|
pageIcon('assets/img/icon.png');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
/*
|
||||||
|
|
||||||
This is unused in the current settings menu.
|
This is unused in the current settings menu.
|
||||||
|
|
||||||
|
@ -163,67 +181,70 @@ if (document.getElementById("csel")) {
|
||||||
});
|
});
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// Provides users with a handy set of title and icon autofill options.
|
// Provides users with a handy set of title and icon autofill options.
|
||||||
attachEventListener("icon-list", "change", e => {
|
attachEventListener('icon-list', 'change', (e) => {
|
||||||
let titleform = document.getElementById("titleform"),
|
let titleform = document.getElementById('titleform'),
|
||||||
iconform = document.getElementById("iconform");
|
iconform = document.getElementById('iconform');
|
||||||
[titleform.firstElementChild.value,
|
[titleform.firstElementChild.value, iconform.firstElementChild.value] = (
|
||||||
iconform.firstElementChild.value] =
|
presetIcons[e.target.value] || ' \n '
|
||||||
(presetIcons[e.target.value] || " \n ").split(" \n ");
|
).split(' \n ');
|
||||||
});
|
});
|
||||||
|
|
||||||
// Allow users to change the UV transport mode, for proxying, with the UI.
|
// Allow users to change the UV transport mode, for proxying, with the UI.
|
||||||
const uvTransportList = document.getElementById("uv-transport-list");
|
const uvTransportList = document.getElementById('uv-transport-list');
|
||||||
uvTransportList.querySelectorAll("input").forEach(element => {
|
uvTransportList.querySelectorAll('input').forEach((element) => {
|
||||||
element.addEventListener("change", e => {
|
element.addEventListener('change', (e) => {
|
||||||
!uvTransportList.querySelector("input:checked") ||
|
!uvTransportList.querySelector('input:checked') ||
|
||||||
e.target.value === defaultMode
|
e.target.value === defaultMode
|
||||||
? removeCookie("HBTransport")
|
? removeCookie('HBTransport')
|
||||||
: setCookie("HBTransport", e.target.value);
|
: setCookie('HBTransport', e.target.value);
|
||||||
|
|
||||||
// Only the libcurl transport mode supports Tor at the moment.
|
// Only the libcurl transport mode supports Tor at the moment.
|
||||||
let torCheck = document.getElementById("useonion");
|
let torCheck = document.getElementById('useonion');
|
||||||
if(e.target.value !== "libcurl" && torCheck.checked)
|
if (e.target.value !== 'libcurl' && torCheck.checked) torCheck.click();
|
||||||
torCheck.click();
|
});
|
||||||
})
|
});
|
||||||
});
|
|
||||||
|
|
||||||
// Allow users to toggle ads with the UI.
|
// Allow users to toggle ads with the UI.
|
||||||
attachEventListener("hideads", "change", e => {
|
attachEventListener('hideads', 'change', (e) => {
|
||||||
if (e.target.checked) {
|
if (e.target.checked) {
|
||||||
pageHideAds();
|
pageHideAds();
|
||||||
setCookie("HBHideAds", "true");
|
setCookie('HBHideAds', 'true');
|
||||||
} else {
|
} else {
|
||||||
pageShowAds();
|
pageShowAds();
|
||||||
setCookie("HBHideAds", "false");
|
setCookie('HBHideAds', 'false');
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// Allow users to toggle onion routing in Ultraviolet with the UI. Only
|
// Allow users to toggle onion routing in Ultraviolet with the UI. Only
|
||||||
// the libcurl transport mode supports Tor at the moment, so ensure that
|
// the libcurl transport mode supports Tor at the moment, so ensure that
|
||||||
// users are aware that they cannot use Tor with other modes.
|
// users are aware that they cannot use Tor with other modes.
|
||||||
attachEventListener("useonion", "change", e => {
|
attachEventListener('useonion', 'change', (e) => {
|
||||||
let unselectedModes =
|
let unselectedModes = document.querySelectorAll(
|
||||||
document.querySelectorAll("#uv-transport-list input:not([value=libcurl])");
|
'#uv-transport-list input:not([value=libcurl])'
|
||||||
if (e.target.checked) {
|
);
|
||||||
let selectedMode =
|
if (e.target.checked) {
|
||||||
document.querySelector("#uv-transport-list input[value=libcurl]");
|
let selectedMode = document.querySelector(
|
||||||
unselectedModes.forEach(e => {e.setAttribute("disabled", "true")});
|
'#uv-transport-list input[value=libcurl]'
|
||||||
selectedMode.click();
|
);
|
||||||
setCookie("HBUseOnion", "true");
|
unselectedModes.forEach((e) => {
|
||||||
} else {
|
e.setAttribute('disabled', 'true');
|
||||||
unselectedModes.forEach(e => {e.removeAttribute("disabled")});
|
});
|
||||||
|
selectedMode.click();
|
||||||
// Tor will likely never be enabled by default, so removing the cookie
|
setCookie('HBUseOnion', 'true');
|
||||||
// here may be better than setting it to false.
|
} else {
|
||||||
removeCookie("HBUseOnion");
|
unselectedModes.forEach((e) => {
|
||||||
}
|
e.removeAttribute('disabled');
|
||||||
});
|
});
|
||||||
}
|
|
||||||
|
|
||||||
|
// Tor will likely never be enabled by default, so removing the cookie
|
||||||
|
// here may be better than setting it to false.
|
||||||
|
removeCookie('HBUseOnion');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
})();
|
})();
|
||||||
|
|
||||||
|
|
||||||
/* -----------------------------------------------
|
/* -----------------------------------------------
|
||||||
/* Original code written by OlyB
|
/* Original code written by OlyB
|
||||||
/* -----------------------------------------------
|
/* -----------------------------------------------
|
||||||
|
@ -359,4 +380,4 @@ decodeURIComponent(atob("JTNDcCUyMGNsYXNzJTNEJTIyY3NlbHRpdGxlJTIyJTNFVGFiJTIwQ2x
|
||||||
}, false);
|
}, false);
|
||||||
}
|
}
|
||||||
})();
|
})();
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -2,10 +2,10 @@
|
||||||
await loadFull(tsParticles);
|
await loadFull(tsParticles);
|
||||||
|
|
||||||
await tsParticles.load({
|
await tsParticles.load({
|
||||||
id: "particles-js",
|
id: 'particles-js',
|
||||||
options: {
|
options: {
|
||||||
background: {
|
background: {
|
||||||
color: { value: "#1d232a" },
|
color: { value: '#1d232a' },
|
||||||
},
|
},
|
||||||
fullScreen: {
|
fullScreen: {
|
||||||
enable: true,
|
enable: true,
|
||||||
|
@ -22,14 +22,14 @@
|
||||||
},
|
},
|
||||||
particles: {
|
particles: {
|
||||||
color: {
|
color: {
|
||||||
value: "#ffffff",
|
value: '#ffffff',
|
||||||
},
|
},
|
||||||
move: {
|
move: {
|
||||||
enable: true,
|
enable: true,
|
||||||
speed: 0.8,
|
speed: 0.8,
|
||||||
direction: "none",
|
direction: 'none',
|
||||||
outModes: {
|
outModes: {
|
||||||
default: "out",
|
default: 'out',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
number: {
|
number: {
|
||||||
|
@ -48,7 +48,7 @@
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
shape: {
|
shape: {
|
||||||
type: "circle",
|
type: 'circle',
|
||||||
},
|
},
|
||||||
size: {
|
size: {
|
||||||
value: { min: 1, max: 5 },
|
value: { min: 1, max: 5 },
|
||||||
|
@ -61,7 +61,7 @@
|
||||||
links: {
|
links: {
|
||||||
enable: true,
|
enable: true,
|
||||||
distance: 150,
|
distance: 150,
|
||||||
color: "#ffffff",
|
color: '#ffffff',
|
||||||
opacity: 0.4,
|
opacity: 0.4,
|
||||||
width: 1,
|
width: 1,
|
||||||
},
|
},
|
||||||
|
|
|
@ -1,81 +1,83 @@
|
||||||
// Encase everything in a new scope so that variables are not accidentally
|
// Encase everything in a new scope so that variables are not accidentally
|
||||||
// attached to the global scope.
|
// attached to the global scope.
|
||||||
(() => {
|
(() => {
|
||||||
|
const stockSW = '/uv/sw.js',
|
||||||
|
blacklistSW = '/uv/sw-blacklist.js',
|
||||||
|
swAllowedHostnames = ['localhost', '127.0.0.1'],
|
||||||
|
connection = new BareMux.BareMuxConnection('/baremux/worker.js'),
|
||||||
|
wispUrl =
|
||||||
|
(location.protocol === 'https:' ? 'wss' : 'ws') +
|
||||||
|
'://' +
|
||||||
|
location.host +
|
||||||
|
'/wisp/',
|
||||||
|
// Proxy configuration
|
||||||
|
proxyUrl = 'socks5h://localhost:9050', // Replace with your proxy URL
|
||||||
|
transports = {
|
||||||
|
epoxy: '/epoxy/index.mjs',
|
||||||
|
libcurl: '/libcurl/index.mjs',
|
||||||
|
bare: '/baremux/index.mjs',
|
||||||
|
},
|
||||||
|
// The following two variables are copied and pasted here from csel.js.
|
||||||
|
readCookie = async (name) => {
|
||||||
|
// Get the first cookie that has the same name.
|
||||||
|
for (let cookie of document.cookie.split('; '))
|
||||||
|
if (!cookie.indexOf(name + '='))
|
||||||
|
// Return the cookie's stored content.
|
||||||
|
return decodeURIComponent(cookie.slice(name.length + 1));
|
||||||
|
},
|
||||||
|
// Sets the default transport mode based on the browser. Firefox is not
|
||||||
|
// supported by epoxy yet, which is why this is implemented.
|
||||||
|
defaultMode = /(?:Chrome|AppleWebKit)\//.test(navigator.userAgent)
|
||||||
|
? 'epoxy'
|
||||||
|
: 'libcurl';
|
||||||
|
|
||||||
const stockSW = "/uv/sw.js",
|
transports.default = transports[defaultMode];
|
||||||
blacklistSW = "/uv/sw-blacklist.js",
|
|
||||||
swAllowedHostnames = ["localhost", "127.0.0.1"],
|
|
||||||
connection = new BareMux.BareMuxConnection("/baremux/worker.js"),
|
|
||||||
wispUrl = (location.protocol === "https:" ? "wss" : "ws") + "://" + location.host + "/wisp/",
|
|
||||||
|
|
||||||
// Proxy configuration
|
// Prevent the transports object from accidentally being edited.
|
||||||
proxyUrl = "socks5h://localhost:9050", // Replace with your proxy URL
|
Object.freeze(transports);
|
||||||
transports = {
|
|
||||||
epoxy: "/epoxy/index.mjs",
|
|
||||||
libcurl: "/libcurl/index.mjs",
|
|
||||||
bare: "/baremux/index.mjs"
|
|
||||||
},
|
|
||||||
|
|
||||||
// The following two variables are copied and pasted here from csel.js.
|
const registerSW = async () => {
|
||||||
readCookie = async name => {
|
if (!navigator.serviceWorker) {
|
||||||
for (let cookie of document.cookie.split("; "))
|
if (
|
||||||
// Get the first cookie that has the same name.
|
location.protocol !== 'https:' &&
|
||||||
if (!cookie.indexOf(name + "="))
|
!swAllowedHostnames.includes(location.hostname)
|
||||||
// Return the cookie's stored content.
|
)
|
||||||
return decodeURIComponent(cookie.slice(name.length + 1));
|
throw new Error('Service workers cannot be registered without https.');
|
||||||
},
|
|
||||||
|
|
||||||
// Sets the default transport mode based on the browser. Firefox is not
|
throw new Error("Your browser doesn't support service workers.");
|
||||||
// supported by epoxy yet, which is why this is implemented.
|
}
|
||||||
defaultMode = /(?:Chrome|AppleWebKit)\//.test(navigator.userAgent)
|
|
||||||
? "epoxy"
|
|
||||||
: "libcurl";
|
|
||||||
|
|
||||||
transports.default = transports[defaultMode];
|
// If the user has changed the transport mode, use that over the default.
|
||||||
|
const transportMode =
|
||||||
|
transports[await readCookie('HBTransport')] || transports.default;
|
||||||
|
let transportOptions = { wisp: wispUrl };
|
||||||
|
|
||||||
// Prevent the transports object from accidentally being edited.
|
// Only use Tor with the proxy if the user has enabled it in settings.
|
||||||
Object.freeze(transports);
|
if ((await readCookie('HBUseOnion')) === 'true')
|
||||||
|
transportOptions.proxy = proxyUrl;
|
||||||
|
|
||||||
const registerSW = async () => {
|
await connection.setTransport(transportMode, [transportOptions]);
|
||||||
if (!navigator.serviceWorker) {
|
|
||||||
if (
|
|
||||||
location.protocol !== "https:" &&
|
|
||||||
!swAllowedHostnames.includes(location.hostname)
|
|
||||||
)
|
|
||||||
throw new Error("Service workers cannot be registered without https.");
|
|
||||||
|
|
||||||
throw new Error("Your browser doesn't support service workers.");
|
// Choose a service worker to register based on whether or not the user
|
||||||
}
|
// has ads enabled. If the user changes this setting, this script needs
|
||||||
|
// to be reloaded for this to update, such as by refreshing the page.
|
||||||
|
const registrations = await navigator.serviceWorker.getRegistrations(),
|
||||||
|
usedSW =
|
||||||
|
(await readCookie('HBHideAds')) !== 'false' ? blacklistSW : stockSW;
|
||||||
|
|
||||||
// If the user has changed the transport mode, use that over the default.
|
// Unregister a service worker if it isn't the one being used.
|
||||||
const transportMode = transports[await readCookie("HBTransport")] ||
|
for (const registration of registrations)
|
||||||
transports.default;
|
if (
|
||||||
let transportOptions = { wisp: wispUrl };
|
registration.active &&
|
||||||
|
new URL(registration.active.scriptURL).pathname !==
|
||||||
|
new URL(usedSW, location.origin).pathname
|
||||||
|
)
|
||||||
|
await registration.unregister();
|
||||||
|
|
||||||
// Only use Tor with the proxy if the user has enabled it in settings.
|
await navigator.serviceWorker.register(usedSW);
|
||||||
if (await readCookie("HBUseOnion") === "true")
|
};
|
||||||
transportOptions.proxy = proxyUrl;
|
|
||||||
|
|
||||||
await connection.setTransport(transportMode, [transportOptions]);
|
/*
|
||||||
|
|
||||||
// Choose a service worker to register based on whether or not the user
|
|
||||||
// has ads enabled. If the user changes this setting, this script needs
|
|
||||||
// to be reloaded for this to update, such as by refreshing the page.
|
|
||||||
const registrations = await navigator.serviceWorker.getRegistrations(),
|
|
||||||
usedSW = await readCookie("HBHideAds") !== "false"
|
|
||||||
? blacklistSW
|
|
||||||
: stockSW;
|
|
||||||
|
|
||||||
// Unregister a service worker if it isn't the one being used.
|
|
||||||
for (const registration of registrations)
|
|
||||||
if (registration.active &&
|
|
||||||
new URL(registration.active.scriptURL).pathname !== new URL(usedSW, location.origin).pathname)
|
|
||||||
await registration.unregister();
|
|
||||||
|
|
||||||
await navigator.serviceWorker.register(usedSW);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
|
|
||||||
Commented out upon discovering that a duplicate BareMux connection may be
|
Commented out upon discovering that a duplicate BareMux connection may be
|
||||||
unnecessary; previously thought to have prevented issues with refreshing.
|
unnecessary; previously thought to have prevented issues with refreshing.
|
||||||
|
@ -91,6 +93,5 @@ async function setupTransportOnLoad() {
|
||||||
setupTransportOnLoad();
|
setupTransportOnLoad();
|
||||||
*/
|
*/
|
||||||
|
|
||||||
registerSW();
|
registerSW();
|
||||||
|
})();
|
||||||
})();
|
|
||||||
|
|
|
@ -44,18 +44,18 @@
|
||||||
<script src="assets/js/particlesjs/particles.js"></script>
|
<script src="assets/js/particlesjs/particles.js"></script>
|
||||||
<script>
|
<script>
|
||||||
(function () {
|
(function () {
|
||||||
var v = document.getElementById("vsc");
|
var v = document.getElementById('vsc');
|
||||||
var t, a;
|
var t, a;
|
||||||
v.addEventListener(
|
v.addEventListener(
|
||||||
"mouseenter",
|
'mouseenter',
|
||||||
function () {
|
function () {
|
||||||
t = setTimeout(function () {
|
t = setTimeout(function () {
|
||||||
if (!a) {
|
if (!a) {
|
||||||
a = true;
|
a = true;
|
||||||
var e = new Audio("assets/misc/visualstudiocode.mp3");
|
var e = new Audio('assets/misc/visualstudiocode.mp3');
|
||||||
e.play();
|
e.play();
|
||||||
e.addEventListener(
|
e.addEventListener(
|
||||||
"ended",
|
'ended',
|
||||||
function () {
|
function () {
|
||||||
a = false;
|
a = false;
|
||||||
},
|
},
|
||||||
|
@ -67,7 +67,7 @@
|
||||||
false
|
false
|
||||||
);
|
);
|
||||||
v.addEventListener(
|
v.addEventListener(
|
||||||
"mouseleave",
|
'mouseleave',
|
||||||
function () {
|
function () {
|
||||||
clearTimeout(t);
|
clearTimeout(t);
|
||||||
},
|
},
|
||||||
|
|
1104
views/index.html
1104
views/index.html
File diff suppressed because it is too large
Load diff
|
@ -1,53 +1,53 @@
|
||||||
{
|
{
|
||||||
"short_name": "Holy Unblocker LTS",
|
"short_name": "Holy Unblocker LTS",
|
||||||
"name": "Holy Unblocker LTS | Free Web Proxy Service",
|
"name": "Holy Unblocker LTS | Free Web Proxy Service",
|
||||||
"icons": [
|
"icons": [
|
||||||
{
|
{
|
||||||
"src": "https://holyunblocker.org/assets/img/icon.png",
|
"src": "https://holyunblocker.org/assets/img/icon.png",
|
||||||
"type": "image/png",
|
"type": "image/png",
|
||||||
"sizes": "300x300"
|
"sizes": "300x300"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"start_url": ".",
|
"start_url": ".",
|
||||||
"display": "standalone",
|
"display": "standalone",
|
||||||
"theme_color": "#b4213b",
|
"theme_color": "#b4213b",
|
||||||
"background_color": "#1f003e",
|
"background_color": "#1f003e",
|
||||||
"description": "Holy Unblocker LTS is a free and secure web proxy service that helps you bypass web filters and access blocked websites. Enjoy anonymous browsing and internet freedom on devices like Chromebooks at school or work.",
|
"description": "Holy Unblocker LTS is a free and secure web proxy service that helps you bypass web filters and access blocked websites. Enjoy anonymous browsing and internet freedom on devices like Chromebooks at school or work.",
|
||||||
"short_description": "Free web proxy service for bypassing filters and accessing blocked sites.",
|
"short_description": "Free web proxy service for bypassing filters and accessing blocked sites.",
|
||||||
"keywords": [
|
"keywords": [
|
||||||
"proxy",
|
"proxy",
|
||||||
"web proxy",
|
"web proxy",
|
||||||
"unblock websites",
|
"unblock websites",
|
||||||
"free web proxy",
|
"free web proxy",
|
||||||
"proxy list",
|
"proxy list",
|
||||||
"online proxy",
|
"online proxy",
|
||||||
"proxy server",
|
"proxy server",
|
||||||
"proxy YouTube",
|
"proxy YouTube",
|
||||||
"bypass web filters",
|
"bypass web filters",
|
||||||
"Holy Unblocker",
|
"Holy Unblocker",
|
||||||
"unblock Chromebook",
|
"unblock Chromebook",
|
||||||
"Titanium Network",
|
"Titanium Network",
|
||||||
"fast proxy",
|
"fast proxy",
|
||||||
"secure proxy",
|
"secure proxy",
|
||||||
"anonymous browsing",
|
"anonymous browsing",
|
||||||
"internet freedom"
|
"internet freedom"
|
||||||
],
|
],
|
||||||
"related_applications": [
|
"related_applications": [
|
||||||
{
|
{
|
||||||
"platform": "web",
|
"platform": "web",
|
||||||
"url": "https://holyunblocker.org"
|
"url": "https://holyunblocker.org"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"platform": "github",
|
"platform": "github",
|
||||||
"url": "https://github.com/QuiteAFancyEmerald/Holy-Unblocker"
|
"url": "https://github.com/QuiteAFancyEmerald/Holy-Unblocker"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"platform": "twitter",
|
"platform": "twitter",
|
||||||
"url": "https://twitter.com/titaniumnetdev"
|
"url": "https://twitter.com/titaniumnetdev"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"platform": "youtube",
|
"platform": "youtube",
|
||||||
"url": "https://www.youtube.com/channel/UC6LaREFvs9L72SK1s2PcxNg"
|
"url": "https://www.youtube.com/channel/UC6LaREFvs9L72SK1s2PcxNg"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
|
@ -36,7 +36,7 @@
|
||||||
<!-- IMPORTANT-HUCOOKINGINSERT-DONOTDELETE -->
|
<!-- IMPORTANT-HUCOOKINGINSERT-DONOTDELETE -->
|
||||||
<iframe id="frame" allow="fullscreen" autofocus></iframe>
|
<iframe id="frame" allow="fullscreen" autofocus></iframe>
|
||||||
<script>
|
<script>
|
||||||
document.getElementById("frame").src = localStorage.getItem("huframesrc");
|
document.getElementById('frame').src = localStorage.getItem('huframesrc');
|
||||||
</script>
|
</script>
|
||||||
<script src="assets/js/csel.js"></script>
|
<script src="assets/js/csel.js"></script>
|
||||||
</body>
|
</body>
|
||||||
|
|
|
@ -1,54 +1,93 @@
|
||||||
<!-- https://markdowntohtml.com/ -->
|
<!-- https://markdowntohtml.com/ -->
|
||||||
<h1 id="holy-unblocker-img-align-left-src-https-raw-githubusercontent-com-titaniumnetwork-dev-holy-unblocker-master-views-assets-img-icon-png-img-">Holy Unblocker Documentation</h1>
|
<h1
|
||||||
<p>Holy Unblocker, an official flagship Titanium Network site, can bypass web filters regardless of whether it is an extension or network-based. Being a secure web proxy service, it supports numerous sites while being updated frequently and concentrating on detail with design, mechanics, and features.</p>
|
id="holy-unblocker-img-align-left-src-https-raw-githubusercontent-com-titaniumnetwork-dev-holy-unblocker-master-views-assets-img-icon-png-img-"
|
||||||
|
>
|
||||||
|
Holy Unblocker Documentation
|
||||||
|
</h1>
|
||||||
|
<p>
|
||||||
|
Holy Unblocker, an official flagship Titanium Network site, can bypass web
|
||||||
|
filters regardless of whether it is an extension or network-based. Being a
|
||||||
|
secure web proxy service, it supports numerous sites while being updated
|
||||||
|
frequently and concentrating on detail with design, mechanics, and features.
|
||||||
|
</p>
|
||||||
<p>Works with a large number of sites, including YouTube, Discord, and more!</p>
|
<p>Works with a large number of sites, including YouTube, Discord, and more!</p>
|
||||||
<p>Also has a good amount of locally hosted games featured on the site.</p>
|
<p>Also has a good amount of locally hosted games featured on the site.</p>
|
||||||
<p><strong>Read below for information if the official site is blocked or for obtaining more links.</strong></p>
|
<p>
|
||||||
|
<strong
|
||||||
|
>Read below for information if the official site is blocked or for obtaining
|
||||||
|
more links.</strong
|
||||||
|
>
|
||||||
|
</p>
|
||||||
<h4 id="supports">Supports</h4>
|
<h4 id="supports">Supports</h4>
|
||||||
<ul>
|
<ul>
|
||||||
<li>Youtube.com</li>
|
<li>Youtube.com</li>
|
||||||
<li>Discord.com</li>
|
<li>Discord.com</li>
|
||||||
<li>Google.com</li>
|
<li>Google.com</li>
|
||||||
<li>Reddit.com</li>
|
<li>Reddit.com</li>
|
||||||
<li>Bing.com</li>
|
<li>Bing.com</li>
|
||||||
<li>And more sites!</li>
|
<li>And more sites!</li>
|
||||||
</ul>
|
</ul>
|
||||||
<h4 id="features-">Features:</h4>
|
<h4 id="features-">Features:</h4>
|
||||||
<ul>
|
<ul>
|
||||||
<li>Tab customization using the Options menu for improved stealth </li>
|
<li>Tab customization using the Options menu for improved stealth</li>
|
||||||
<li>Considerable variety with the open selection of proxy types </li>
|
<li>Considerable variety with the open selection of proxy types</li>
|
||||||
<li>Game library with moderately decent titles</li>
|
<li>Game library with moderately decent titles</li>
|
||||||
<li>Has frequent support articles for issues relating to the various proxy instances</li>
|
<li>
|
||||||
|
Has frequent support articles for issues relating to the various proxy
|
||||||
|
instances
|
||||||
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
<p>Note: EmuLibrary is not featured in the public version.</p>
|
<p>Note: EmuLibrary is not featured in the public version.</p>
|
||||||
<p>Official Site: <a href="https://holyubofficial.net">https://holyubofficial.net</a></p>
|
<p>
|
||||||
<p><strong>Be sure to join Titanium Network's Discord for more official site links:</strong> <a href="https://discord.gg/unblock">https://discord.gg/unblock</a></p>
|
Official Site:
|
||||||
<p>Simply do <code>%proxy hu</code> in <code>#proxy-commands</code> for more Holy Unblocker links on the TN Discord server.</p>
|
<a href="https://holyubofficial.net">https://holyubofficial.net</a>
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<strong
|
||||||
|
>Be sure to join Titanium Network's Discord for more official site
|
||||||
|
links:</strong
|
||||||
|
>
|
||||||
|
<a href="https://discord.gg/unblock">https://discord.gg/unblock</a>
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
Simply do <code>%proxy hu</code> in <code>#proxy-commands</code> for more Holy
|
||||||
|
Unblocker links on the TN Discord server.
|
||||||
|
</p>
|
||||||
<h2 id="table-of-contents-">Table of contents:</h2>
|
<h2 id="table-of-contents-">Table of contents:</h2>
|
||||||
<ul>
|
<ul>
|
||||||
<li><a href="#how-to-setup">Setup</a>
|
<li>
|
||||||
|
<a href="#how-to-setup">Setup</a>
|
||||||
|
<ul>
|
||||||
|
<li>
|
||||||
|
<a href="#structure">Structure</a>
|
||||||
<ul>
|
<ul>
|
||||||
<li><a href="#structure">Structure</a>
|
<li><a href="#structure-information">Structure Information</a></li>
|
||||||
<ul>
|
<li><a href="#details-of-views">Static Files</a></li>
|
||||||
<li><a href="#structure-information">Structure Information</a></li>
|
<li><a href="#scripts-located-in-viewsassetsjs">Scripts</a></li>
|
||||||
<li><a href="#details-of-views">Static Files</a></li>
|
|
||||||
<li><a href="#scripts-located-in-viewsassetsjs">Scripts</a></li>
|
|
||||||
</ul>
|
|
||||||
</li>
|
|
||||||
<li><a href="#future-additions">Future Additions</a></li>
|
|
||||||
<li><a href="#vauge-explanation-for-beginners-with-external-proxies-and-hosting">Beginner's Explanation</a>
|
|
||||||
<ul>
|
|
||||||
<li><a href="#list-of-some-good-hosting-options">Hosting Providers</a></li>
|
|
||||||
<li><a href="#heroku-steps">Heroku Setup</a></li>
|
|
||||||
<li><a href="#freenomdomain-steps">Domain Setup</a></li>
|
|
||||||
<li><a href="#cloudflare-steps">Cloudflare Setup</a></li>
|
|
||||||
<li><a href="#workspace-configurations">Workspace Configurations</a></li>
|
|
||||||
</ul>
|
|
||||||
</li>
|
|
||||||
<li><a href="#detailed-faq">Detailed FAQ</a></li>
|
|
||||||
<li><a href="#more-information">More Information</a></li>
|
|
||||||
</ul>
|
</ul>
|
||||||
</li>
|
</li>
|
||||||
|
<li><a href="#future-additions">Future Additions</a></li>
|
||||||
|
<li>
|
||||||
|
<a
|
||||||
|
href="#vauge-explanation-for-beginners-with-external-proxies-and-hosting"
|
||||||
|
>Beginner's Explanation</a
|
||||||
|
>
|
||||||
|
<ul>
|
||||||
|
<li>
|
||||||
|
<a href="#list-of-some-good-hosting-options">Hosting Providers</a>
|
||||||
|
</li>
|
||||||
|
<li><a href="#heroku-steps">Heroku Setup</a></li>
|
||||||
|
<li><a href="#freenomdomain-steps">Domain Setup</a></li>
|
||||||
|
<li><a href="#cloudflare-steps">Cloudflare Setup</a></li>
|
||||||
|
<li>
|
||||||
|
<a href="#workspace-configurations">Workspace Configurations</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
<li><a href="#detailed-faq">Detailed FAQ</a></li>
|
||||||
|
<li><a href="#more-information">More Information</a></li>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
<h2 id="how-to-setup">How to Setup</h2>
|
<h2 id="how-to-setup">How to Setup</h2>
|
||||||
<p>Either use the button above to deploy to Heroku or do the below:</p>
|
<p>Either use the button above to deploy to Heroku or do the below:</p>
|
||||||
|
@ -60,167 +99,370 @@ npm install
|
||||||
|
|
||||||
npm <span class="hljs-literal">start</span>
|
npm <span class="hljs-literal">start</span>
|
||||||
</code></pre>
|
</code></pre>
|
||||||
<p>The default place for the proxy when its started is <code>http://localhost:8080</code> but you can change it if needed in config.json</p>
|
<p>
|
||||||
<p>This website is hosted locally with Corrosion built-in. More more information go to the Corrosion repository below.</p>
|
The default place for the proxy when its started is
|
||||||
|
<code>http://localhost:8080</code> but you can change it if needed in
|
||||||
|
config.json
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
This website is hosted locally with Corrosion built-in. More more information
|
||||||
|
go to the Corrosion repository below.
|
||||||
|
</p>
|
||||||
<h2 id="structure">Structure</h2>
|
<h2 id="structure">Structure</h2>
|
||||||
<ul>
|
<ul>
|
||||||
<li><code>index.html</code>: The homepage of the site.</li>
|
<li><code>index.html</code>: The homepage of the site.</li>
|
||||||
<li><code>404.html</code>: The 404 page.</li>
|
<li><code>404.html</code>: The 404 page.</li>
|
||||||
<li><code>error.html</code>: Other errors that are not 404.</li>
|
<li><code>error.html</code>: Other errors that are not 404.</li>
|
||||||
<li><code>info.html</code>: Documentation (This page!)</li>
|
<li><code>info.html</code>: Documentation (This page!)</li>
|
||||||
<li><code>faq.html</code>: Frequently asked questions page.</li>
|
<li><code>faq.html</code>: Frequently asked questions page.</li>
|
||||||
<li><code>hidden.html</code>: Fake "Site not Found" page (unused)</li>
|
<li>
|
||||||
<li><code>frame.html</code>: Handles any pages under stealth.</li>
|
<code>hidden.html</code>: Fake "Site not Found" page (unused)
|
||||||
<li><code>surf.html</code>: Web Proxies page, page offers to be redirected to any proxies you would like to add. In this case, Corrosion, Womginx, and Palladium.</li>
|
</li>
|
||||||
<li><code>credits.html</code>: List of all contributors to the site.</li>
|
<li><code>frame.html</code>: Handles any pages under stealth.</li>
|
||||||
<li><code>bookmarklets.html</code>: Bookmarklets page, to be worked on more in the future.</li>
|
<li>
|
||||||
<li><code>icons.html</code>: Information regarding Settings Menu page. Added this in for standard users.</li>
|
<code>surf.html</code>: Web Proxies page, page offers to be redirected to
|
||||||
<li><code>terms.html</code>: Terms of Services, AUP and Privacy Policy page.</li>
|
any proxies you would like to add. In this case, Corrosion, Womginx, and
|
||||||
<li><code>gtools.html</code>: Games page, help from @BinBashBanana and @kinglalu.</li>
|
Palladium.
|
||||||
<li><code>games5.html</code>: HTML5 game navigation page.</li>
|
</li>
|
||||||
<li><code>emulators.html</code>: Emulator navigation page, using <a href="https://github.com/BinBashBanana/webretro">webretro</a>.</li>
|
<li><code>credits.html</code>: List of all contributors to the site.</li>
|
||||||
<li><code>emulibrary.html</code>: Games page for emulated games (not included in public release)</li>
|
<li>
|
||||||
<li><code>flash.html</code>: Games page for flash games, credits given to @BinBashBanana and Titanium Network for its assets.</li>
|
<code>bookmarklets.html</code>: Bookmarklets page, to be worked on more in
|
||||||
<li><code>corrosion.html</code>: Corrosion Proxy page which features Corrosion hosted locally but can be configured to redirect to an external instance.</li>
|
the future.
|
||||||
<li><code>womginx.html</code>: Womginx Proxy page. Script links to a subdomain for Womginx, a highly fast proxy with reCaptcha and discord support.</li>
|
</li>
|
||||||
<li><code>palladium.html</code>: Palladium Proxy page.</li>
|
<li>
|
||||||
<li><code>youtube.html</code>: An proxied version of Youtube running off of the locally hosted Corrosion.</li>
|
<code>icons.html</code>: Information regarding Settings Menu page. Added
|
||||||
<li><code>discord.html</code>: Hub for the Discord proxy.</li>
|
this in for standard users.
|
||||||
<li><code>reddit.html</code>: Hub for the Reddit proxy.</li>
|
</li>
|
||||||
|
<li>
|
||||||
|
<code>terms.html</code>: Terms of Services, AUP and Privacy Policy page.
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<code>gtools.html</code>: Games page, help from @BinBashBanana and
|
||||||
|
@kinglalu.
|
||||||
|
</li>
|
||||||
|
<li><code>games5.html</code>: HTML5 game navigation page.</li>
|
||||||
|
<li>
|
||||||
|
<code>emulators.html</code>: Emulator navigation page, using
|
||||||
|
<a href="https://github.com/BinBashBanana/webretro">webretro</a>.
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<code>emulibrary.html</code>: Games page for emulated games (not included in
|
||||||
|
public release)
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<code>flash.html</code>: Games page for flash games, credits given to
|
||||||
|
@BinBashBanana and Titanium Network for its assets.
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<code>corrosion.html</code>: Corrosion Proxy page which features Corrosion
|
||||||
|
hosted locally but can be configured to redirect to an external instance.
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<code>womginx.html</code>: Womginx Proxy page. Script links to a subdomain
|
||||||
|
for Womginx, a highly fast proxy with reCaptcha and discord support.
|
||||||
|
</li>
|
||||||
|
<li><code>palladium.html</code>: Palladium Proxy page.</li>
|
||||||
|
<li>
|
||||||
|
<code>youtube.html</code>: An proxied version of Youtube running off of the
|
||||||
|
locally hosted Corrosion.
|
||||||
|
</li>
|
||||||
|
<li><code>discord.html</code>: Hub for the Discord proxy.</li>
|
||||||
|
<li><code>reddit.html</code>: Hub for the Reddit proxy.</li>
|
||||||
</ul>
|
</ul>
|
||||||
<h3 id="structure-information">Structure Information</h3>
|
<h3 id="structure-information">Structure Information</h3>
|
||||||
<ul>
|
<ul>
|
||||||
<li><code>/views/</code>: The physical site base of Holy Unblocker goes here where static assets are served.</li>
|
<li>
|
||||||
<li><code>/src/</code>: For future implementation of obfuscation and keyword removing features.</li>
|
<code>/views/</code>: The physical site base of Holy Unblocker goes here
|
||||||
|
where static assets are served.
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<code>/src/</code>: For future implementation of obfuscation and keyword
|
||||||
|
removing features.
|
||||||
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
<h4 id="details-of-views-">Details of <code>/views/</code></h4>
|
<h4 id="details-of-views-">Details of <code>/views/</code></h4>
|
||||||
<ul>
|
<ul>
|
||||||
<li><code>/archive/</code> is used for game pages and vibeOS.</li>
|
<li><code>/archive/</code> is used for game pages and vibeOS.</li>
|
||||||
<li><code>/pages/</code> is used for the HTML for the site.</li>
|
<li><code>/pages/</code> is used for the HTML for the site.</li>
|
||||||
<li><code>/assets/</code> is used for various assets for CSS, JS, and images.</li>
|
<li>
|
||||||
|
<code>/assets/</code> is used for various assets for CSS, JS, and images.
|
||||||
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
<h4 id="scripts-located-in-views-assets-js-">Scripts located in <code>/views/assets/js/</code></h4>
|
<h4 id="scripts-located-in-views-assets-js-">
|
||||||
|
Scripts located in <code>/views/assets/js/</code>
|
||||||
|
</h4>
|
||||||
<ul>
|
<ul>
|
||||||
<li><code>common.js</code> is used on all of the pages for common useful functions.</li>
|
<li>
|
||||||
<li><code>csel.js</code> manages the settings menu on the header.</li>
|
<code>common.js</code> is used on all of the pages for common useful
|
||||||
|
functions.
|
||||||
|
</li>
|
||||||
|
<li><code>csel.js</code> manages the settings menu on the header.</li>
|
||||||
</ul>
|
</ul>
|
||||||
<h2 id="future-additions">Future Additions</h2>
|
<h2 id="future-additions">Future Additions</h2>
|
||||||
<ul>
|
<ul>
|
||||||
<li>Expansive game library</li>
|
<li>Expansive game library</li>
|
||||||
<li>Various parity changes.</li>
|
<li>Various parity changes.</li>
|
||||||
</ul>
|
</ul>
|
||||||
<h2 id="vauge-explanation-for-beginners-with-external-proxies-and-hosting">Vauge Explanation for Beginners With External Proxies and Hosting</h2>
|
<h2 id="vauge-explanation-for-beginners-with-external-proxies-and-hosting">
|
||||||
<p>You will first want to host your proxies locally or externally. </p>
|
Vauge Explanation for Beginners With External Proxies and Hosting
|
||||||
<h4 id="list-of-some-good-hosting-options-">List of some good hosting options:</h4>
|
</h2>
|
||||||
|
<p>You will first want to host your proxies locally or externally.</p>
|
||||||
|
<h4 id="list-of-some-good-hosting-options-">
|
||||||
|
List of some good hosting options:
|
||||||
|
</h4>
|
||||||
<ul>
|
<ul>
|
||||||
<li><a href="https://dedipath.com">Dedipath</a> (Paid and Dedicated)</li>
|
<li><a href="https://dedipath.com">Dedipath</a> (Paid and Dedicated)</li>
|
||||||
<li><a href="https://heroku.com">Heroku</a> (Free)</li>
|
<li><a href="https://heroku.com">Heroku</a> (Free)</li>
|
||||||
<li><a href="https://nodeclusters.com">NodeClusters</a> (Paid)</li>
|
<li><a href="https://nodeclusters.com">NodeClusters</a> (Paid)</li>
|
||||||
<li><a href="https://glitch.com">Glitch</a> (Free)</li>
|
<li><a href="https://glitch.com">Glitch</a> (Free)</li>
|
||||||
<li><a href="https://repl.it">Repl.it</a> (Free)</li>
|
<li><a href="https://repl.it">Repl.it</a> (Free)</li>
|
||||||
<li><a href="https://azure.microsoft.com">Azure</a> (Free and Paid)</li>
|
<li><a href="https://azure.microsoft.com">Azure</a> (Free and Paid)</li>
|
||||||
</ul>
|
</ul>
|
||||||
<p>Out of the list of hosting providers Heroku and NodeClusters rank first as a preference. You may also self-host.</p>
|
<p>
|
||||||
<p>After you have selected a decent VPS, use Cloudflare for the DNS records for both the site and the subdomains for the proxies.</p>
|
Out of the list of hosting providers Heroku and NodeClusters rank first as a
|
||||||
<p>This is an example of DNS records involving Heroku. Self-hosting will require <code>A records</code> preferably.</p>
|
preference. You may also self-host.
|
||||||
<p><img src="/assets/img/dnssetup.png" width="500"></img></p>
|
</p>
|
||||||
|
<p>
|
||||||
|
After you have selected a decent VPS, use Cloudflare for the DNS records for
|
||||||
|
both the site and the subdomains for the proxies.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
This is an example of DNS records involving Heroku. Self-hosting will require
|
||||||
|
<code>A records</code> preferably.
|
||||||
|
</p>
|
||||||
|
<p><img src="/assets/img/dnssetup.png" width="500" /></p>
|
||||||
<ul>
|
<ul>
|
||||||
<li><code>@</code> and <code>www.deepsoil.ml</code> are being used for the local Corrosion proxy.</li>
|
<li>
|
||||||
<li><code>p.deepsoil.ml</code> is being used for Palladium.</li>
|
<code>@</code> and <code>www.deepsoil.ml</code> are being used for the local
|
||||||
<li><code>a.deepsoil.ml</code> is being used for womginx.</li>
|
Corrosion proxy.
|
||||||
<li><code>cdn.deepsoil.ml</code> is being used for a private Corrosion host on the official sites.</li>
|
</li>
|
||||||
|
<li><code>p.deepsoil.ml</code> is being used for Palladium.</li>
|
||||||
|
<li><code>a.deepsoil.ml</code> is being used for womginx.</li>
|
||||||
|
<li>
|
||||||
|
<code>cdn.deepsoil.ml</code> is being used for a private Corrosion host on
|
||||||
|
the official sites.
|
||||||
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
<p>As stated previously, Holy Unblocker is hosted locally with Corrosion.</p>
|
<p>As stated previously, Holy Unblocker is hosted locally with Corrosion.</p>
|
||||||
<h4 id="heroku-steps">Heroku Steps</h4>
|
<h4 id="heroku-steps">Heroku Steps</h4>
|
||||||
<p>So you chose to use Heroku to host. I personally favor it as a free choice.</p>
|
<p>
|
||||||
|
So you chose to use Heroku to host. I personally favor it as a free choice.
|
||||||
|
</p>
|
||||||
<ul>
|
<ul>
|
||||||
<li>First obtain a card; (Prepaid, Debit, and Credit Cards work). You need this to add custom domains to your Heroku instance.</li>
|
<li>
|
||||||
|
First obtain a card; (Prepaid, Debit, and Credit Cards work). You need this
|
||||||
|
to add custom domains to your Heroku instance.
|
||||||
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
<p>Make sure you connect your Heroku app to your GitHub and enable automatic deploys. Will make things easier. :) </p>
|
<p>
|
||||||
|
Make sure you connect your Heroku app to your GitHub and enable automatic
|
||||||
|
deploys. Will make things easier. :)
|
||||||
|
</p>
|
||||||
<h4 id="freenom-domain-steps">Freenom/Domain Steps</h4>
|
<h4 id="freenom-domain-steps">Freenom/Domain Steps</h4>
|
||||||
<p>For beginners, Freenom is a good provider for obtaining domains for free. However the catch is that you can only use properly "Freenom" domains for free being .cf, .ml, .gq, ga and .tk. However these can be blocked rather easily.</p>
|
<p>
|
||||||
|
For beginners, Freenom is a good provider for obtaining domains for free.
|
||||||
|
However the catch is that you can only use properly "Freenom"
|
||||||
|
domains for free being .cf, .ml, .gq, ga and .tk. However these can be blocked
|
||||||
|
rather easily.
|
||||||
|
</p>
|
||||||
<ul>
|
<ul>
|
||||||
<li>Get some Freenom domains then add them to your Heroku instance (Personal > [App Name] > Settings > Domains) Add a domain for both <code>www.youdomainhere.cf</code> and <code>yourdomainhere.cf</code> with .cf being interchangeable with other
|
<li>
|
||||||
Freenom domain names.</li>
|
Get some Freenom domains then add them to your Heroku instance (Personal
|
||||||
<li>If you prefer to obtain premium domains (TLDs) then use <a href="https://porkbun.com">Porkbun</a>, which offers domains for amazing prices. Literally a <code>.net</code> domain normally costs around $10. On Porkbun for the first year it costs $3 so
|
> [App Name] > Settings > Domains) Add a domain for both
|
||||||
its definitely a deal.</li>
|
<code>www.youdomainhere.cf</code> and <code>yourdomainhere.cf</code> with
|
||||||
|
.cf being interchangeable with other Freenom domain names.
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
If you prefer to obtain premium domains (TLDs) then use
|
||||||
|
<a href="https://porkbun.com">Porkbun</a>, which offers domains for amazing
|
||||||
|
prices. Literally a <code>.net</code> domain normally costs around $10. On
|
||||||
|
Porkbun for the first year it costs $3 so its definitely a deal.
|
||||||
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
<h4 id="cloudflare-steps">Cloudflare Steps</h4>
|
<h4 id="cloudflare-steps">Cloudflare Steps</h4>
|
||||||
<ul>
|
<ul>
|
||||||
<li>Use Cloudflare (make an account), add your site (Freenom Domain or other) and then add your various DNS targets to Cloudflare. Make sure you add Cloudflare's Nameservers which will be given later when you are adding your site. </li>
|
<li>
|
||||||
|
Use Cloudflare (make an account), add your site (Freenom Domain or other)
|
||||||
|
and then add your various DNS targets to Cloudflare. Make sure you add
|
||||||
|
Cloudflare's Nameservers which will be given later when you are adding
|
||||||
|
your site.
|
||||||
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
<p>Make sure they are CNAME although A records also work and try to follow this structure:</p>
|
<p>
|
||||||
|
Make sure they are CNAME although A records also work and try to follow this
|
||||||
|
structure:
|
||||||
|
</p>
|
||||||
<p><strong>Type | Name | Target</strong></p>
|
<p><strong>Type | Name | Target</strong></p>
|
||||||
<p><code>CNAME | @ | your-main-heroku-target-here.herokudns.com</code><br><code>CNAME | www | your-main-heroku-target-here.herokudns.com</code></p>
|
<p>
|
||||||
<p><strong>Below are if you want external proxies also with your site:</strong></p>
|
<code>CNAME | @ | your-main-heroku-target-here.herokudns.com</code><br /><code
|
||||||
<p><code>CNAME | p | your-palladium-instance-here.herokudns.com</code><br><code>CNAME | a | your-womginx-instance-here.herokudns.com</code><br><code>CNAME | pd | your-pydodgeb-instance-here.herokudns.com</code></p>
|
>CNAME | www | your-main-heroku-target-here.herokudns.com</code
|
||||||
<p>Make sure HTTPS is forced and have SSL set to Flexible for Heroku. Otherwise you can have SSL set to Full.</p>
|
>
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<strong>Below are if you want external proxies also with your site:</strong>
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<code>CNAME | p | your-palladium-instance-here.herokudns.com</code><br /><code
|
||||||
|
>CNAME | a | your-womginx-instance-here.herokudns.com</code
|
||||||
|
><br /><code>CNAME | pd | your-pydodgeb-instance-here.herokudns.com</code>
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
Make sure HTTPS is forced and have SSL set to Flexible for Heroku. Otherwise
|
||||||
|
you can have SSL set to Full.
|
||||||
|
</p>
|
||||||
<h4 id="workspace-configurations">Workspace Configurations</h4>
|
<h4 id="workspace-configurations">Workspace Configurations</h4>
|
||||||
<p>Preferably if you have your own device use Visual Studio Code. Pretty much the best option you can get but obviously this is an opinion. Also make sure you have <a href="https://nodejs.org/">Node.JS</a> installed on your machine.</p>
|
<p>
|
||||||
<p>Not going to go too in depth with this part but first fork this repository. The clone it locally through a Terminal of some sort depending on what OS you are on. Make sure you navigate to the folder you want to set this up in.</p>
|
Preferably if you have your own device use Visual Studio Code. Pretty much the
|
||||||
|
best option you can get but obviously this is an opinion. Also make sure you
|
||||||
|
have <a href="https://nodejs.org/">Node.JS</a> installed on your machine.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
Not going to go too in depth with this part but first fork this repository.
|
||||||
|
The clone it locally through a Terminal of some sort depending on what OS you
|
||||||
|
are on. Make sure you navigate to the folder you want to set this up in.
|
||||||
|
</p>
|
||||||
<pre><code>git <span class="hljs-keyword">clone</span> <span class="hljs-title">https</span>://github.com/titaniumnetwork-dev/Holy-Unblocker.git
|
<pre><code>git <span class="hljs-keyword">clone</span> <span class="hljs-title">https</span>://github.com/titaniumnetwork-dev/Holy-Unblocker.git
|
||||||
|
|
||||||
cd Holy-Unblocker
|
cd Holy-Unblocker
|
||||||
|
|
||||||
npm install
|
npm install
|
||||||
</code></pre>
|
</code></pre>
|
||||||
<p>Now simply add the folder you cloned this repo in in <span id="vsc" style="cursor: help;">VSC</span>. Then run <code>npm install</code>. I recommend that if you are releasing this publically on GitHub that you add a <code>.gitignore</code> in your root directory with the following exclusions:</p>
|
<p>
|
||||||
|
Now simply add the folder you cloned this repo in in
|
||||||
|
<span id="vsc" style="cursor: help">VSC</span>. Then run
|
||||||
|
<code>npm install</code>. I recommend that if you are releasing this
|
||||||
|
publically on GitHub that you add a <code>.gitignore</code> in your root
|
||||||
|
directory with the following exclusions:
|
||||||
|
</p>
|
||||||
<pre><code>node_modules
|
<pre><code>node_modules
|
||||||
</code></pre>
|
</code></pre>
|
||||||
<p>Now you have your following workspace environment setup. To deploy the following workspace you just created you will need to look up depending on your hosting provider.</p>
|
<p>
|
||||||
<p>For an online IDE that you can use on your school computer and/or chromebook use GitPod. Basically the equivalent of Visual Studio Code but with in-browser support.</p>
|
Now you have your following workspace environment setup. To deploy the
|
||||||
|
following workspace you just created you will need to look up depending on
|
||||||
|
your hosting provider.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
For an online IDE that you can use on your school computer and/or chromebook
|
||||||
|
use GitPod. Basically the equivalent of Visual Studio Code but with in-browser
|
||||||
|
support.
|
||||||
|
</p>
|
||||||
<ul>
|
<ul>
|
||||||
<li>Make an account: <code>https://gitpod.io/</code></li>
|
<li>Make an account: <code>https://gitpod.io/</code></li>
|
||||||
<li>Fork this repo and enter in this URL to setup your workspace: <code>https://gitpod.io#https://github.com/YourNameHere/Holy-Unblocker/</code></li>
|
<li>
|
||||||
|
Fork this repo and enter in this URL to setup your workspace:
|
||||||
|
<code
|
||||||
|
>https://gitpod.io#https://github.com/YourNameHere/Holy-Unblocker/</code
|
||||||
|
>
|
||||||
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
<p>Use the same steps above by running <code>npm install</code> in your repository and adding a <code>.gitignore</code> in your root directory specifying to exclude <code>node_modules</code>.</p>
|
<p>
|
||||||
|
Use the same steps above by running <code>npm install</code> in your
|
||||||
|
repository and adding a <code>.gitignore</code> in your root directory
|
||||||
|
specifying to exclude <code>node_modules</code>.
|
||||||
|
</p>
|
||||||
<h2 id="detailed-faq">Detailed FAQ</h2>
|
<h2 id="detailed-faq">Detailed FAQ</h2>
|
||||||
<p>A detailed FAQ with common issues and solutions can be found <a href="https://holyunblocker.org/questions">here</a> or on any official HU site on the FAQ page.</p>
|
<p>
|
||||||
|
A detailed FAQ with common issues and solutions can be found
|
||||||
|
<a href="https://holyunblocker.org/questions">here</a> or on any official HU
|
||||||
|
site on the FAQ page.
|
||||||
|
</p>
|
||||||
<details>
|
<details>
|
||||||
<summary>Quick FAQ</summary>
|
<summary>Quick FAQ</summary>
|
||||||
|
|
||||||
<p><strong>Why is the site I am on not working correctly or having CAPTCHA errors?</strong></p> Captcha support is currently not available on all of the current proxies sadly. Therefore some sites may not work with any of the sites. Read below for issues
|
<p>
|
||||||
with links on sites.
|
<strong
|
||||||
|
>Why is the site I am on not working correctly or having CAPTCHA
|
||||||
|
errors?</strong
|
||||||
|
>
|
||||||
|
</p>
|
||||||
|
Captcha support is currently not available on all of the current proxies
|
||||||
|
sadly. Therefore some sites may not work with any of the sites. Read below for
|
||||||
|
issues with links on sites.
|
||||||
|
|
||||||
<p><strong>Why are some page links not working or leading to 404 pages?</strong></p> This is an issue with the latest release of Alloy proxy but it may also occur with other proxies. In this case manually entering the URL of the page you would like to view
|
<p>
|
||||||
can solve this or try navigating using the home button. (Reddit, Twitter) The next release of Alloy may fix this also.
|
<strong
|
||||||
|
>Why are some page links not working or leading to 404 pages?</strong
|
||||||
|
>
|
||||||
|
</p>
|
||||||
|
This is an issue with the latest release of Alloy proxy but it may also occur
|
||||||
|
with other proxies. In this case manually entering the URL of the page you
|
||||||
|
would like to view can solve this or try navigating using the home button.
|
||||||
|
(Reddit, Twitter) The next release of Alloy may fix this also.
|
||||||
|
|
||||||
<p><strong>When using YouTube on any of the proxy sites, why does the page not load fully or the video is just white?</strong></p> There are two methods for fixing this: - Reloading the page normally when the error above happens should load the video. -
|
<p>
|
||||||
Or right-clicking the page and doing Reload Frame if you are using some form of Stealth Mode.
|
<strong
|
||||||
|
>When using YouTube on any of the proxy sites, why does the page not load
|
||||||
|
fully or the video is just white?</strong
|
||||||
|
>
|
||||||
|
</p>
|
||||||
|
There are two methods for fixing this: - Reloading the page normally when the
|
||||||
|
error above happens should load the video. - Or right-clicking the page and
|
||||||
|
doing Reload Frame if you are using some form of Stealth Mode.
|
||||||
|
|
||||||
<p><strong>When using Discord under Alloy or SysYa, why does the page stay gray/white or the QR code not load?</strong></p> Once again do the same steps above: - Reloading the page normally when the error above happens should load the video - Or right-clicking
|
<p>
|
||||||
the page and doing Reload Frame if you are using some form of Stealth Mode. Make sure you are also doing the steps correctly. Simply view link above for extended Discord proxy information/steps.
|
<strong
|
||||||
|
>When using Discord under Alloy or SysYa, why does the page stay
|
||||||
<p><strong>I am getting 502 errors. What do I do?</strong></p> When this happens you may either switch sites to fix the error or wait a bit. Sometimes clearing your cache can help. If you still have any questions feel free to ask them in the discord linked
|
gray/white or the QR code not load?</strong
|
||||||
here.
|
>
|
||||||
|
</p>
|
||||||
|
Once again do the same steps above: - Reloading the page normally when the
|
||||||
|
error above happens should load the video - Or right-clicking the page and
|
||||||
|
doing Reload Frame if you are using some form of Stealth Mode. Make sure you
|
||||||
|
are also doing the steps correctly. Simply view link above for extended
|
||||||
|
Discord proxy information/steps.
|
||||||
|
|
||||||
|
<p><strong>I am getting 502 errors. What do I do?</strong></p>
|
||||||
|
When this happens you may either switch sites to fix the error or wait a bit.
|
||||||
|
Sometimes clearing your cache can help. If you still have any questions feel
|
||||||
|
free to ask them in the discord linked here.
|
||||||
</details>
|
</details>
|
||||||
|
|
||||||
<h2 id="more-information">More Information</h2>
|
<h2 id="more-information">More Information</h2>
|
||||||
<p>This project is maintained by Quite A Fancy Emerald with massive help from BinBashBanana (OlyB) and is an official flagship Titanium Network proxy site.</p>
|
<p>
|
||||||
|
This project is maintained by Quite A Fancy Emerald with massive help from
|
||||||
|
BinBashBanana (OlyB) and is an official flagship Titanium Network proxy site.
|
||||||
|
</p>
|
||||||
<ul>
|
<ul>
|
||||||
<li><a href="https://github.com/titaniumnetwork-dev/Holy-Unblocker">GitHub link</a></li>
|
<li>
|
||||||
<li><a href="https://github.com/titaniumnetwork-dev/">https://github.com/titaniumnetwork-dev/</a></li>
|
<a href="https://github.com/titaniumnetwork-dev/Holy-Unblocker"
|
||||||
<li><a href="https://titaniumnetwork.org/">https://titaniumnetwork.org/</a></li>
|
>GitHub link</a
|
||||||
|
>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a href="https://github.com/titaniumnetwork-dev/"
|
||||||
|
>https://github.com/titaniumnetwork-dev/</a
|
||||||
|
>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a href="https://titaniumnetwork.org/">https://titaniumnetwork.org/</a>
|
||||||
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
<p>View the official website for more detail and credits.</p>
|
<p>View the official website for more detail and credits.</p>
|
||||||
<h3 id="proxy-sources-">Proxy Sources:</h3>
|
<h3 id="proxy-sources-">Proxy Sources:</h3>
|
||||||
<p>This project currently uses Corrosion, Womginx, and Palladium, linked below.</p>
|
<p>
|
||||||
|
This project currently uses Corrosion, Womginx, and Palladium, linked below.
|
||||||
|
</p>
|
||||||
<ul>
|
<ul>
|
||||||
<li><a href="https://github.com/titaniumnetwork-dev/Corrosion">Corrosion</a></li>
|
<li>
|
||||||
<li><a href="https://github.com/binary-person/womginx">Womginx</a></li>
|
<a href="https://github.com/titaniumnetwork-dev/Corrosion">Corrosion</a>
|
||||||
<li><a href="https://github.com/LudicrousDevelopment/Palladium">Palladium</a></li>
|
</li>
|
||||||
<li><a href="https://github.com/BinBashBanana/PyDodge">PyDodge</a></li>
|
<li><a href="https://github.com/binary-person/womginx">Womginx</a></li>
|
||||||
|
<li>
|
||||||
|
<a href="https://github.com/LudicrousDevelopment/Palladium">Palladium</a>
|
||||||
|
</li>
|
||||||
|
<li><a href="https://github.com/BinBashBanana/PyDodge">PyDodge</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
<h3 id="other-">Other:</h3>
|
<h3 id="other-">Other:</h3>
|
||||||
<ul>
|
<ul>
|
||||||
<li><a href="https://github.com/vibedivide/vibeOS">vibeOS</a></li>
|
<li><a href="https://github.com/vibedivide/vibeOS">vibeOS</a></li>
|
||||||
<li><a href="https://github.com/BinBashBanana/webretro">webretro</a></li>
|
<li><a href="https://github.com/BinBashBanana/webretro">webretro</a></li>
|
||||||
<li><a href="https://ruffle.rs/">Ruffle</a></li>
|
<li><a href="https://ruffle.rs/">Ruffle</a></li>
|
||||||
<li><a href="https://github.com/BlaNKtext/webosu">webosu</a></li>
|
<li><a href="https://github.com/BlaNKtext/webosu">webosu</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
<h3 id="notable-mentions-">Notable Mentions:</h3>
|
<h3 id="notable-mentions-">Notable Mentions:</h3>
|
||||||
<ul>
|
<ul>
|
||||||
<li><a href="https://soyoustart.com/">SoYouStart / OVH</a> (Hosting Provider)</li>
|
<li>
|
||||||
|
<a href="https://soyoustart.com/">SoYouStart / OVH</a> (Hosting Provider)
|
||||||
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
<p>Thanks :D</p>
|
<p>Thanks :D</p>
|
||||||
|
|
|
@ -23,7 +23,7 @@
|
||||||
<a id="iconfinder" class="fancybutton fb-l glowbutton">Find Icon URL</a>
|
<a id="iconfinder" class="fancybutton fb-l glowbutton">Find Icon URL</a>
|
||||||
</div>
|
</div>
|
||||||
<script>
|
<script>
|
||||||
document.getElementById("iconfinder").href =
|
document.getElementById('iconfinder').href =
|
||||||
`javascript:alert((Array.from(document.head.querySelectorAll("link[rel*='icon']")).slice(-1)[0]||0).href||location.origin+"/favicon.ico")`;
|
`javascript:alert((Array.from(document.head.querySelectorAll("link[rel*='icon']")).slice(-1)[0]||0).href||location.origin+"/favicon.ico")`;
|
||||||
</script>
|
</script>
|
||||||
<p>
|
<p>
|
||||||
|
|
|
@ -7,111 +7,143 @@
|
||||||
<div class="footerlist">
|
<div class="footerlist">
|
||||||
<h3>Dependencies</h3>
|
<h3>Dependencies</h3>
|
||||||
<ul>
|
<ul>
|
||||||
<li><a
|
<li>
|
||||||
target="_blank"
|
<a
|
||||||
rel="noopener noreferrer"
|
target="_blank"
|
||||||
href="/github/fastify"
|
rel="noopener noreferrer"
|
||||||
title="Fastify - Fast and low overhead web framework, for Node.js "
|
href="/github/fastify"
|
||||||
>Fastify</a
|
title="Fastify - Fast and low overhead web framework, for Node.js "
|
||||||
></li>
|
>Fastify</a
|
||||||
<li><a
|
>
|
||||||
target="_blank"
|
</li>
|
||||||
rel="noopener noreferrer"
|
<li>
|
||||||
href="/github/nord-theme"
|
<a
|
||||||
title="Nord Theme - An arctic, north-bluish color palette."
|
target="_blank"
|
||||||
>Nord Theme</a
|
rel="noopener noreferrer"
|
||||||
></li>
|
href="/github/nord-theme"
|
||||||
<li><a
|
title="Nord Theme - An arctic, north-bluish color palette."
|
||||||
target="_blank"
|
>Nord Theme</a
|
||||||
rel="noopener noreferrer"
|
>
|
||||||
href="/github/aos"
|
</li>
|
||||||
title="AOS - Animate on scroll library "
|
<li>
|
||||||
>AOS</a
|
<a
|
||||||
></li>
|
target="_blank"
|
||||||
<li><a
|
rel="noopener noreferrer"
|
||||||
target="_blank"
|
href="/github/aos"
|
||||||
rel="noopener noreferrer"
|
title="AOS - Animate on scroll library "
|
||||||
href="/github/font-awesome"
|
>AOS</a
|
||||||
title="Font Awesome - The iconic SVG, font, and CSS toolkit"
|
>
|
||||||
>Font Awesome </a
|
</li>
|
||||||
></li>
|
<li>
|
||||||
|
<a
|
||||||
|
target="_blank"
|
||||||
|
rel="noopener noreferrer"
|
||||||
|
href="/github/font-awesome"
|
||||||
|
title="Font Awesome - The iconic SVG, font, and CSS toolkit"
|
||||||
|
>Font Awesome
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
<div class="footerlist">
|
<div class="footerlist">
|
||||||
<h3>Transports</h3>
|
<h3>Transports</h3>
|
||||||
<ul>
|
<ul>
|
||||||
<li><a
|
<li>
|
||||||
target="_blank"
|
<a
|
||||||
rel="noopener noreferrer"
|
target="_blank"
|
||||||
href="/github/epoxy"
|
rel="noopener noreferrer"
|
||||||
title="Epoxy - Epoxy is an encrypted proxy for browser javascript. It allows you to make requests that bypass CORS without compromising security, by running SSL/TLS inside webassembly."
|
href="/github/epoxy"
|
||||||
>Epoxy</a
|
title="Epoxy - Epoxy is an encrypted proxy for browser javascript. It allows you to make requests that bypass CORS without compromising security, by running SSL/TLS inside webassembly."
|
||||||
></li>
|
>Epoxy</a
|
||||||
<li><a
|
>
|
||||||
target="_blank"
|
</li>
|
||||||
rel="noopener noreferrer"
|
<li>
|
||||||
href="/github/libcurl-js"
|
<a
|
||||||
title="A port of libcurl to WebAssembly, for proxying HTTPS requests from the browser with full TLS encryption"
|
target="_blank"
|
||||||
>Libcurl</a
|
rel="noopener noreferrer"
|
||||||
></li>
|
href="/github/libcurl-js"
|
||||||
<li><a
|
title="A port of libcurl to WebAssembly, for proxying HTTPS requests from the browser with full TLS encryption"
|
||||||
target="_blank"
|
>Libcurl</a
|
||||||
rel="noopener noreferrer"
|
>
|
||||||
href="/github/bare-module"
|
</li>
|
||||||
title="Bare Module - Tomp Bare Client as a bare-mux module"
|
<li>
|
||||||
>Bare Module</a
|
<a
|
||||||
></li>
|
target="_blank"
|
||||||
|
rel="noopener noreferrer"
|
||||||
|
href="/github/bare-module"
|
||||||
|
title="Bare Module - Tomp Bare Client as a bare-mux module"
|
||||||
|
>Bare Module</a
|
||||||
|
>
|
||||||
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
<div class="footerlist">
|
<div class="footerlist">
|
||||||
<h3>Services</h3>
|
<h3>Services</h3>
|
||||||
<ul>
|
<ul>
|
||||||
<li><a
|
<li>
|
||||||
target="_blank"
|
<a
|
||||||
rel="noopener noreferrer"
|
target="_blank"
|
||||||
href="/github/ultraviolet"
|
rel="noopener noreferrer"
|
||||||
title="Ultraviolet - Explore Ultraviolet"
|
href="/github/ultraviolet"
|
||||||
>Ultraviolet</a
|
title="Ultraviolet - Explore Ultraviolet"
|
||||||
></li>
|
>Ultraviolet</a
|
||||||
<li><a
|
>
|
||||||
target="_blank"
|
</li>
|
||||||
rel="noopener noreferrer"
|
<li>
|
||||||
href="/github/wisp"
|
<a
|
||||||
title="Wisp - Wisp is a low-overhead, easy to implement protocol for proxying multiple TCP/UDP sockets over a single websocket. "
|
target="_blank"
|
||||||
>Wisp Protocol</a
|
rel="noopener noreferrer"
|
||||||
></li>
|
href="/github/wisp"
|
||||||
<li><a
|
title="Wisp - Wisp is a low-overhead, easy to implement protocol for proxying multiple TCP/UDP sockets over a single websocket. "
|
||||||
target="_blank"
|
>Wisp Protocol</a
|
||||||
rel="noopener noreferrer"
|
>
|
||||||
href="/rammerhead-discord"
|
</li>
|
||||||
title="Rammerhead - Join Rammerhead on Discord"
|
<li>
|
||||||
>Rammerhead</a
|
<a
|
||||||
></li>
|
target="_blank"
|
||||||
<li><a
|
rel="noopener noreferrer"
|
||||||
target="_blank"
|
href="/rammerhead-discord"
|
||||||
rel="noopener noreferrer"
|
title="Rammerhead - Join Rammerhead on Discord"
|
||||||
href="/github/bare-mux"
|
>Rammerhead</a
|
||||||
title="BareMux - A system for managing http transports in a project such as Ultraviolet"
|
>
|
||||||
>Bare-Mux</a
|
</li>
|
||||||
></li>
|
<li>
|
||||||
|
<a
|
||||||
|
target="_blank"
|
||||||
|
rel="noopener noreferrer"
|
||||||
|
href="/github/bare-mux"
|
||||||
|
title="BareMux - A system for managing http transports in a project such as Ultraviolet"
|
||||||
|
>Bare-Mux</a
|
||||||
|
>
|
||||||
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
<div class="footerlist">
|
<div class="footerlist">
|
||||||
<h3>About</h3>
|
<h3>About</h3>
|
||||||
<ul>
|
<ul>
|
||||||
<li><a
|
<li>
|
||||||
target="_blank"
|
<a
|
||||||
rel="noopener noreferrer"
|
target="_blank"
|
||||||
href="/github"
|
rel="noopener noreferrer"
|
||||||
title="Holy Unblocker GitHub Repository"
|
href="/github"
|
||||||
>GitHub</a
|
title="Holy Unblocker GitHub Repository"
|
||||||
></li>
|
>GitHub</a
|
||||||
<li><a href="/terms" title="Privacy Policy and Terms of Service">Privacy and Terms of Service</a></li>
|
>
|
||||||
<li><a href="/credits" title="Credits and Acknowledgements">Credits</a></li>
|
</li>
|
||||||
|
<li>
|
||||||
|
<a href="/terms" title="Privacy Policy and Terms of Service"
|
||||||
|
>Privacy and Terms of Service</a
|
||||||
|
>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a href="/credits" title="Credits and Acknowledgements">Credits</a>
|
||||||
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
<div class="footerlist">
|
<div class="footerlist">
|
||||||
<a href="#header" title="Back to Top"><i class="fas fa-angle-double-up" aria-hidden="true"></i></a>
|
<a href="#header" title="Back to Top"
|
||||||
|
><i class="fas fa-angle-double-up" aria-hidden="true"></i
|
||||||
|
></a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="footersocials">
|
<div class="footersocials">
|
||||||
|
|
|
@ -1,20 +1,38 @@
|
||||||
<div class="brand-logo-container" aria-label="Brand Logo">
|
<div class="brand-logo-container" aria-label="Brand Logo">
|
||||||
<div class="logo" role="img" aria-label="Holy Unblocker Logo"></div>
|
<div class="logo" role="img" aria-label="Holy Unblocker Logo"></div>
|
||||||
<a href="/" class="brand pulse" title="Holy Unblocker Home Page">Holy Unblocker v6.3.x</a>
|
<a href="/" class="brand pulse" title="Holy Unblocker Home Page"
|
||||||
|
>Holy Unblocker v6.3.x</a
|
||||||
|
>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<ul class="navbar-1" role="list" aria-label="Primary navigation">
|
<ul class="navbar-1" role="list" aria-label="Primary navigation">
|
||||||
<li class="pulse" style="margin-left: 0;" role="listitem">
|
<li class="pulse" style="margin-left: 0" role="listitem">
|
||||||
<a href="/browsing" title="Web Proxies - Access various web proxies to bypass restrictions">Web Proxies</a>
|
<a
|
||||||
|
href="/browsing"
|
||||||
|
title="Web Proxies - Access various web proxies to bypass restrictions"
|
||||||
|
>Web Proxies</a
|
||||||
|
>
|
||||||
</li>
|
</li>
|
||||||
<li class="pulse" role="listitem">
|
<li class="pulse" role="listitem">
|
||||||
<a href="/games" title="Games - Explore a range of games available through our service">Games</a>
|
<a
|
||||||
|
href="/games"
|
||||||
|
title="Games - Explore a range of games available through our service"
|
||||||
|
>Games</a
|
||||||
|
>
|
||||||
</li>
|
</li>
|
||||||
<li class="pulse" role="listitem">
|
<li class="pulse" role="listitem">
|
||||||
<a href="/youtube" title="YouTube - Access YouTube content through our proxy service">YouTube</a>
|
<a
|
||||||
|
href="/youtube"
|
||||||
|
title="YouTube - Access YouTube content through our proxy service"
|
||||||
|
>YouTube</a
|
||||||
|
>
|
||||||
</li>
|
</li>
|
||||||
<li class="pulse new" role="listitem">
|
<li class="pulse new" role="listitem">
|
||||||
<a href="/apps" title="Applications - Browse a selection of useful applications">Applications</a>
|
<a
|
||||||
|
href="/apps"
|
||||||
|
title="Applications - Browse a selection of useful applications"
|
||||||
|
>Applications</a
|
||||||
|
>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
|
@ -26,33 +44,65 @@
|
||||||
<ul class="navbar" role="list" aria-label="Secondary navigation">
|
<ul class="navbar" role="list" aria-label="Secondary navigation">
|
||||||
<li class="dropdown-parent" role="listitem">
|
<li class="dropdown-parent" role="listitem">
|
||||||
<div class="pulse white-text" aria-haspopup="true" aria-expanded="false">
|
<div class="pulse white-text" aria-haspopup="true" aria-expanded="false">
|
||||||
<a href="#" aria-label="More options">More <i class="fas fa-ellipsis-v" aria-hidden="true"></i></a>
|
<a href="#" aria-label="More options"
|
||||||
|
>More <i class="fas fa-ellipsis-v" aria-hidden="true"></i
|
||||||
|
></a>
|
||||||
</div>
|
</div>
|
||||||
<div class="dropdown-child" tabindex="0" role="menu" aria-label="More options submenu">
|
<div
|
||||||
|
class="dropdown-child"
|
||||||
|
tabindex="0"
|
||||||
|
role="menu"
|
||||||
|
aria-label="More options submenu"
|
||||||
|
>
|
||||||
<ul class="subnavbar" role="menu">
|
<ul class="subnavbar" role="menu">
|
||||||
<li role="menuitem">
|
<li role="menuitem">
|
||||||
<a href="/bookmarklets" title="Bookmarklets - Useful tools and shortcuts for your browser">Bookmarklets</a>
|
<a
|
||||||
|
href="/bookmarklets"
|
||||||
|
title="Bookmarklets - Useful tools and shortcuts for your browser"
|
||||||
|
>Bookmarklets</a
|
||||||
|
>
|
||||||
</li>
|
</li>
|
||||||
<li role="menuitem">
|
<li role="menuitem">
|
||||||
<a href="/?documentation" title="Documentation - Detailed information and guides">Docs</a>
|
<a
|
||||||
|
href="/?documentation"
|
||||||
|
title="Documentation - Detailed information and guides"
|
||||||
|
>Docs</a
|
||||||
|
>
|
||||||
</li>
|
</li>
|
||||||
<li role="menuitem">
|
<li role="menuitem">
|
||||||
<a href="/questions" title="FAQ - Frequently asked questions and answers">FAQ</a>
|
<a
|
||||||
|
href="/questions"
|
||||||
|
title="FAQ - Frequently asked questions and answers"
|
||||||
|
>FAQ</a
|
||||||
|
>
|
||||||
</li>
|
</li>
|
||||||
<li role="menuitem">
|
<li role="menuitem">
|
||||||
<a href="/credits" title="Credits - Acknowledgements and contributions">Credits</a>
|
<a
|
||||||
|
href="/credits"
|
||||||
|
title="Credits - Acknowledgements and contributions"
|
||||||
|
>Credits</a
|
||||||
|
>
|
||||||
</li>
|
</li>
|
||||||
<li role="menuitem">
|
<li role="menuitem">
|
||||||
<a href="/terms" title="Terms of Service - Rules and policies of use">TOS</a>
|
<a href="/terms" title="Terms of Service - Rules and policies of use"
|
||||||
|
>TOS</a
|
||||||
|
>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
</li>
|
</li>
|
||||||
<li class="dropdown-parent" role="listitem">
|
<li class="dropdown-parent" role="listitem">
|
||||||
<div class="pulse white-text" aria-haspopup="true" aria-expanded="false">
|
<div class="pulse white-text" aria-haspopup="true" aria-expanded="false">
|
||||||
<a href="#" aria-label="Settings menu">Settings <i class="fas fa-cog pulse" aria-hidden="true"></i></a>
|
<a href="#" aria-label="Settings menu"
|
||||||
|
>Settings <i class="fas fa-cog pulse" aria-hidden="true"></i
|
||||||
|
></a>
|
||||||
</div>
|
</div>
|
||||||
<div class="dropdown-settings" tabindex="0" role="menu" aria-label="Settings menu">
|
<div
|
||||||
|
class="dropdown-settings"
|
||||||
|
tabindex="0"
|
||||||
|
role="menu"
|
||||||
|
aria-label="Settings menu"
|
||||||
|
>
|
||||||
<div id="csel"><!--SETTINGS--></div>
|
<div id="csel"><!--SETTINGS--></div>
|
||||||
</div>
|
</div>
|
||||||
</li>
|
</li>
|
||||||
|
|
|
@ -1,85 +1,91 @@
|
||||||
<div id="csel" class="settings-content">
|
<div id="csel" class="settings-content">
|
||||||
<div class="settings-header">
|
<div class="settings-header">
|
||||||
<p class="cseltitle-main">Settings</p>
|
<p class="cseltitle-main">Settings</p>
|
||||||
<i class="far fa-times-circle close-settings-btn"></i>
|
<i class="far fa-times-circle close-settings-btn"></i>
|
||||||
</div>
|
</div>
|
||||||
<div class="settings-content-body">
|
<div class="settings-content-body">
|
||||||
<div class="csel-container-left">
|
<div class="csel-container-left">
|
||||||
<p class="cseltitle">Tab Cloak</p>
|
<p class="cseltitle">Tab Cloak</p>
|
||||||
<form id="titleform" class="cloakform">
|
<form id="titleform" class="cloakform">
|
||||||
<input type="text" placeholder="Tab Title" spellcheck="false">
|
<input type="text" placeholder="Tab Title" spellcheck="false" />
|
||||||
<input type="submit" value="Apply">
|
<input type="submit" value="Apply" />
|
||||||
</form>
|
</form>
|
||||||
<form id="iconform" class="cloakform">
|
<form id="iconform" class="cloakform">
|
||||||
<input type="text" placeholder="Icon URL" spellcheck="false">
|
<input type="text" placeholder="Icon URL" spellcheck="false" />
|
||||||
<input type="submit" value="Apply">
|
<input type="submit" value="Apply" />
|
||||||
</form>
|
</form>
|
||||||
<p class="cseltitle">Ultraviolet Proxy Transport</p>
|
<p class="cseltitle">Ultraviolet Proxy Transport</p>
|
||||||
<div class="radio-group" id=uv-transport-list>
|
<div class="radio-group" id="uv-transport-list">
|
||||||
<label>
|
<label>
|
||||||
<p>Libcurl <span class="default-badge">Cross-Browser/Secure (Firefox)</span></p>
|
<p>
|
||||||
<input type="radio" name="uv-transport" value="libcurl" checked>
|
Libcurl
|
||||||
</label>
|
<span class="default-badge">Cross-Browser/Secure (Firefox)</span>
|
||||||
<label>
|
</p>
|
||||||
<p>Epoxy <span class="bare-badge">Fastest/Secure (Chromium, Apple)</span></p>
|
<input type="radio" name="uv-transport" value="libcurl" checked />
|
||||||
<input type="radio" name="uv-transport" value="epoxy">
|
</label>
|
||||||
</label>
|
<label>
|
||||||
<label>
|
<p>
|
||||||
<p>Bare <span class="beta-badge">Least Secure (All)</span></p>
|
Epoxy
|
||||||
<input type="radio" name="uv-transport" value="bare">
|
<span class="bare-badge">Fastest/Secure (Chromium, Apple)</span>
|
||||||
</label>
|
</p>
|
||||||
</div>
|
<input type="radio" name="uv-transport" value="epoxy" />
|
||||||
<p class="cseltitle">Advanced Options</p>
|
</label>
|
||||||
<div class="radio-group">
|
<label>
|
||||||
<label>
|
<p>Bare <span class="beta-badge">Least Secure (All)</span></p>
|
||||||
<p>Hide Ads <span class="default-badge">AdGuard</span></p>
|
<input type="radio" name="uv-transport" value="bare" />
|
||||||
<input type="checkbox" id="hideads" class="switch" checked>
|
</label>
|
||||||
</label>
|
|
||||||
<label>
|
|
||||||
<p>Enable Tor <span class="bare-badge">SOCKS5 Onion Routing</span></p>
|
|
||||||
<input type="checkbox" id="useonion" class="switch">
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="settings-right-column">
|
<p class="cseltitle">Advanced Options</p>
|
||||||
<p class="cseltitle">Search Engine</p>
|
<div class="radio-group">
|
||||||
<select>
|
<label>
|
||||||
<option>Google</option>
|
<p>Hide Ads <span class="default-badge">AdGuard</span></p>
|
||||||
<option>Bing</option>
|
<input type="checkbox" id="hideads" class="switch" checked />
|
||||||
<option>DuckDuckGo</option>
|
</label>
|
||||||
<option>Yahoo</option>
|
<label>
|
||||||
</select>
|
<p>Enable Tor <span class="bare-badge">SOCKS5 Onion Routing</span></p>
|
||||||
<p class="cseltitle">About:Blank</p>
|
<input type="checkbox" id="useonion" class="switch" />
|
||||||
<div class="switch-container">
|
</label>
|
||||||
<p>Stealth Tab <span class="default-badge">Default</span></p>
|
|
||||||
<input type="checkbox" class="switch">
|
|
||||||
</div>
|
|
||||||
<p class="cseltitle">Select Theme</p>
|
|
||||||
<div class="radio-group">
|
|
||||||
<label>
|
|
||||||
<p>Light</p>
|
|
||||||
<input type="radio" name="theme" value="lighttheme" checked>
|
|
||||||
</label>
|
|
||||||
<label>
|
|
||||||
<p>Dark</p>
|
|
||||||
<input type="radio" name="theme" value="darktheme">
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
<p class="cseltitle">Icon Presets</p>
|
|
||||||
<select id=icon-list>
|
|
||||||
<option><!-- Leave this blank to avoid a bug. --></option>
|
|
||||||
<option>Google</option>
|
|
||||||
<option>Bing</option>
|
|
||||||
<option>Google Drive</option>
|
|
||||||
<option>Gmail</option>
|
|
||||||
</select>
|
|
||||||
<p class="cseltitle">Enable Devtools</p>
|
|
||||||
<div class="radio-group">
|
|
||||||
<label>
|
|
||||||
<p>Eruda Devtools<span class="bare-badge">CTRL+SHIFT+I</span></p>
|
|
||||||
<input type="radio" name="theme" value="lighttheme" checked>
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="settings-right-column">
|
||||||
|
<p class="cseltitle">Search Engine</p>
|
||||||
|
<select>
|
||||||
|
<option>Google</option>
|
||||||
|
<option>Bing</option>
|
||||||
|
<option>DuckDuckGo</option>
|
||||||
|
<option>Yahoo</option>
|
||||||
|
</select>
|
||||||
|
<p class="cseltitle">About:Blank</p>
|
||||||
|
<div class="switch-container">
|
||||||
|
<p>Stealth Tab <span class="default-badge">Default</span></p>
|
||||||
|
<input type="checkbox" class="switch" />
|
||||||
|
</div>
|
||||||
|
<p class="cseltitle">Select Theme</p>
|
||||||
|
<div class="radio-group">
|
||||||
|
<label>
|
||||||
|
<p>Light</p>
|
||||||
|
<input type="radio" name="theme" value="lighttheme" checked />
|
||||||
|
</label>
|
||||||
|
<label>
|
||||||
|
<p>Dark</p>
|
||||||
|
<input type="radio" name="theme" value="darktheme" />
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
<p class="cseltitle">Icon Presets</p>
|
||||||
|
<select id="icon-list">
|
||||||
|
<option><!-- Leave this blank to avoid a bug. --></option>
|
||||||
|
<option>Google</option>
|
||||||
|
<option>Bing</option>
|
||||||
|
<option>Google Drive</option>
|
||||||
|
<option>Gmail</option>
|
||||||
|
</select>
|
||||||
|
<p class="cseltitle">Enable Devtools</p>
|
||||||
|
<div class="radio-group">
|
||||||
|
<label>
|
||||||
|
<p>Eruda Devtools<span class="bare-badge">CTRL+SHIFT+I</span></p>
|
||||||
|
<input type="radio" name="theme" value="lighttheme" checked />
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -36,7 +36,7 @@
|
||||||
<div id="particles-js" class="fullwidth"></div>
|
<div id="particles-js" class="fullwidth"></div>
|
||||||
<div id="mainbody" class="fullwidth">
|
<div id="mainbody" class="fullwidth">
|
||||||
<div class="box-g text-center textm">
|
<div class="box-g text-center textm">
|
||||||
<div id=emu-nav class=glist></div>
|
<div id="emu-nav" class="glist"></div>
|
||||||
<div class="gfooter">
|
<div class="gfooter">
|
||||||
<p>I promise I'll fix N64 and add DS soon ._.</p>
|
<p>I promise I'll fix N64 and add DS soon ._.</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -36,7 +36,7 @@
|
||||||
<div id="particles-js" class="fullwidth"></div>
|
<div id="particles-js" class="fullwidth"></div>
|
||||||
<div id="mainbody" class="fullwidth">
|
<div id="mainbody" class="fullwidth">
|
||||||
<div class="box-g text-center textm">
|
<div class="box-g text-center textm">
|
||||||
<div id=emulib-nav class=glist></div>
|
<div id="emulib-nav" class="glist"></div>
|
||||||
<div class="gfooter">
|
<div class="gfooter">
|
||||||
<p>
|
<p>
|
||||||
Have a game request? Contact us on <a id="tnlink">discord</a> or
|
Have a game request? Contact us on <a id="tnlink">discord</a> or
|
||||||
|
|
|
@ -44,7 +44,7 @@
|
||||||
autocomplete="off"
|
autocomplete="off"
|
||||||
placeholder="Search"
|
placeholder="Search"
|
||||||
/>
|
/>
|
||||||
<div id=flash-nav class=flist></div>
|
<div id="flash-nav" class="flist"></div>
|
||||||
<div class="gfooter-only">
|
<div class="gfooter-only">
|
||||||
<p>
|
<p>
|
||||||
Have a game request? Contact us on <a id="tnlink">discord</a> or
|
Have a game request? Contact us on <a id="tnlink">discord</a> or
|
||||||
|
|
|
@ -40,7 +40,7 @@
|
||||||
<div id="particles-js" class="fullwidth"></div>
|
<div id="particles-js" class="fullwidth"></div>
|
||||||
<div id="mainbody" class="fullwidth">
|
<div id="mainbody" class="fullwidth">
|
||||||
<div class="box-g text-center textm">
|
<div class="box-g text-center textm">
|
||||||
<div id=h5-nav class=glist></div>
|
<div id="h5-nav" class="glist"></div>
|
||||||
<div class="gfooter">
|
<div class="gfooter">
|
||||||
<p>
|
<p>
|
||||||
Have a game request? Contact us on <a id="tnlink">discord</a> or
|
Have a game request? Contact us on <a id="tnlink">discord</a> or
|
||||||
|
|
|
@ -49,7 +49,7 @@
|
||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
<script>
|
<script>
|
||||||
document.getElementById("iconfinder").href =
|
document.getElementById('iconfinder').href =
|
||||||
`javascript:alert((Array.from(document.head.querySelectorAll("link[rel*='icon']")).slice(-1)[0]||0).href||location.origin+"/favicon.ico")`;
|
`javascript:alert((Array.from(document.head.querySelectorAll("link[rel*='icon']")).slice(-1)[0]||0).href||location.origin+"/favicon.ico")`;
|
||||||
</script>
|
</script>
|
||||||
<p>
|
<p>
|
||||||
|
|
|
@ -90,13 +90,24 @@
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<div id=pr-rh-dc>
|
<div id="pr-rh-dc">
|
||||||
<a href="#" class="fancybutton glowbutton pr-go1">Ra­mmer­head (Classic)</a>
|
<a href="#" class="fancybutton glowbutton pr-go1"
|
||||||
<a href="#" class="fancybutton glowbutton pr-go2">Ra­mmer­head (Stealth)</a>
|
>Ra­mmer­head (Classic)</a
|
||||||
|
>
|
||||||
|
<a href="#" class="fancybutton glowbutton pr-go2"
|
||||||
|
>Ra­mmer­head (Stealth)</a
|
||||||
|
>
|
||||||
</div>
|
</div>
|
||||||
<div id=pr-uv-dc>
|
<div id="pr-uv-dc">
|
||||||
<a href="#" style="display:none;" class="fancybutton glowbutton pr-go1">Ultr­av­iol­et (Classic)</a>
|
<a
|
||||||
<a href="#" class="fancybutton glowbutton pr-go2">Ultr­avi­ole­t (Stealth)</a>
|
href="#"
|
||||||
|
style="display: none"
|
||||||
|
class="fancybutton glowbutton pr-go1"
|
||||||
|
>Ultr­av­iol­et (Classic)</a
|
||||||
|
>
|
||||||
|
<a href="#" class="fancybutton glowbutton pr-go2"
|
||||||
|
>Ultr­avi­ole­t (Stealth)</a
|
||||||
|
>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -57,8 +57,13 @@
|
||||||
<br />Sometimes the proxies are under high load so things may be slow,
|
<br />Sometimes the proxies are under high load so things may be slow,
|
||||||
sorry. In that case simply wait for the page to load.
|
sorry. In that case simply wait for the page to load.
|
||||||
</p>
|
</p>
|
||||||
<div id=pr-yt class="responsive-fix">
|
<div id="pr-yt" class="responsive-fix">
|
||||||
<a href="#" style="display:none;" class="fancybutton glowbutton pr-go1">Classic</a>
|
<a
|
||||||
|
href="#"
|
||||||
|
style="display: none"
|
||||||
|
class="fancybutton glowbutton pr-go1"
|
||||||
|
>Classic</a
|
||||||
|
>
|
||||||
<a href="#" class="fancybutton glowbutton pr-go2">Stealth</a>
|
<a href="#" class="fancybutton glowbutton pr-go2">Stealth</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -50,7 +50,7 @@
|
||||||
Its session-based proxying concept enables much support for webites
|
Its session-based proxying concept enables much support for webites
|
||||||
like Discord, YouTube, and more!
|
like Discord, YouTube, and more!
|
||||||
</p>
|
</p>
|
||||||
<div id=pr-rh class="pr-form">
|
<div id="pr-rh" class="pr-form">
|
||||||
<input
|
<input
|
||||||
type="text"
|
type="text"
|
||||||
spellcheck="false"
|
spellcheck="false"
|
||||||
|
|
|
@ -55,15 +55,17 @@
|
||||||
such as service workers and sophisticated rewriting techniques with
|
such as service workers and sophisticated rewriting techniques with
|
||||||
CAPTCHA support.
|
CAPTCHA support.
|
||||||
</p>
|
</p>
|
||||||
<div id=pr-uv class="pr-form">
|
<div id="pr-uv" class="pr-form">
|
||||||
<input
|
<input
|
||||||
type="text"
|
type="text"
|
||||||
spellcheck="false"
|
spellcheck="false"
|
||||||
autocomplete="off"
|
autocomplete="off"
|
||||||
placeholder="Search or enter in a target site!"
|
placeholder="Search or enter in a target site!"
|
||||||
/>
|
/>
|
||||||
<a href="#" style="display:none;" class="pr-button glowbutton pr-go1">Stea­lth</a>
|
<a href="#" style="display: none" class="pr-button glowbutton pr-go1"
|
||||||
<a href="#"" class="pr-button glowbutton pr-go2">Stea­lth</a>
|
>Stea­lth</a
|
||||||
|
>
|
||||||
|
<a href="#" class="pr-button glowbutton pr-go2">Stea­lth</a>
|
||||||
</div>
|
</div>
|
||||||
<h3>More Information:</h3>
|
<h3>More Information:</h3>
|
||||||
<div class="font3">
|
<div class="font3">
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
<!DOCTYPE html>
|
<!doctype html>
|
||||||
<html>
|
<html>
|
||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8" />
|
<meta charset="utf-8" />
|
||||||
|
|
|
@ -7,6 +7,6 @@
|
||||||
class WWError extends Error {
|
class WWError extends Error {
|
||||||
constructor(message) {
|
constructor(message) {
|
||||||
super(message);
|
super(message);
|
||||||
this.name = "[WorkerWare Exception]";
|
this.name = '[WorkerWare Exception]';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
importScripts("/uv/uv.bundle.js");
|
importScripts('/uv/uv.bundle.js');
|
||||||
importScripts("/uv/uv.config.js");
|
importScripts('/uv/uv.config.js');
|
||||||
importScripts(__uv$config.sw || "/uv/uv.sw.js");
|
importScripts(__uv$config.sw || '/uv/uv.sw.js');
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
||||||
|
@ -28,53 +28,54 @@ ww.use({
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
const uv = new UVServiceWorker();
|
const uv = new UVServiceWorker();
|
||||||
|
|
||||||
// Get list of blacklisted domains.
|
// Get list of blacklisted domains.
|
||||||
const blacklist = {};
|
const blacklist = {};
|
||||||
fetch("/assets/json/blacklist.json").then(request => {
|
fetch('/assets/json/blacklist.json').then((request) => {
|
||||||
request.json().then(jsonData => {
|
request.json().then((jsonData) => {
|
||||||
|
// Organize each domain by their tld (top level domain) ending.
|
||||||
|
jsonData.forEach((domain) => {
|
||||||
|
const domainTld = domain.replace(/.+(?=\.\w)/, '');
|
||||||
|
if (!blacklist.hasOwnProperty(domainTld)) blacklist[domainTld] = [];
|
||||||
|
|
||||||
// Organize each domain by their tld (top level domain) ending.
|
// Store each entry in an array. Each tld has its own array, which will
|
||||||
jsonData.forEach(domain => {
|
// later be concatenated into a regular expression.
|
||||||
const domainTld = domain.replace(/.+(?=\.\w)/, "");
|
|
||||||
if (!blacklist.hasOwnProperty(domainTld))
|
|
||||||
blacklist[domainTld] = [];
|
|
||||||
|
|
||||||
// Store each entry in an array. Each tld has its own array, which will
|
|
||||||
// later be concatenated into a regular expression.
|
|
||||||
blacklist[domainTld].push(
|
blacklist[domainTld].push(
|
||||||
encodeURIComponent(domain.slice(0, -domainTld.length))
|
encodeURIComponent(domain.slice(0, -domainTld.length))
|
||||||
.replace(/([()])/g, "\\$1")
|
.replace(/([()])/g, '\\$1')
|
||||||
.replace(/(\*\.)|\./g, (match, firstExpression) =>
|
.replace(/(\*\.)|\./g, (match, firstExpression) =>
|
||||||
firstExpression ? "(?:.+\\.)?" : "\\" + match)
|
firstExpression ? '(?:.+\\.)?' : '\\' + match
|
||||||
|
)
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
// Turn each domain list into a regular expression and prevent this
|
// Turn each domain list into a regular expression and prevent this
|
||||||
// from being accidentally modified afterward.
|
// from being accidentally modified afterward.
|
||||||
for (let [domainTld, domainList] of Object.entries(blacklist))
|
for (let [domainTld, domainList] of Object.entries(blacklist))
|
||||||
blacklist[domainTld] = new RegExp(`^(?:${domainList.join("|")})$`);
|
blacklist[domainTld] = new RegExp(`^(?:${domainList.join('|')})$`);
|
||||||
Object.freeze(blacklist);
|
Object.freeze(blacklist);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
self.addEventListener("fetch", (event) => {
|
self.addEventListener('fetch', (event) => {
|
||||||
event.respondWith(
|
event.respondWith(
|
||||||
(async () => {
|
(async () => {
|
||||||
if (uv.route(event)) {
|
if (uv.route(event)) {
|
||||||
// The one and only ghetto domain blacklist.
|
// The one and only ghetto domain blacklist.
|
||||||
const domain = new URL(uv.config.decodeUrl(
|
const domain = new URL(
|
||||||
new URL(event.request.url).pathname
|
uv.config.decodeUrl(
|
||||||
.replace(uv.config.prefix, "")
|
new URL(event.request.url).pathname.replace(uv.config.prefix, '')
|
||||||
)).hostname,
|
)
|
||||||
domainTld = domain.replace(/.+(?=\.\w)/, "");
|
).hostname,
|
||||||
|
domainTld = domain.replace(/.+(?=\.\w)/, '');
|
||||||
|
|
||||||
// If the domain is in the blacklist, return a 406 response code.
|
// If the domain is in the blacklist, return a 406 response code.
|
||||||
if (blacklist.hasOwnProperty(domainTld) &&
|
if (
|
||||||
blacklist[domainTld].test(domain.slice(0, -domainTld.length)))
|
blacklist.hasOwnProperty(domainTld) &&
|
||||||
return new Response(new Blob(), {status: 406});
|
blacklist[domainTld].test(domain.slice(0, -domainTld.length))
|
||||||
|
)
|
||||||
|
return new Response(new Blob(), { status: 406 });
|
||||||
|
|
||||||
return await uv.fetch(event);
|
return await uv.fetch(event);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,11 +1,10 @@
|
||||||
importScripts("/uv/uv.bundle.js");
|
importScripts('/uv/uv.bundle.js');
|
||||||
importScripts("/uv/uv.config.js");
|
importScripts('/uv/uv.config.js');
|
||||||
importScripts(__uv$config.sw || "/uv/uv.sw.js");
|
importScripts(__uv$config.sw || '/uv/uv.sw.js');
|
||||||
|
|
||||||
|
|
||||||
const uv = new UVServiceWorker();
|
const uv = new UVServiceWorker();
|
||||||
|
|
||||||
self.addEventListener("fetch", (event) => {
|
self.addEventListener('fetch', (event) => {
|
||||||
event.respondWith(
|
event.respondWith(
|
||||||
(async () => {
|
(async () => {
|
||||||
if (uv.route(event)) return await uv.fetch(event);
|
if (uv.route(event)) return await uv.fetch(event);
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
// This file overwrites the stock UV config.js
|
// This file overwrites the stock UV config.js
|
||||||
|
|
||||||
self.__uv$config = {
|
self.__uv$config = {
|
||||||
prefix: "/uv/service/",
|
prefix: '/uv/service/',
|
||||||
encodeUrl: Ultraviolet.codec.xor.encode,
|
encodeUrl: Ultraviolet.codec.xor.encode,
|
||||||
decodeUrl: Ultraviolet.codec.xor.decode,
|
decodeUrl: Ultraviolet.codec.xor.decode,
|
||||||
handler: "/uv/uv.handler.js",
|
handler: '/uv/uv.handler.js',
|
||||||
client: "/uv/uv.client.js",
|
client: '/uv/uv.client.js',
|
||||||
bundle: "/uv/uv.bundle.js",
|
bundle: '/uv/uv.bundle.js',
|
||||||
config: "/uv/uv.config.js",
|
config: '/uv/uv.config.js',
|
||||||
sw: "/uv/uv.sw.js",
|
sw: '/uv/uv.sw.js',
|
||||||
};
|
};
|
||||||
|
|
|
@ -4,10 +4,10 @@
|
||||||
/* Service Worker Middleware Script
|
/* Service Worker Middleware Script
|
||||||
/* ----------------------------------------------- */
|
/* ----------------------------------------------- */
|
||||||
|
|
||||||
importScripts("./WWError.js");
|
importScripts('./WWError.js');
|
||||||
const dbg = console.log.bind(console, "[WorkerWare]");
|
const dbg = console.log.bind(console, '[WorkerWare]');
|
||||||
const time = console.time.bind(console, "[WorkerWare]");
|
const time = console.time.bind(console, '[WorkerWare]');
|
||||||
const timeEnd = console.timeEnd.bind(console, "[WorkerWare]");
|
const timeEnd = console.timeEnd.bind(console, '[WorkerWare]');
|
||||||
|
|
||||||
/*
|
/*
|
||||||
OPTS:
|
OPTS:
|
||||||
|
@ -23,26 +23,26 @@ const defaultOpt = {
|
||||||
};
|
};
|
||||||
|
|
||||||
const validEvents = [
|
const validEvents = [
|
||||||
"abortpayment",
|
'abortpayment',
|
||||||
"activate",
|
'activate',
|
||||||
"backgroundfetchabort",
|
'backgroundfetchabort',
|
||||||
"backgroundfetchclick",
|
'backgroundfetchclick',
|
||||||
"backgroundfetchfail",
|
'backgroundfetchfail',
|
||||||
"backgroundfetchsuccess",
|
'backgroundfetchsuccess',
|
||||||
"canmakepayment",
|
'canmakepayment',
|
||||||
"contentdelete",
|
'contentdelete',
|
||||||
"cookiechange",
|
'cookiechange',
|
||||||
"fetch",
|
'fetch',
|
||||||
"install",
|
'install',
|
||||||
"message",
|
'message',
|
||||||
"messageerror",
|
'messageerror',
|
||||||
"notificationclick",
|
'notificationclick',
|
||||||
"notificationclose",
|
'notificationclose',
|
||||||
"paymentrequest",
|
'paymentrequest',
|
||||||
"periodicsync",
|
'periodicsync',
|
||||||
"push",
|
'push',
|
||||||
"pushsubscriptionchange",
|
'pushsubscriptionchange',
|
||||||
"sync",
|
'sync',
|
||||||
];
|
];
|
||||||
|
|
||||||
class WorkerWare {
|
class WorkerWare {
|
||||||
|
@ -52,7 +52,7 @@ class WorkerWare {
|
||||||
}
|
}
|
||||||
info() {
|
info() {
|
||||||
return {
|
return {
|
||||||
version: "0.1.0",
|
version: '0.1.0',
|
||||||
middlewares: this._middlewares,
|
middlewares: this._middlewares,
|
||||||
options: this._opt,
|
options: this._opt,
|
||||||
};
|
};
|
||||||
|
@ -61,10 +61,11 @@ class WorkerWare {
|
||||||
let validateMW = this.validateMiddleware(middleware);
|
let validateMW = this.validateMiddleware(middleware);
|
||||||
if (validateMW.error) throw new WWError(validateMW.error);
|
if (validateMW.error) throw new WWError(validateMW.error);
|
||||||
// This means the middleware is an anonymous function, or the user is silly and named their function "function"
|
// This means the middleware is an anonymous function, or the user is silly and named their function "function"
|
||||||
if (middleware.function.name == "function") middleware.name = crypto.randomUUID();
|
if (middleware.function.name == 'function')
|
||||||
|
middleware.name = crypto.randomUUID();
|
||||||
if (!middleware.name) middleware.name = middleware.function.name;
|
if (!middleware.name) middleware.name = middleware.function.name;
|
||||||
if (this._opt.randomNames) middleware.name = crypto.randomUUID();
|
if (this._opt.randomNames) middleware.name = crypto.randomUUID();
|
||||||
if (this._opt.debug) dbg("Adding middleware:", middleware.name);
|
if (this._opt.debug) dbg('Adding middleware:', middleware.name);
|
||||||
this._middlewares.push(middleware);
|
this._middlewares.push(middleware);
|
||||||
}
|
}
|
||||||
// Run all middlewares for the event type passed in.
|
// Run all middlewares for the event type passed in.
|
||||||
|
@ -91,12 +92,16 @@ class WorkerWare {
|
||||||
return fn;
|
return fn;
|
||||||
}
|
}
|
||||||
deleteByName(middlewareID) {
|
deleteByName(middlewareID) {
|
||||||
if (this._opt.debug) dbg("Deleting middleware:", middlewareID);
|
if (this._opt.debug) dbg('Deleting middleware:', middlewareID);
|
||||||
this._middlewares = this._middlewares.filter((mw) => mw.name !== middlewareID);
|
this._middlewares = this._middlewares.filter(
|
||||||
|
(mw) => mw.name !== middlewareID
|
||||||
|
);
|
||||||
}
|
}
|
||||||
deleteByEvent(middlewareEvent) {
|
deleteByEvent(middlewareEvent) {
|
||||||
if (this._opt.debug) dbg("Deleting middleware by event:", middlewareEvent);
|
if (this._opt.debug) dbg('Deleting middleware by event:', middlewareEvent);
|
||||||
this._middlewares = this._middlewares.filter((mw) => !mw.events.includes(middlewareEvent));
|
this._middlewares = this._middlewares.filter(
|
||||||
|
(mw) => !mw.events.includes(middlewareEvent)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
get() {
|
get() {
|
||||||
return this._middlewares;
|
return this._middlewares;
|
||||||
|
@ -107,7 +112,7 @@ class WorkerWare {
|
||||||
*/
|
*/
|
||||||
runMW(name, event) {
|
runMW(name, event) {
|
||||||
const middlewares = this._middlewares;
|
const middlewares = this._middlewares;
|
||||||
if (this._opt.debug) dbg("Running middleware:", name);
|
if (this._opt.debug) dbg('Running middleware:', name);
|
||||||
// if (middlewares.includes(name)) {
|
// if (middlewares.includes(name)) {
|
||||||
// return middlewares[name](event);
|
// return middlewares[name](event);
|
||||||
// } else {
|
// } else {
|
||||||
|
@ -119,7 +124,7 @@ class WorkerWare {
|
||||||
didCall = true;
|
didCall = true;
|
||||||
event.workerware = {
|
event.workerware = {
|
||||||
config: middlewares[i].configuration || {},
|
config: middlewares[i].configuration || {},
|
||||||
}
|
};
|
||||||
if (this._opt.timing) console.time(middlewares[i].name);
|
if (this._opt.timing) console.time(middlewares[i].name);
|
||||||
let call = middlewares[i].function(event);
|
let call = middlewares[i].function(event);
|
||||||
if (this._opt.timing) console.timeEnd(middlewares[i].name);
|
if (this._opt.timing) console.timeEnd(middlewares[i].name);
|
||||||
|
@ -127,7 +132,7 @@ class WorkerWare {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!didCall) {
|
if (!didCall) {
|
||||||
throw new WWError("Middleware not found!");
|
throw new WWError('Middleware not found!');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// type middlewareManifest = {
|
// type middlewareManifest = {
|
||||||
|
@ -139,32 +144,40 @@ class WorkerWare {
|
||||||
validateMiddleware(middleware) {
|
validateMiddleware(middleware) {
|
||||||
if (!middleware.function)
|
if (!middleware.function)
|
||||||
return {
|
return {
|
||||||
error: "middleware.function is required",
|
error: 'middleware.function is required',
|
||||||
};
|
};
|
||||||
if (typeof middleware.function !== "function")
|
if (typeof middleware.function !== 'function')
|
||||||
return {
|
return {
|
||||||
error: "middleware.function must be typeof function",
|
error: 'middleware.function must be typeof function',
|
||||||
};
|
};
|
||||||
if (typeof middleware.configuration !== "object" && middleware.configuration !== undefined) {
|
if (
|
||||||
|
typeof middleware.configuration !== 'object' &&
|
||||||
|
middleware.configuration !== undefined
|
||||||
|
) {
|
||||||
return {
|
return {
|
||||||
error: "middleware.configuration must be typeof object",
|
error: 'middleware.configuration must be typeof object',
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
if (!middleware.events)
|
if (!middleware.events)
|
||||||
return {
|
return {
|
||||||
error: "middleware.events is required",
|
error: 'middleware.events is required',
|
||||||
};
|
};
|
||||||
if (!Array.isArray(middleware.events))
|
if (!Array.isArray(middleware.events))
|
||||||
return {
|
return {
|
||||||
error: "middleware.events must be an array",
|
error: 'middleware.events must be an array',
|
||||||
};
|
};
|
||||||
if (middleware.events.some((ev) => !validEvents.includes(ev)))
|
if (middleware.events.some((ev) => !validEvents.includes(ev)))
|
||||||
return {
|
return {
|
||||||
error: "Invalid event type! Must be one of the following: " + validEvents.join(", "),
|
error:
|
||||||
|
'Invalid event type! Must be one of the following: ' +
|
||||||
|
validEvents.join(', '),
|
||||||
};
|
};
|
||||||
if (middleware.explicitCall && typeof middleware.explicitCall !== "boolean") {
|
if (
|
||||||
|
middleware.explicitCall &&
|
||||||
|
typeof middleware.explicitCall !== 'boolean'
|
||||||
|
) {
|
||||||
return {
|
return {
|
||||||
error: "middleware.explicitCall must be typeof boolean",
|
error: 'middleware.explicitCall must be typeof boolean',
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
return {
|
return {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue