This commit is contained in:
blahai 2024-08-12 12:02:48 +00:00
commit 39c61fd150
46 changed files with 16306 additions and 0 deletions

1
.gitignore vendored Normal file
View file

@ -0,0 +1 @@
.log/

21
LICENSE Normal file
View file

@ -0,0 +1,21 @@
MIT License
Copyright (c) 2020 Bruno
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

56
README.md Normal file
View file

@ -0,0 +1,56 @@
## 💻 Preview
https://github.com/AllJavi/tartarus-startpage/assets/49349604/9a2a3f4c-33ef-4eb3-9243-cc160a56a181
This start page is based on the [dawn](https://github.com/b-coimbra/dawn) repository, which has even more functionality. I've tweaked the page's style a bit to match my [dotfiles](https://github.com/AllJavi/tartarus-dotfiles), and I've added some features to make it more comfortable.
## ⌨️ Keybindings
| Hotkey | Action |
| ------------------------------------------------- | --------------------------- |
| <kbd>Numrow</kbd> \| <kbd>MouseWheel</kbd> \| <kbd>Click</kbd> | Switch tabs |
| <kbd>s</kbd> | Search Dialog |
| <kbd>q</kbd> | Config Dialog (new) |
| <kbd>Esc</kbd> | Close Dialogs |
## ⚙️ Configuration Dialog
![config-dialog](https://github.com/AllJavi/tartarus-startpage/assets/49349604/3b42c650-b5bb-4a7d-a358-cfa5a8915966)
The default configuration file is [userconfig.js](userconfig.js), but you can change it in the configuration dialog. You can find more information about how the file works in the [original repository](https://github.com/b-coimbra/dawn). The available components are tabs, a clock, and weather.
Additionally, there are two different new options:
- `fastlink`: To set the link of the Pokeball button.
- `localIcons`: To optimize the loading time of the icons, you can check it out [here](#local-icons).
## 🔍 Search Dialog
![search-dialog](https://github.com/AllJavi/tartarus-startpage/assets/49349604/3f76323d-88c4-41b6-b93d-e4cceb1780b7)
The search dialog allows you to display a search bar with various search engines defined in the configuration. To select each one, you simply need to prefix the query with the corresponding `!<id>`.
By default, the defined search engines are:
- `!g`: google
- `!d`: duckduckgo
- `!y`: youtube
- `!r`: reddit
- `!p`: pinterest
## 🖼 Available banners
|cbg-2|cbg-3|cbg-4|cbg-5|
| ------------- | ------------- | ------------- | ------------- |
|<img src="src/img/banners/cbg-2.gif" width=175>|<img src="src/img/banners/cbg-3.gif" width=175>|<img src="src/img/banners/cbg-4.gif" width=175>|<img src="src/img/banners/cbg-5.gif" width=175>|
|cbg-6|cbg-7|cbg-8|cbg-9|
| ------------- | ------------- | ------------- | ------------- |
|<img src="src/img/banners/cbg-6.gif" width=175>|<img src="src/img/banners/cbg-7.gif" width=175>|<img src="src/img/banners/cbg-8.gif" width=175>|<img src="src/img/banners/cbg-9.gif" width=175>|
|cbg-10|cbg-11|cbg-12|cbg-13|
| ------------- | ------------- | ------------- | ------------- |
|<img src="src/img/banners/cbg-10.gif" width=175>|<img src="src/img/banners/cbg-11.gif" width=175>|<img src="src/img/banners/cbg-12.gif" width=175>|<img src="src/img/banners/cbg-13.gif" width=175>|
## Local Icons
If you want to reduce the loading time of the icons, you could install the [icon font](https://github.com/AllJavi/tartarus-startpage/tree/master/src/fonts) locally and activate the option `"localIcons": true` in the config to disable the remote styles.
## Credit
- [Dawn Startpage](https://github.com/b-coimbra/dawn) ([preview](https://startpage.metaphoric.dev/))
## License
[MIT License](./LICENSE)

BIN
img/README-decorator.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 115 KiB

40
index.html Normal file
View file

@ -0,0 +1,40 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<link rel="stylesheet" type="text/css" href="src/css/awoo.min.css">
<link href="https://fonts.googleapis.com/css?family=Nunito:200|Roboto:100,400,700|Raleway:600" rel="stylesheet">
<link href="https://cdn.jsdelivr.net/gh/monzanifabio/cryptofont/cryptofont.css" rel="stylesheet">
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet" type="text/css">
<link href="src/css/style.css" rel="stylesheet" type="text/css">
<!-- <link href="src/css/tabler-icons.min.css" rel="stylesheet"> -->
<link rel="icon" type="image/svg+xml" href="src/img/favico.svg">
<title>~</title>
</head>
<body>
<tabs-list></tabs-list>
<script type="text/javascript" src="src/common/utils.js"></script>
<script type="text/javascript" src="src/common/storage.js"></script>
<script type="text/javascript" src="src/common/actions.js"></script>
<script type="text/javascript" src="src/common/config.js"></script>
<script type="text/javascript" src="src/common/strftime.js"></script>
<script type="text/javascript" src="src/common/component.js"></script>
<script type="text/javascript" src="./userconfig.js"></script>
<script type="text/javascript" src="src/components/tabs/tabs.component.js"></script>
<script type="text/javascript" src="src/components/weather/weather.api.js"></script>
<script type="text/javascript" src="src/components/weather/weather.component.js"></script>
<script type="text/javascript" src="src/components/clock/clock.component.js"></script>
<script type="text/javascript" src="src/components/statusbar/statusbar.component.js"></script>
<script type="text/javascript" src="src/components/search/search.component.js"></script>
<script type="text/javascript" src="src/components/config/config.component.js"></script>
<script type="text/javascript" src="src/common/module.js"></script>
</body>
</html>

5
src/common/actions.js Normal file
View file

@ -0,0 +1,5 @@
class Actions {
static activate(componentName) {
return RenderedComponents[componentName].activate();
}
}

107
src/common/component.js Normal file
View file

@ -0,0 +1,107 @@
const RenderedComponents = {};
class Component extends HTMLElement {
refs = {};
resources = {
fonts: {
roboto: '<link href="https://fonts.googleapis.com/css?family=Roboto:100,400,700" rel="stylesheet">',
nunito: '<link href="https://fonts.googleapis.com/css?family=Nunito:200" rel="stylesheet">',
raleway: '<link href="https://fonts.googleapis.com/css?family=Raleway:600" rel="stylesheet">'
},
icons: {
material: '<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet" type="text/css">',
cryptofont: '<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/monzanifabio/cryptofont/cryptofont.css">',
tabler: '<link rel="stylesheet" href="src/css/tabler-icons.min.css">'
},
libs: {
awoo: '<link rel="stylesheet" type="text/css" href="src/css/awoo.min.css">'
}
};
constructor() {
super();
this.shadow = this.attachShadow({ mode: 'open' });
}
style() { return null; }
template() { return null; }
imports() { return []; }
/**
* Reference an external css file
* OBS: External style loading not yet fully supported with web components, causes flickering.
* @param {string} path
* @returns {void}
*/
set stylePath(path) {
this.resources.style = `<link rel="preload" as="style" href="${path}" onload="this.rel='stylesheet'">`;
}
/**
* Return all the imports that a component requested.
* @returns {Array<string>} imports
*/
get getResources() {
const imports = this.imports();
if (this.resources?.style)
imports.push(this.resources.style);
return imports;
}
/**
* Return inline style tag.
* @returns {string}
*/
async loadStyles() {
let html = this.getResources.join("\n");
if (this.style())
html += `<style>${this.style()}</style>`;
return html;
}
/**
* Build the component's HTML body.
* @returns {string} html
*/
async buildHTML() {
return await this.loadStyles() +
await this.template();
}
/**
* Create a reference for manipulating DOM elements.
* @returns {Proxy<HTMLElement | boolean>}
*/
createRef() {
return new Proxy(this.refs, {
get: (target, prop) => {
const ref = target[prop];
const elems = this.shadow.querySelectorAll(ref);
if (elems.length > 1) return elems;
const element = elems[0];
if (!element) return ref;
return element;
},
set: (target, prop, value) => {
this.shadow.querySelector(target[prop]).innerHTML = value;
return true;
}
});
}
async render() {
this.shadow.innerHTML = await this.buildHTML();
this.refs = this.createRef();
RenderedComponents[this.localName] = this;
}
}

119
src/common/config.js Normal file
View file

@ -0,0 +1,119 @@
class Config {
defaults = {
overrideStorage: false,
temperature: {
location: 'New York',
scale: 'C'
},
clock: {
format: 'h:i p',
iconColor: '#ff7b95'
},
search: {
engines: {
w: ['https://whoogle.no-logs.com/search?q=', 'Whoogle'],
y: ['https://youtube.com/results?search_query=', 'Youtube'],
}
},
disabled: [],
openLastVisitedTab: false,
tabs: [],
keybindings: {
"s": 'search-bar'
}
};
config;
constructor (config) {
this.config = config;
this.storage = new Storage('config');
this.autoConfig();
this.setKeybindings();
this.save();
return new Proxy(this, {
...this,
__proto__: this.__proto__,
set: (target, prop, value) =>
this.settingUpdatedCallback(target, prop, value)
});
}
/**
* Automatically save whenever a config property is updated.
* @returns {void}
*/
settingUpdatedCallback(target, prop, val) {
if (!(prop in target)) return false;
Reflect.set(target, prop, val);
Object.assign(this, target);
this.save();
return true;
}
/**
* Set default config values or load them from the local storage.
* @returns {void}
*/
autoConfig() {
Object.keys(this.defaults).forEach(setting => {
if (this.canOverrideStorage(setting))
this[setting] = this.config[setting];
else
if (this.storage.hasValue(setting))
this[setting] = this.storage.get(setting);
else
this[setting] = this.defaults[setting];
});
}
/**
* Determines whether the localStorage can be overridden.
* If the setting is for the tabs section, always override.
* @returns {bool}
*/
canOverrideStorage(setting) {
return setting in this.config && (this.config.overrideStorage || setting === 'tabs');
}
/**
* Deserialize the configuration object.
* @returns {Object}
*/
toJSON() {
return { ...this, defaults: undefined };
}
/**
* Trigger keybinding actions.
* @returns {void}
*/
setKeybindings() {
document.onkeypress = ({ key }) => {
if (document.activeElement !== document.body) return;
if (Object.keys(this.config.keybindings).includes(key))
Actions.activate(this.config.keybindings[key]);
};
}
save() {
this.storage.save(stringify(this));
}
exportSettings() {
const anchor = document.createElement('a');
const filename = 'dawn.config.json';
const mimeType = 'data:text/plain;charset=utf-8,';
anchor.href = mimeType + encodeURIComponent(stringify(this, null, 2));
anchor.download = filename;
anchor.click();
}
}

13
src/common/module.js Normal file
View file

@ -0,0 +1,13 @@
const components = {
'search-bar': Search,
'config-tab': ConfigTab,
'status-bar': Statusbar,
'current-time': Clock,
'weather-forecast': Weather,
'tabs-list': Tabs,
};
Object.keys(components).forEach(componentName => {
if (!CONFIG.disabled.includes(componentName))
customElements.define(componentName, components[componentName]);
});

20
src/common/storage.js Normal file
View file

@ -0,0 +1,20 @@
class Storage {
key;
constructor(key) {
this.key = key;
}
get(prop) {
return parse(localStorage[this.key])[prop];
}
save(value) {
localStorage[this.key] = value;
}
hasValue(value) {
if (!localStorage[this.key]) return false;
return value in parse(localStorage[this.key]);
}
}

65
src/common/strftime.js Normal file
View file

@ -0,0 +1,65 @@
/*
+----------+
| STRFTIME |
+----------+
Author: https://github.com/b-coimbra
Description: silly strftime function implementation in js without the percentage notation.
based off https://strftime.org
USAGE: new Date().strftime('H:M p - A') => 21:32 AM - Thursday
new Date().strftime('m/b/Y') => 1/Jan/2018
new Date().strftime('do B Y') => 18th January 2018
*/
Date.prototype.strftime = function (format = 'c') {
const date = this;
const isValid = (date) => date instanceof Date && !isNaN(date);
if (!isValid(date))
throw date;
Number.prototype.pad = function(n = 2) {
return (Array(n).join('0') + this).substr(-n);
};
Number.prototype.ord = function() {
return { 1: 'st', 2: 'nd', 3: 'rd' }[((num = this.toString()).length) > 1 ? parseInt(num.split('')[1]) : num] || 'th';
};
const month = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'],
days = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'],
result = [],
formats = {
a: days[date.getDay()].substr(0, 3),
A: days[date.getDay()],
w: date.getDay(),
q: date.getDay().pad(),
d: date.getDate().pad(),
e: date.getDate(),
b: month[date.getMonth()].substr(0, 3),
B: month[date.getMonth()],
m: date.getMonth() + 1,
N: (date.getMonth() + 1).pad(),
y: date.getFullYear().pad(),
Y: date.getFullYear(),
H: date.getHours(),
h: date.getHours().pad(),
p: date.getHours() >= 12 ? 'PM' : 'AM',
o: date.getDate().ord(),
M: date.getMinutes(),
i: date.getMinutes().pad(),
S: date.getSeconds(),
s: date.getSeconds().pad(),
f: date.getMilliseconds(),
c: date.toDateString() + ' - ' + date.toTimeString(),
x: date.toLocaleDateString(),
X: date.toLocaleTimeString()
};
format.split(/(\w|.)/m).forEach((type) => {
if (type)
result.push(typeof formats[type] === 'undefined' ? type : formats[type]);
});
return result.join('');
};

21
src/common/utils.js Normal file
View file

@ -0,0 +1,21 @@
const { parse, stringify } = JSON;
/**
* Handler for document.querySelector(All)
* @returns {HTMLElement | Array<HTMLElement>}
*/
const $ = (e, options) => {
const elems = document.querySelectorAll(e);
if (options?.includeAll || elems.length > 1) return elems;
return elems[0];
};
/**
* Return all children of a parent node.
* @returns {Array<HTMLElement>}
*/
Element.prototype.nodes = function() {
return Array.prototype.slice.call(this.children);
};

View file

@ -0,0 +1,60 @@
class Clock extends Component {
refs = {
clock: '.clock-time',
icon: '.clock-icon'
};
constructor() {
super();
}
imports() {
return [
this.resources.icons.material,
this.resources.fonts.roboto
];
}
style() {
return `
.clock-time {
white-space: nowrap;
font: 300 9pt 'Roboto', sans-serif;
color: #d4be98;
letter-spacing: .5px;
}
.clock-icon {
color: #ea6962;
font-size: 10pt;
margin-right: 10px;
}
`;
}
template() {
return `
<span class="material-icons clock-icon">schedule</span>
<p class="clock-time"></p>
`;
}
setIconColor() {
this.refs.icon.style.color = CONFIG.clock.iconColor;
}
setTime() {
const date = new Date();
this.refs.clock = date.strftime(CONFIG.clock.format);
}
connectedCallback() {
this.render().then(() => {
this.setTime();
this.setIconColor();
setInterval(() => this.setTime(), 1000);
});
}
}

View file

@ -0,0 +1,163 @@
class ConfigTab extends Component {
refs = {
config: '#config',
textarea: '#config textarea[type="text"]',
save: '.save',
close: '.close'
};
constructor() {
super();
this.config = JSON.parse(localStorage.getItem("config")).config;
}
style() {
return `
#config {
position: absolute;
display: flex;
align-items: center;
justify-content: center;
width: calc(100% - 2px);
height: 100%;
background: rgb(24 24 29 / 80%);
z-index: 99;
visibility: hidden;
top: -100%;
backdrop-filter: blur(5px);
transition: all .2s ease-in-out;
}
#config.active {
top: 0;
visibility: visible;
}
#config div {
position: relative;
width: 80%;
}
#config textarea {
border: 0;
outline: 0;
width: 100%;
box-shadow: inset 0 -2px #737373;
padding: .5em 0;
background: none;
font: 300 16px 'Roboto', sans-serif;
letter-spacing: 1px;
color: #d4be98;
resize: none;
height: 300px;
-ms-overflow-style: none;
scrollbar-width: none;
}
#config textarea:focus {
box-shadow: inset 0 -2px #d4be98;
}
#config textarea::selection {
background: #e78a4e;
color: #313244;
}
#config textarea::-webkit-scrollbar {
display: none;
}
#config .save {
background: 0;
border: 0;
outline: 0;
color: #d4be98;
position: absolute;
right: 40px;
cursor: pointer;
top: 15px;
font-size: 18px;
font-family: 'Roboto';
}
#config .save:hover {
filter: opacity(.5);
}
#config .close {
background: 0;
border: 0;
outline: 0;
color: #d4be98;
position: absolute;
right: 0;
cursor: pointer;
top: 15px;
}
#config .close:hover {
filter: opacity(.5);
}
`;
}
imports() {
return [
this.resources.fonts.roboto,
this.resources.icons.material
];
}
template() {
return `
<div id="config">
<div>
<textarea type="text" spellcheck="false"></textarea>
<button class="save">Save</button>
<button class="close"><i class="material-icons">&#xE5CD;</i></button>
</div>
</div>
`;
}
activate() {
this.refs.config.classList.add('active');
this.refs.textarea.scrollIntoView();
setTimeout(() => this.refs.textarea.focus(), 100);
}
deactivate() {
this.refs.config.classList.remove('active');
}
saveConfig() {
localStorage.setItem("CONFIG", this.refs.textarea.value);
this.deactivate();
location.reload();
}
handleSearch(event) {
const { key } = event;
if (key === 'Escape')
this.deactivate();
}
setEvents() {
this.refs.config.onkeyup = (e) => this.handleSearch(e);
this.refs.close.onclick = () => this.deactivate();
this.refs.save.onclick = () => this.saveConfig();
}
setConfig() {
this.refs.textarea.value = JSON.stringify(this.config, null, 4);
}
connectedCallback() {
this.render().then(() => {
this.setEvents();
this.setConfig();
});
}
}

View file

@ -0,0 +1,179 @@
class Search extends Component {
refs = {
search: '#search',
input: '#search input[type="text"]',
engines: '.search-engines',
close: '.close'
};
constructor() {
super();
this.engines = CONFIG.search.engines;
}
style() {
return `
#search {
position: absolute;
display: flex;
align-items: center;
justify-content: center;
width: calc(100% - 2px);
height: 100%;
background: rgb(24 24 29 / 80%);
z-index: 99;
visibility: hidden;
top: -100%;
backdrop-filter: blur(5px);
transition: all .2s ease-in-out;
}
#search.active {
top: 0;
visibility: visible;
}
#search div {
position: relative;
width: 80%;
}
#search input {
border: 0;
outline: 0;
width: 100%;
box-shadow: inset 0 -2px #737373;
padding: .5em 0;
background: none;
font: 500 22px 'Roboto', sans-serif;
letter-spacing: 1px;
color: #d4be98;
}
#search input:focus {
box-shadow: inset 0 -2px #d4be98;
}
#search input::selection {
background: #e78a4e;
color: #313244;
}
#search .close {
background: 0;
border: 0;
outline: 0;
color: #d4be98;
position: absolute;
right: 0;
cursor: pointer;
top: 15px;
}
#search .close:hover {
filter: opacity(.5);
}
.search-engines {
list-style: none;
color: rgba(212, 190, 152, 0.5);
display: flex;
padding: 0;
top: 50px;
left: 0;
margin: 1em 0 0 0;
}
.search-engines li p {
cursor: default;
transition: all .2s;
font-size: 12px;
font-family: 'Roboto', sans-serif;
}
.search-engines li {
margin: 0 1em 0 0;
}
.search-engines li.active {
color: #d4be98;
font-weight: 700;
}
`;
}
imports() {
return [
this.resources.fonts.roboto,
this.resources.icons.material
];
}
template() {
return `
<div id="search">
<div>
<input type="text" spellcheck="false" placeholder="search">
<button class="close"><i class="material-icons">&#xE5CD;</i></button>
<ul class="search-engines"></ul>
</div>
</div>
`;
}
loadEngines() {
for (var key in this.engines)
this.refs.engines.innerHTML += `<li><p title="${this.engines[key][1]}">!${key}</p></li>`;
}
activate() {
this.refs.search.classList.add('active');
this.refs.input.scrollIntoView();
setTimeout(() => this.refs.input.focus(), 100);
}
deactivate() {
this.refs.search.classList.remove('active');
}
handleSearch(event) {
const { target, key } = event;
let args = target.value.split(' ');
let prefix = args[0];
let defaultEngine = this.engines['d'][0];
let engine = defaultEngine;
this.refs.engines.childNodes.forEach(engine => {
if (prefix === engine.firstChild.innerHTML)
engine.classList.add('active');
else
engine.classList.remove('active');
});
if (key === 'Enter') {
if (prefix.indexOf('!') === 0) {
engine = this.engines[prefix.substr(1)][0];
args = args.slice(1);
}
window.location = engine + encodeURI(args.join(' '));
}
if (key === 'Escape')
this.deactivate();
}
setEvents() {
this.refs.search.onkeyup = (e) => this.handleSearch(e);
this.refs.close.onclick = () => this.deactivate();
}
connectedCallback() {
this.render().then(() => {
this.loadEngines();
this.setEvents();
});
}
}

View file

@ -0,0 +1,348 @@
class Statusbar extends Component {
externalRefs = {};
refs = {
categories: ".categories ul",
tabs: "#tabs ul li",
indicator: ".indicator",
fastlink: ".fastlink",
};
currentTabIndex = 0;
constructor() {
super();
this.setDependencies();
}
setDependencies() {
this.externalRefs = {
categories: this.parentNode.querySelectorAll(this.refs.categories),
};
}
imports() {
return [
this.resources.fonts.roboto,
this.resources.icons.material,
this.resources.libs.awoo,
];
}
style() {
return `
*:not(:defined) { display: none; }
#tabs,
#tabs .widgets,
#tabs ul li:last-child {
position: absolute;
}
#tabs {
width: 100%;
height: 100%;
}
#tabs ul {
counter-reset: tabs;
height: 100%;
position: relative;
list-style: none;
margin-left: 1em;
}
#tabs ul li:not(:last-child)::after {
content: counter(tabs, cjk-ideographic);
counter-increment: tabs;
display: flex;
width: 100%;
height: 100%;
position: relative;
align-items: center;
text-align: center;
justify-content: center;
}
#tabs ul li:not(:last-child) {
width: 35px;
text-align: center;
font: 700 13px 'Yu Gothic', serif;
color: rgba(212, 190, 152, 0.5);
padding: 6px 0;
transition: all .1s;
cursor: pointer;
line-height: 0;
height: 100%;
}
#tabs ul li:not(:last-child):hover {
background: #313244;
}
#tabs ul li:last-child {
--flavour: var(--accent);
width: 35px;
height: 3px;
background: var(--flavour);
bottom: 0;
transition: all .3s;
}
#tabs ul li[active]:not(:last-child) {
color: #d4be98;
font-size: 13px;
padding: 6px 0;
}
#tabs ul li[active]:nth-child(2) ~ li:last-child { margin: 0 0 0 35px; }
#tabs ul li[active]:nth-child(3) ~ li:last-child { margin: 0 0 0 70px; }
#tabs ul li[active]:nth-child(4) ~ li:last-child { margin: 0 0 0 105px; }
#tabs ul li[active]:nth-child(5) ~ li:last-child { margin: 0 0 0 140px; }
#tabs ul li[active]:nth-child(6) ~ li:last-child { margin: 0 0 0 175px; }
#tabs ul li[active]:nth-child(7) ~ li:last-child { margin: 0 0 0 210px; }
#tabs ul li[active]:nth-child(8) ~ li:last-child { margin: 0 0 0 245px; }
#tabs ul li[active]:nth-child(9) ~ li:last-child { margin: 0 0 0 280px; }
#tabs ul li[active]:nth-child(10) ~ li:last-child { margin: 0 0 0 315px; }
#tabs ul li[active]:nth-child(11) ~ li:last-child { margin: 0 0 0 350px; }
#tabs ul li[active]:nth-child(12) ~ li:last-child { margin: 0 0 0 385px; }
#tabs ul li[active]:nth-child(2) ~ li:last-child {
--flavour: #e78a4e;
}
#tabs ul li[active]:nth-child(3) ~ li:last-child {
--flavour: #ea6962;
}
#tabs ul li[active]:nth-child(4) ~ li:last-child {
--flavour: #7daea3;
}
#tabs ul li[active]:nth-child(5) ~ li:last-child {
--flavour: #d3869b;
}
#tabs ul li[active]:nth-child(6) ~ li:last-child {
--flavour: #89b482;
}
#tabs ul li[active]:nth-child(7) ~ li:last-child {
--flavour: #a9b665;
}
#tabs ul li[active]:nth-child(8) ~ li:last-child {
--flavour: #e78a4e;
}
#tabs ul li[active]:nth-child(9) ~ li:last-child {
--flavour: #ea6962;
}
#tabs ul li[active]:nth-child(10) ~ li:last-child {
--flavour: #7daea3;
}
#tabs ul li[active]:nth-child(11) ~ li:last-child {
--flavour: #d3869b;
}
#tabs ul li[active]:nth-child(12) ~ li:last-child {
--flavour: #89b482;
}
.widgets {
right: 0;
margin: auto;
height: 32px;
color: #fff;
font-size: 12px;
}
.widgets:hover .edit {
margin: 0;
}
.widget {
position: relative;
height: 100%;
padding: 0 1em;
}
.widget:first-child {
padding-left: 2em;
}
.widget:last-child {
padding-right: 2em;
}
.widget:hover {
cursor: pointer;
background: rgba(255, 255, 255, .05);
}
#tabs > cols {
position: relative;
grid-template-columns: [chat-tab] 35px [tabs] auto [widgets] auto;
}
#tabs .time span {
font-weight: 400;
}
#tabs i {
font-size: 14pt !important;
}
.widget:not(:first-child)::before {
content: '';
position: absolute;
display: block;
left: 0;
height: calc(100% - 15px);
width: 1px;
background: rgb(255 255 255 / 10%);
}
.fastlink {
border: 0;
background: #313244;
color: #a9b665;
cursor: pointer;
border-radius: 5px 15px 15px 5px;
}
.fastlink:hover {
filter: brightness(1.2);
}
.fastlink-icon {
width: 70%;
}
`;
}
template() {
return `
<div id="tabs">
<cols>
<button class="+ fastlink">
<img class="fastlink-icon" src="src/img/pokeball.svg"/>
</button>
<ul class="- indicator"></ul>
<div class="+ widgets col-end">
<current-time class="+ widget"></current-time>
<weather-forecast class="+ widget weather"></weather-forecast>
</div>
</cols>
</div>`;
}
setEvents() {
this.refs.tabs.forEach((tab) =>
tab.onclick = ({ target }) => this.handleTabChange(target)
);
document.onkeydown = (e) => this.handleKeyPress(e);
document.onwheel = (e) => this.handleWheelScroll(e);
this.refs.fastlink.onclick = () => {
console.log(CONFIG.fastlink);
if (CONFIG.config.fastlink) {
window.location.href = CONFIG.config.fastlink;
}
}
if (CONFIG.openLastVisitedTab) {
window.onbeforeunload = () => this.saveCurrentTab();
}
}
saveCurrentTab() {
localStorage.lastVisitedTab = this.currentTabIndex;
}
openLastVisitedTab() {
if (!CONFIG.openLastVisitedTab) return;
this.activateByKey(localStorage.lastVisitedTab);
}
handleTabChange(tab) {
this.activateByKey(Number(tab.getAttribute("tab-index")));
}
handleWheelScroll(event) {
if (!event) return;
let { target, wheelDelta } = event;
if (target.shadow && target.shadow.activeElement) return;
let activeTab = -1;
this.refs.tabs.forEach((tab, index) => {
if (tab.getAttribute("active") === "") {
activeTab = index;
}
});
if (wheelDelta > 0) {
this.activateByKey(
(activeTab - 1) < 0 ? this.refs.tabs.length - 2 : activeTab - 1,
);
} else {
this.activateByKey(
(activeTab + 1) % (this.refs.tabs.length - 1)
);
}
}
handleKeyPress(event) {
if (!event) return;
let { target, key } = event;
if (target.shadow && target.shadow.activeElement) return;
if (
Number.isInteger(parseInt(key)) &&
key <= this.externalRefs.categories.length
) {
this.activateByKey(key - 1);
}
}
activateByKey(key) {
if (key < 0) return;
this.currentTabIndex = key;
this.activate(this.refs.tabs, this.refs.tabs[key]);
this.activate(
this.externalRefs.categories,
this.externalRefs.categories[key],
);
}
createTabs() {
const categoriesCount = this.externalRefs.categories.length;
for (let i = 0; i <= categoriesCount; i++) {
this.refs.indicator.innerHTML += `<li tab-index=${i} ${
i == 0 ? "active" : ""
}></li>`;
}
}
activate(target, item) {
target.forEach((i) => i.removeAttribute("active"));
item.setAttribute("active", "");
}
connectedCallback() {
this.render().then(() => {
this.createTabs();
this.setEvents();
this.openLastVisitedTab();
});
}
}

View file

@ -0,0 +1,332 @@
class Links extends Component {
constructor() {
super();
}
static getIcon(link) {
const defaultColor = "#726f6f";
return link.icon
? `<i class="ti ti-${link.icon} link-icon"
style="color: ${link.icon_color ?? defaultColor}"></i>`
: "";
}
static getAll(tabName, tabs) {
const { categories } = tabs.find((f) => f.name === tabName);
return `
${
categories.map(({ name, links }) => {
return `
<li>
<h1>${name}</h1>
<div class="links-wrapper">
${
links.map((link) => `
<div class="link-info">
<a href="${link.url}">
${Links.getIcon(link)}
${
link.name ? `<p class="link-name">${link.name}</p>` : ""
}
</a>
</div>`).join("")
}
</div>
</li>`;
}).join("")
}
`;
}
}
class Category extends Component {
constructor() {
super();
}
static getBackgroundStyle(url) {
return `style="background-image: url(${url}); background-repeat: no-repeat;background-size: contain;"`;
}
static getAll(tabs) {
return `
${
tabs.map(({ name, background_url }, index) => {
return `<ul class="${name}" ${
Category.getBackgroundStyle(background_url)
} ${index == 0 ? "active" : ""}>
<div class="banner"></div>
<div class="links">${Links.getAll(name, tabs)}</div>
</ul>`;
}).join("")
}
`;
}
}
class Tabs extends Component {
refs = {};
constructor() {
super();
this.tabs = CONFIG.tabs;
}
imports() {
return [
this.resources.icons.material,
this.resources.icons.tabler,
this.resources.fonts.roboto,
this.resources.fonts.raleway,
this.resources.libs.awoo,
];
}
style() {
return `
status-bar {
bottom: -70px;
height: 32px;
background: #1d2021;
border-radius: 4px;
box-shadow: 0 10px 20px rgba(0, 0, 0, .25);
}
#panels, #panels ul,
#panels .links {
position: absolute;
}
.nav {
color: #fff;
}
#panels {
border-radius: 5px 0 0 5px;
width: 90%;
max-width: 1200px;
height: 450px;
right: 0;
left: 0;
top: 0;
bottom: 0;
margin: auto;
box-shadow: 0 5px 10px rgba(0, 0, 0, .2);
background: #1d2021;
}
.categories {
width: 100%;
height: 100%;
overflow: hidden;
position: relative;
border-radius: 10px 0 0 10px;
}
.categories ul {
--panelbg: transparent;
--flavour: var(--accent);
width: 100%;
height: 100%;
right: 100%;
background: #1d2021 url("../img/bg-1.gif") repeat left;
transition: all .6s;
# animation: scroll 25s ease-in-out infinite;
}
@keyframes scroll {
50% {
background-position-x: -240px;
}
}
.categories ul:nth-child(2) {
--flavour: #e78a4e;
}
.categories ul:nth-child(3) {
--flavour: #ea6962;
}
.categories ul:nth-child(4) {
--flavour: #7daea3;
}
.categories ul:nth-child(5) {
--flavour: #d3869b;
}
.categories ul:nth-child(6) {
--flavour: #d3869b;
}
.categories ul:nth-child(7) {
--flavour: #a9b665;
}
.categories ul:nth-child(8) {
--flavour: #e78a4e;
}
.categories ul:nth-child(9) {
--flavour: #ea6962;
}
.categories ul:nth-child(10) {
--flavour: #7daea3;
}
.categories ul:nth-child(11) {
--flavour: #d3869b;
}
.categories ul:nth-child(12) {
--flavour: #d3869b;
}
.categories ul .links {
box-shadow: inset -1px 0 var(--flavour);
}
.categories ul[active] {
right: 0;
z-index: 1;
}
.categories .links {
right: 0;
width: 70%;
height: 100%;
background: #282828;
padding: 5%;
flex-wrap: wrap;
}
.categories .links li {
list-style: none;
}
.categories ul .links a {
color: #d4be98;
text-decoration: none;
font: 700 18px 'Roboto', sans-serif;
transition: all .2s;
display: inline-flex;
align-items: center;
padding: .4em .7em;
background: #313244;
box-shadow: 0 4px rgba(50, 48, 47, 0.5), 0 5px 10px rgb(0 0 0 / 20%);
border-radius: 2px;
margin-bottom: .7em;
}
.categories .link-info {
display: inline-flex;
}
.categories .link-info:not(:last-child) { margin-right: .5em; }
.categories ul .links a:hover {
transform: translate(0, 4px);
box-shadow: 0 0 rgba(0, 0, 0, 0.25), 0 0 0 rgba(0, 0, 0, .5), 0 -0px 5px rgba(0, 0, 0, .1);
color: var(--flavour);
}
.categories ul::after {
content: attr(class);
position: absolute;
display: flex;
text-transform: uppercase;
overflow-wrap: break-word;
width: 25px;
height: 250px;
padding: 1em;
margin: auto;
border-radius: 5px;
box-shadow: inset 0 0 0 2px var(--flavour);
left: calc(15% - 42.5px);
bottom: 0;
top: 0;
background: linear-gradient(to top, rgb(50 48 47 / 90%), transparent);
color: var(--flavour);
letter-spacing: 1px;
font: 500 30px 'Nunito', sans-serif;
text-align: center;
flex-wrap: wrap;
word-break: break-all;
align-items: center;
backdrop-filter: blur(3px);
}
.categories .links li:not(:last-child) {
box-shadow: 0 1px 0 rgba(212, 190, 152, .25);
padding: 0 0 .5em 0;
margin-bottom: 1.5em;
}
.categories .links li h1 {
color: #d4be98;
opacity: 0.5;
font-size: 13px;
margin-bottom: 1em;
font-weight: 600;
letter-spacing: 1px;
text-transform: uppercase;
font-family: 'Raleway', sans-serif;
}
.categories .link-icon {
font-size: 27px;
color: #7f849c;
}
.categories .link-icon + .link-name {
margin-left: 10px;
}
.categories .links-wrapper {
display: flex;
flex-wrap: wrap;
}
.ti {
animation: fadeInAnimation ease .5s;
animation-iteration-count: 1;
animation-fill-mode: forwards;
height: 27px;
width: 27px;
}
@keyframes fadeInAnimation {
0% {
opacity: 0;
}
100% {
opacity: 1;
}
}
`;
}
template() {
return `
<div id="links" class="-">
<div id="panels">
<div class="categories">
${Category.getAll(this.tabs)}
<search-bar></search-bar>
<config-tab></config-tab>
</div>
<status-bar class="!-"></status-bar>
</div>
</div>
`;
}
connectedCallback() {
this.render();
}
}

View file

@ -0,0 +1,23 @@
class WeatherForecastClient {
constructor(location) {
this.appId = '50a34e070dd5c09a99554b57ab7ea7e2';
this.url = `https://api.openweathermap.org/data/2.5/weather?q=${encodeURI(location)}&units=metric&appid=${this.appId}`;
}
async getWeather() {
return await fetch(this.url)
.then(res => res.json())
.then(json => JSON.stringify(json))
.then(json => JSON.parse(json))
.then(data => {
const temperature = Math.round(data.main.temp);
const condition = data.weather[0].main.toLowerCase();
return {
temperature,
condition
};
})
.catch(err => console.warn('Weather API returned an error:', err));
}
}

View file

@ -0,0 +1,168 @@
class Weather extends Component {
refs = {
temperature: '.weather-temperature-value',
condition: '.weather-condition-icon',
scale: '.weather-temperature-scale'
};
forecasts = [
{
conditions: ['clouds', 'mist', 'haze', 'smoke'],
icon: 'cloud_queue',
color: 'cloudy'
},
{
conditions: ['drizzle', 'snow', 'rain'],
icon: 'opacity',
color: 'cloudy'
},
{
conditions: ['clear'],
icon: 'wb_sunny',
color: 'sunny'
},
{
conditions: ['thunderstorm'],
icon: 'bolt',
color: 'cloudy'
}
];
location;
constructor() {
super();
this.setDependencies();
this.setEvents();
}
setEvents() {
this.onclick = this.swapScale;
}
setDependencies() {
this.location = CONFIG.temperature.location;
this.temperatureScale = CONFIG.temperature.scale;
this.weatherForecast = new WeatherForecastClient(this.location);
}
imports() {
return [
this.resources.icons.material,
this.resources.fonts.roboto
];
}
style() {
return `
.weather-icon {
margin-right: 10px;
display: flex;
align-items: center;
justify-content: center;
}
.weather-temperature {
font: 300 9pt 'Roboto', sans-serif;
color: #d4be98;
white-space: nowrap;
display: flex;
align-items: center;
justify-content: center;
height: 100%;
}
.weather-temperature:hover .weather-temperature-location {
display: inline-block;
}
.weather-temperature-location {
display: none;
margin-right: 10px;
}
.weather-temperature-location {
font-weight: 500;
}
.weather-temperature-value
{
font-weight: bold;
}
.weather-condition-icon {
font-size: 14pt;
line-height: 0;
}
.weather-condition-icon.sunny {
color: #e78a4e;
}
.weather-condition-icon.cloudy {
color: #7daea3;
}
`;
}
async template() {
return `
<p class="+ weather-temperature">
<span class="weather-icon" class="+"><i class="material-icons weather-condition-icon sunny">wb_sunny</i></span>
<span class="weather-temperature-location">${this.location}</span>
<span class="weather-temperature-value">1</span>
º<span class="weather-temperature-scale">${this.temperatureScale}</span>
</p>`;
}
toC(f) { return Math.round((f - 32) * 5 / 9); }
toF(c) { return Math.round(c * 9 / 5 + 32); }
swapScale() {
this.temperatureScale = this.temperatureScale === 'C' ? 'F' : 'C';
CONFIG.temperature = {
...CONFIG.temperature,
scale: this.temperatureScale
};
this.setTemperature();
}
convertScale(temperature) {
if (this.temperatureScale === 'F')
return this.toF(temperature);
return temperature;
}
async setWeather() {
this.weather = await this.weatherForecast.getWeather();
this.setTemperature();
}
setTemperature() {
const { temperature, condition } = this.weather;
const { icon, color } = this.getForecast(condition);
this.refs.temperature = this.convertScale(temperature);
this.refs.condition = icon;
this.refs.scale = this.temperatureScale;
this.refs.condition.classList.add(color);
}
getForecast(condition) {
for (const forecast of this.forecasts)
if (forecast.conditions.includes(condition))
return forecast;
return this.forecasts[0];
}
async connectedCallback() {
await this.render();
await this.setWeather();
}
}

1
src/css/awoo.min.css vendored Normal file
View file

@ -0,0 +1 @@
@import url("https://fonts.googleapis.com/css?family=Roboto:300,400,500,700");*{margin:0;padding:0;outline:0;box-sizing:border-box}h1,h2,h3,h4,h5,h6,p,span{font-family:'Roboto', sans-serif}.\+{display:flex;align-items:center;justify-content:center}.\-,.\|{display:flex}.\-{align-items:center}.\|{justify-content:center}.\21\2d,.\21\7c,.\21\2b,.\21\5e,.\21\7e,.\21\3c,.\21\5f,.\21\3e{position:absolute;margin:auto}.\21\2d,.\21\2b,.\21\7e{right:0;left:0}.\21\7c,.\21\2b,.\21\7e{top:0;bottom:0}.\21\3c{left:0}.\21\5e{top:0}.\21\3e{right:0}.\21\5f{bottom:0}.push-right{float:right}.push-left{float:left}@media screen and (min-width: 700px){.col-1{--col: 1}.row-1{--row: 1}.col-2{--col: 2}.row-2{--row: 2}.col-3{--col: 3}.row-3{--row: 3}.col-4{--col: 4}.row-4{--row: 4}.col-5{--col: 5}.row-5{--row: 5}.col-6{--col: 6}.row-6{--row: 6}.col-7{--col: 7}.row-7{--row: 7}.col-8{--col: 8}.row-8{--row: 8}.col-9{--col: 9}.row-9{--row: 9}.col-10{--col: 10}.row-10{--row: 10}.col-11{--col: 11}.row-11{--row: 11}.col-12{--col: 12}.row-12{--row: 12}cols{grid-template-columns:repeat(12, auto);height:100%}rows{grid-template-rows:repeat(12, auto);width:100%;height:auto}cols .col-1.col-end{--col: calc((1 - 12) + 12) / calc(12 + 1)}cols .col-2.col-end{--col: calc((2 - 12) + 12) / calc(12 + 1)}cols .col-2.col-3{--col: 2 / calc(1 + 3)}cols .col-3.col-end{--col: calc((3 - 12) + 12) / calc(12 + 1)}cols .col-2.col-4{--col: 2 / calc(1 + 4)}cols .col-3.col-4{--col: 3 / calc(1 + 4)}cols .col-4.col-end{--col: calc((4 - 12) + 12) / calc(12 + 1)}cols .col-2.col-5{--col: 2 / calc(1 + 5)}cols .col-3.col-5{--col: 3 / calc(1 + 5)}cols .col-4.col-5{--col: 4 / calc(1 + 5)}cols .col-5.col-end{--col: calc((5 - 12) + 12) / calc(12 + 1)}cols .col-2.col-6{--col: 2 / calc(1 + 6)}cols .col-3.col-6{--col: 3 / calc(1 + 6)}cols .col-4.col-6{--col: 4 / calc(1 + 6)}cols .col-5.col-6{--col: 5 / calc(1 + 6)}cols .col-6.col-end{--col: calc((6 - 12) + 12) / calc(12 + 1)}cols .col-2.col-7{--col: 2 / calc(1 + 7)}cols .col-3.col-7{--col: 3 / calc(1 + 7)}cols .col-4.col-7{--col: 4 / calc(1 + 7)}cols .col-5.col-7{--col: 5 / calc(1 + 7)}cols .col-6.col-7{--col: 6 / calc(1 + 7)}cols .col-7.col-end{--col: calc((7 - 12) + 12) / calc(12 + 1)}cols .col-2.col-8{--col: 2 / calc(1 + 8)}cols .col-3.col-8{--col: 3 / calc(1 + 8)}cols .col-4.col-8{--col: 4 / calc(1 + 8)}cols .col-5.col-8{--col: 5 / calc(1 + 8)}cols .col-6.col-8{--col: 6 / calc(1 + 8)}cols .col-7.col-8{--col: 7 / calc(1 + 8)}cols .col-8.col-end{--col: calc((8 - 12) + 12) / calc(12 + 1)}cols .col-2.col-9{--col: 2 / calc(1 + 9)}cols .col-3.col-9{--col: 3 / calc(1 + 9)}cols .col-4.col-9{--col: 4 / calc(1 + 9)}cols .col-5.col-9{--col: 5 / calc(1 + 9)}cols .col-6.col-9{--col: 6 / calc(1 + 9)}cols .col-7.col-9{--col: 7 / calc(1 + 9)}cols .col-8.col-9{--col: 8 / calc(1 + 9)}cols .col-9.col-end{--col: calc((9 - 12) + 12) / calc(12 + 1)}cols .col-2.col-10{--col: 2 / calc(1 + 10)}cols .col-3.col-10{--col: 3 / calc(1 + 10)}cols .col-4.col-10{--col: 4 / calc(1 + 10)}cols .col-5.col-10{--col: 5 / calc(1 + 10)}cols .col-6.col-10{--col: 6 / calc(1 + 10)}cols .col-7.col-10{--col: 7 / calc(1 + 10)}cols .col-8.col-10{--col: 8 / calc(1 + 10)}cols .col-9.col-10{--col: 9 / calc(1 + 10)}cols .col-10.col-end{--col: calc((10 - 12) + 12) / calc(12 + 1)}cols .col-2.col-11{--col: 2 / calc(1 + 11)}cols .col-3.col-11{--col: 3 / calc(1 + 11)}cols .col-4.col-11{--col: 4 / calc(1 + 11)}cols .col-5.col-11{--col: 5 / calc(1 + 11)}cols .col-6.col-11{--col: 6 / calc(1 + 11)}cols .col-7.col-11{--col: 7 / calc(1 + 11)}cols .col-8.col-11{--col: 8 / calc(1 + 11)}cols .col-9.col-11{--col: 9 / calc(1 + 11)}cols .col-10.col-11{--col: 10 / calc(1 + 11)}cols .col-11.col-end{--col: calc((11 - 12) + 12) / calc(12 + 1)}cols .col-2.col-12{--col: 2 / calc(1 + 12)}cols .col-3.col-12{--col: 3 / calc(1 + 12)}cols .col-4.col-12{--col: 4 / calc(1 + 12)}cols .col-5.col-12{--col: 5 / calc(1 + 12)}cols .col-6.col-12{--col: 6 / calc(1 + 12)}cols .col-7.col-12{--col: 7 / calc(1 + 12)}cols .col-8.col-12{--col: 8 / calc(1 + 12)}cols .col-9.col-12{--col: 9 / calc(1 + 12)}cols .col-10.col-12{--col: 10 / calc(1 + 12)}cols .col-11.col-12{--col: 11 / calc(1 + 12)}cols .col-12.col-end{--col: calc((12 - 12) + 12) / calc(12 + 1)}.col-1.col-2{--col: 1 / calc(3)}.col-half{--col: 1 / 7}.row-half{--row: 1 / 7}.row-half-middle{--row: 7 / 13}.col-half-middle{--col: 7 / 13}.col-third{--col: 1 / 5}.row-third{--row: 1 / 5}.col-end{--col: 12}.row-end{--row: 12}}cols,rows{display:grid}[class*='col-']{grid-column:var(--col)}[class*='row-']{grid-row:var(--row)}.text-center{text-align:center}.relative{position:relative}

59
src/css/style.css Normal file
View file

@ -0,0 +1,59 @@
@charset "UTF-8";
* {
margin: 0;
border: 0;
padding: 0;
outline: 0;
list-style: none;
text-decoration: none;
text-rendering: optimizeLegibility;
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
-webkit-font-smoothing: subpixel-antialiased;
-moz-font-smoothing: subpixel-antialiased;
-ms-font-smoothing: subpixel-antialiased;
-o-font-smoothing: subpixel-antialiased;
-webkit-user-select: none;
-webkit-user-drag: none;
-moz-user-select: none;
-ms-user-select: none;
-o-user-select: none;
user-select: none;
}
*:not(:defined) {
display: none;
}
:root {
--accent: #a9b665;
--bg: #1d2021;
}
body {
background-color: var(--bg);
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='20' height='12' viewBox='0 0 20 12'%3E%3Cg fill-rule='evenodd'%3E%3Cg id='charlie-brown' fill='%23585858' fill-opacity='0.05'%3E%3Cpath d='M9.8 12L0 2.2V.8l10 10 10-10v1.4L10.2 12h-.4zm-4 0L0 6.2V4.8L7.2 12H5.8zm8.4 0L20 6.2V4.8L12.8 12h1.4zM9.8 0l.2.2.2-.2h-.4zm-4 0L10 4.2 14.2 0h-1.4L10 2.8 7.2 0H5.8z'/%3E%3C/g%3E%3C/g%3E%3C/svg%3E");
height: 100vh;
width: 100%;
display: flex;
overflow: hidden;
}
::selection {
background: none;
}
tabs-list {
position: relative;
width: 100%;
height: 100%;
background-image: url(../img/background.png);
background-repeat: no-repeat;
background-size: cover;
}

13992
src/css/tabler-icons.min.css vendored Normal file

File diff suppressed because it is too large Load diff

BIN
src/fonts/tabler-icons.eot Normal file

Binary file not shown.

BIN
src/fonts/tabler-icons.ttf Normal file

Binary file not shown.

BIN
src/fonts/tabler-icons.woff Normal file

Binary file not shown.

Binary file not shown.

BIN
src/img/background.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 162 KiB

BIN
src/img/banners/bg-1.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 182 KiB

BIN
src/img/banners/bg-2.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 600 KiB

BIN
src/img/banners/bg-3.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 47 KiB

BIN
src/img/banners/cbg-1.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 654 KiB

BIN
src/img/banners/cbg-10.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 MiB

BIN
src/img/banners/cbg-11.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 MiB

BIN
src/img/banners/cbg-12.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 679 KiB

BIN
src/img/banners/cbg-13.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 211 KiB

BIN
src/img/banners/cbg-2.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 599 KiB

BIN
src/img/banners/cbg-3.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 730 KiB

BIN
src/img/banners/cbg-4.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 851 KiB

BIN
src/img/banners/cbg-5.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 696 KiB

BIN
src/img/banners/cbg-6.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 98 KiB

BIN
src/img/banners/cbg-7.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 216 KiB

BIN
src/img/banners/cbg-8.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 241 KiB

BIN
src/img/banners/cbg-9.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 MiB

155
src/img/favico.svg Normal file
View file

@ -0,0 +1,155 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 27.1.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 450.6 732" style="enable-background:new 0 0 450.6 732;" xml:space="preserve">
<style type="text/css">
.st0{fill-rule:evenodd;clip-rule:evenodd;fill:#A9B665;}
</style>
<g id="Capa_2">
<g id="Capa_1-2">
<g id="Capa_2-2">
<g id="Capa_1-2-2">
<path class="st0" d="M217.1,321.8h17.2v0.8h3v0.8l5.2,0.8v0.8h1.5v0.8h2.2v0.8h1.5v0.8h1.5l0.8,1.5h1.5l0.8,1.5h1.5l2.2,3h1.5
l0.8,1.5h0.8v1.5l4.5,3.8v1.5l2.2,1.5l0.8,3h0.8l1.5,4.5h0.8l0.8,4.5h0.8v2.2h0.8l0.8,18h-0.8v4.5h-0.8v2.2h-0.8v2.2h-0.8v2.2
h-0.8l-1.5,4.5h-0.8l-0.8,3l-2.2,1.5v1.5l-3,2.2v1.5l-1.5,0.8v0.8l-2.2,0.8l-3,3.8h-1.5l-0.8,1.5h-1.5l-0.8,1.5l-4.5,1.5v0.8
h-1.5v0.8h-2.2v0.8h-2.2v0.8h-3v0.8h-3.8v0.8c-4.8,1.4-19.7-1-22.5-2.2v-0.8h-1.5v-0.8h-2.2V411h-1.5v-0.8h-1.5l-0.8-1.5l-3-0.8
l-1.5-2.2h-1.5l-3-3.8l-5.2-4.5c-6.1-8.6-12.9-24.5-8.2-39l0.8-6c3.7-9.5,12.1-19.6,20.2-24.8l3-0.8V326l3-0.8v-0.8h2.2V324h1.5
v-0.8C212.6,322.3,215.4,323.2,217.1,321.8z"/>
<path class="st0" d="M445.1,321c0.2-9.6-10.2-33.4-12-40.5c-1.7,0.7-0.6-3.7-2.2-3V276h-0.8v-2.2h-0.8c-0.8-0.2-0.7-5.5-2.2-4.5
v-1.5h-0.8c0-1.4-0.7-3.4-2.2-3.8v-1.5h-0.8V261h-0.8v-1.5c-1.2,0.4-0.5-1-0.8-1.5c-1.7,0-2.6-4.1-3-5.2
c-1.2,0.6-1.1-1.8-1.5-2.2l-1.5-0.8c-0.6-0.2-0.1-3.9-1.5-3l-0.8-2.2l-1.5-0.8v-1.5l-2.2-1.5v-1.5l-1.5-0.8V237l-1.5-0.8
c-0.5-1.4-1.4-3.3-3-3.8c0.6-1.5-2-3-3-3.8c0.8-2.4-3.8-2.9-3-5.2l-6-5.2c1.1-1.7-3.9-4.3-4.5-5.2c-1.9,0.2-8.3-11.7-10.5-9.8
l-4.5-5.2c-1.5,0.8-3.7-2.9-4.5-3.8c-1.6,0.8-3-2.2-3.8-3c-1.7,0.8-2.2-1.4-3-2.2c-1.2-0.5-2.8-0.8-3-2.2h-1.5
c-0.7-0.9-0.5-1.9-2.2-1.5c-1.8-3.6-2.7-1-3.8-3.8c-1.1-0.6-3.6-0.3-3.8-2.2c-1.3,0.1-1.9-0.3-2.2-1.5c-1.3,0.1-1.9-0.3-2.2-1.5
c-0.4-0.3-3.8-0.3-3-1.5c-1.3,0.1-1.9-0.3-2.2-1.5c-2.6,0.4-0.4-1.1-3-0.8v-0.8h-1.5V171H331v-0.8h-1.5v-0.8H328v-0.8h-1.5V168
H325v-0.8h-1.5c0.6-1.6-3.7-0.6-3-2.2H319v-0.8h-2.2c0.6-1.6-3.7-0.6-3-2.2h-2.2v-0.8h-1.5v-0.8c-0.4-0.3-4.6-0.2-3.8-1.5h-2.2
v-0.8h-1.5c0.8-1.9-5.3-0.4-4.5-2.2h-2.2v-0.8h-2.2v-0.8h-2.2v-0.8c-0.3-0.4-6.3,0-5.2-1.5c-0.4-0.3-7,0-6-1.5l-20.2-3.8
L254.6,0h-57.8c-1.1,5.4,0.4,20.5-1.5,24c-0.3,40.7-3.2,81.8-3.8,123c-12.5,1.2-25.4,5.1-34.5,8.2c-0.5,0-2.8-0.5-2.2,0.8
c-0.5,0-2.8-0.5-2.2,0.8h-2.2c0.3,1.2-0.9,0.6-1.5,0.8c0.9,1.2-4.1,1.2-4.5,1.5c0.4,1.5-0.9,0.4-1.5,0.8
c0.6,1.5-1.7,0.4-2.2,0.8c0.4,1.5-0.9,0.4-1.5,0.8c0.6,1.5-1.7,0.4-2.2,0.8c0.7,1.7-3.7,0.6-3,2.2c-0.4,0.5-2.9-0.8-2.2,0.8
l-4.5,1.5c0.4,1.5-0.9,0.4-1.5,0.8c0.4,1.5-0.9,0.4-1.5,0.8c0.4,1.5-0.9,0.4-1.5,0.8c0.4,1.5-0.9,0.4-1.5,0.8
c0.4,1.5-0.9,0.4-1.5,0.8c0.4,1.5-0.9,0.4-1.5,0.8c0.4,1.5-0.9,0.4-1.5,0.8c0,1.7-4.1,2.6-5.2,3c-0.1,1.8-2.6,1.9-3.8,2.2
c-0.1,1.8-2.6,1.9-3.8,2.2c0.6,1.1-1.8,1.1-2.2,1.5l-0.8,1.5c-2.5-0.5-1.3,2-3.8,1.5c-0.7,1.4-1.4,2.5-3,2.2
c-0.5,1.2-1,1.8-2.2,1.5c-0.7,1.4-1.4,2.5-3,2.2c-0.9,1.9-2.5,3.2-4.5,3.8c-0.5,1.2-1,1.7-2.2,1.5c-1.3,0.5-2.6,4.9-4.5,3.8
c-1.6,1.2-4.4,6.3-6.8,6c-5.7,6.2-12.8,14.1-18.7,19.5c0.8,1.6-2.2,3-3,3.8c0.7,1.6-1.4,2.3-2.2,3c0.7,1.6-1.4,2.3-2.2,3
c0.7,1.6-1.4,2.3-2.2,3c0.5,1.5-0.6,1.7-1.5,2.2c-0.3,0.6-0.5,2.7-1.5,2.2c0.7,1.6-1.4,2.3-2.2,3c-0.6,1.3-0.4,3.6-2.2,3.8
l-0.8,2.2h-0.8v1.5h-0.8v1.5c-1.8,0-2.5,4.1-3,5.2c-0.9,0.5-1.9,0.8-1.5,2.2h-0.8v1.5c-1.5-0.4,0,1.9-1.5,1.5
c0.3,2.5-1.1,0.5-0.8,3c-1.5-0.4,0,1.9-1.5,1.5c0.3,2.5-1.1,0.5-0.8,3c-1.5-0.4,0,1.9-1.5,1.5v1.5c-1.2-0.9-1.8,4.2-2.2,4.5
c-1.2-0.5-0.7,1.7-0.8,2.2c-1.5-0.4,0,1.9-1.5,1.5v2.2h-0.8v1.5h-0.8v2.2h-0.8v1.5h-0.8L13,295c-1.2-0.5-0.7,1.7-0.8,2.2
c-1.2-0.5-0.7,1.7-0.8,2.2c-1.2-0.5-0.7,1.7-0.8,2.2c-1.2-0.5-0.7,1.7-0.8,2.2c-1.5-1-1.1,5.7-1.5,6c-1.2-0.5-0.7,1.7-0.8,2.2
c-1.6-1.1-1,6.5-1.5,6.8c-1.3-0.7-0.6,2.5-0.8,3c-1.5-0.8-0.5,3.3-0.8,3.8c-1.5-0.8-0.5,3.3-0.8,3.8c-1.6-1-0.4,4.9-0.8,5.2
C1,335.9,1.7,352.9,1,357c-2.8,14,0.8,31.3,1.5,45c0.5,3.5,7.3,32.1,7.5,32.2c1.2-1,2,7.2,2.2,7.5c1.4-0.5,0.5,1,0.8,1.5
c1.2-0.8,1.2,4.1,1.5,4.5c1.6-0.5-0.1,2,1.5,1.5l0.8,4.5c1.2-0.7,1.2,2.5,1.5,3c1.2-0.8,1.2,3.3,1.5,3.8c1-0.8,1.9,4.1,2.2,4.5
c1.3-0.5,0.5,1,0.8,1.5c1.3-0.5,0.5,1,0.8,1.5c1.3-0.5,0.5,1,0.8,1.5c1.3-0.5,0.5,1,0.8,1.5c1.3-0.6,0.5,1,0.8,1.5
c1.6-0.5-0.1,2,1.5,1.5c0.1,0.5-0.5,1.9,0.8,1.5c0.1,0.5-0.5,1.9,0.8,1.5v1.5l1.5,0.8c1,0.7,0.8,5.6,3,5.2v1.5l1.5,0.8
c-0.2,3.2,2,0.7,2.2,5.2c1.3,0.4,1.7,1,1.5,2.2c0.9,0.8,2.8,1.5,2.2,3c1.3,0.4,1.7,1,1.5,2.2c0.9,0.8,2.8,1.5,2.2,3
c0.9,0.8,2.8,1.5,2.2,3c0.8,0.9,3.8,2.2,3,3.8c0.7,1,4.7,2.9,3.8,4.5c3.2,4,24,21.4,21,24c-1-0.7-0.8,1.1-0.8,1.5l-1.5,0.8
l-0.8,3l-1.5,0.8v1.5l-1.5,0.8l-0.8,2.2H67l-0.8,3c-1-0.6-1.2,1.8-1.5,2.2l-1.5,0.8v1.5c-1.5,0-2,2.6-2.2,3.8
c-1.2,0-2.1,2-2.2,3c-1.2-0.7-1.2,2.6-1.5,3l-1.5,0.8v1.5l-1.5,0.8v1.5c-2.5,0.3-1.3,4.2-3.8,4.5v1.5L49,577l-0.8,3
c-2.6,0.6-0.4,2.2-3,3c-0.2,0.2-0.5,3.1-1.5,2.2l-0.8,3h-0.8l-0.8,2.2l-1.5,0.8v1.5l-1.5,0.8l-0.8,3c-1.2-0.1-2.1,2-2.2,3
c-0.9-0.8-0.8,1.2-0.8,1.5c-2.6,0.9-2.5,5.5-5.2,6.8l-0.8,2.2l2.2,1.5v0.8c1.6-0.9,2.3,1.5,3,2.2c1.6-0.8,3,2.2,3.8,3
c2.2-0.8,2.2,3,4.5,2.2c0.5,0.9,1.5,2.8,3,2.2l1.5,2.2c1.6-0.9,2.3,1.5,3,2.2c2.5-0.5,1.3,2,3.8,1.5l1.5,2.2
c1.5-0.4,1.8,0.5,2.2,1.5l2.2,0.8v0.8l3,0.8l0.8,1.5l3,0.8l0.8,1.5c1.1,0.5,5.3,1.3,5.2,3c0.3,0.2,5.4,1.1,4.5,2.2H78v0.8h1.5
c-0.8,1.7,5.3,1.3,4.5,3h2.2v0.8c0.4,0.2,3.8,0.3,3,1.5h1.5v0.8h2.2c-0.7,1.7,3.7,0.6,3,2.2l3.8,0.8c-0.5,1,1.7,0.8,2.2,0.8v0.8
h1.5c-0.5,1,1.7,0.8,2.2,0.8v0.8c8.3,3.1,7.2,1.9,11.2-5.2c-0.3-1.4,0.3-1.9,1.5-2.2l0.8-3c1.6,0.4-0.1-1.9,1.5-1.5
c0-0.5-0.3-2,0.8-1.5v-1.5h0.8V639h0.8v-1.5c1.7,1.1,6.2-12.3,6.8-12.8c1.6-0.4,2-2.4,2.2-3.8c1.2,0,0.6-0.6,0.8-1.5
c1.6,0.4-0.1-1.9,1.5-1.5c0.1-0.5-0.3-2,0.8-1.5V615c1.2,0,0.6-0.6,0.8-1.5l1.5-0.8v-1.5c1.2,0,0.6-0.6,0.8-1.5
c1.6,0.4-0.1-1.9,1.5-1.5c0.1-0.6-0.3-2,0.8-1.5v-1.5c1.1,0,0.6-0.6,0.8-1.5c1.1,0,0.6-0.6,0.8-1.5c1.3-0.5,1.7-0.8,1.5-2.2
c1.1,0.2,0.7-0.8,0.8-1.5c1.1,0.2,0.7-0.8,0.8-1.5c1.6,0.4-0.1-1.9,1.5-1.5c0.1-1.2-0.4-1.5,0.8-1.5l1.5-4.5
c1.3-0.6,1.7-0.7,1.5-2.2c1.6,0.4-0.1-1.9,1.5-1.5c0.1-1.1-0.4-1.6,0.8-1.5c0.4-1.5,1.1-2.2,1.5-3.8c6.6,1.5,13.3,4.6,20.2,6
c-0.4,19.5-1.7,38.9-1.5,57.8c-1.8,8.8-1.1,30.2-1.5,40.5c-2-1.2-0.1,19.3-0.8,19.5c-1.8-1-0.2,7.9-0.7,8.2
c1,4.7-3.2,14.5,1.5,14.2v0.8c4.9-0.5,11,1.2,15.8,0.8c-1.3,1.7,7.4,0.3,7.5,0.8c-1.3,1.7,7.4,0.3,7.5,0.8
c-1.3,2.3,17.1,0,15.8,2.2c6.2-0.1,29.7,0.7,33-1.5c0.4-0.6,7.8,1.1,6.7-0.8c0.5-0.8,7.7,1.2,6.8-0.8c6,0,10.6-1.2,17.2-2.2
l-5.2-140.2l20.2-6c0.4,1.2,0.8,2.8,2.2,3c0.4,0.6-0.6,1.8,0.8,1.5l1.5,4.5c1.2-0.4,0.6,0.9,0.8,1.5c1.6-0.5-0.1,2,1.5,1.5
c-0.3,2.5,1.1,0.5,0.8,3c2.5,0.2,1.2,3.9,3,3.8c0.3,0.6-0.5,1.9,0.8,1.5c-0.3,2.5,1.1,0.5,0.8,3c1.2-0.4,0.6,0.9,0.8,1.5
c1.2-0.4,0.6,0.9,0.8,1.5c1,0.1,1.7,1,1.6,2l0,0c0,0.1,0,0.2-0.1,0.3c1.6-0.5-0.1,2,1.5,1.5c0.3,0.5-0.5,1.9,0.8,1.5
c0.3,0.5-0.5,1.9,0.8,1.5c0.3,0.5-0.5,2,0.8,1.5c0.3,0.5-0.5,2,0.8,1.5c0.3,0.5-0.5,2,0.8,1.5c-0.3,1,0.3,2,1.3,2.2l0,0h0.2
c0.5,0.3,0.2,3.8,1.5,3c0.3,0.4-0.5,2,0.8,1.5c0.2,0.4-0.5,2,0.8,1.5c0.2,0.4-0.5,2,0.8,1.5c-0.3,2.5,1.1,0.5,0.8,3
c2.5,0.5,0.6,2.4,2.2,2.2c0.2,0.4-0.5,2,0.8,1.5c0.2,0.4-0.5,2,0.8,1.5c0.2,0.4-0.5,2,0.8,1.5c0.2,0.4-0.5,2,0.8,1.5
c0.2,0.4-0.5,2,0.8,1.5c-0.2,1,0.3,2,1.3,2.2l0,0h0.2c0.2,0.3-0.5,2,0.8,1.5c0.2,0.3-0.5,2,0.8,1.5c0.2,0.3-0.5,2,0.8,1.5
c0.2,0.3-0.4,2.1,0.8,1.5c0.2,0.3-0.4,2.1,0.8,1.5c1.1,3.1,2.6,4.9,3.8,7.5c0.5-0.7,3.6-0.1,3-1.5h2.2c-0.5-1.3,1.7-0.5,2.2-0.8
c-0.4-1.2,0.9-0.6,1.5-0.8c-0.5-1.3,1.7-0.5,2.2-0.8c-0.7-1.2,2.5-1.2,3-1.5c-0.5-1.3,1.7-0.5,2.2-0.8c-0.8-1.2,3.3-1.2,3.8-1.5
c-0.4-1.2,0.9-0.6,1.5-0.8c-0.8-1.2,3.3-1.2,3.8-1.5c-0.8-1.1,4.1-1.9,4.5-2.2c-0.4-1.2,0.9-0.6,1.5-0.8c-0.5-1.6,2,0.1,1.5-1.5
c0.5-0.3,1.9,0.5,1.5-0.8c2.5,0.3,0.5-1.1,3-0.8c-0.5-1.6,2,0.1,1.5-1.5c0.5-0.3,1.9,0.5,1.5-0.8c2.5,0.3,0.5-1.1,3-0.8
c0.4-2.5,4.1-1.3,4.5-3.8c4.3-0.4,2.6-2.6,5.2-2.2c0.1-1,1-1.7,1.9-1.6l0,0c0.1,0,0.2,0,0.3,0.1c0.1-1,1-1.7,1.9-1.6l0,0
c0.1,0,0.2,0,0.3,0.1c0.1-1,1-1.7,1.9-1.6l0,0c0.1,0,0.2,0,0.3,0.1c0.5-1.1,1.6-2.7,3-2.2c1-2.8,2.1-0.1,3.8-3.8
c1,0.2,2-0.4,2.2-1.3l0,0v0.2c1.4,0.5,2.4-1.2,3-2.2c1.5,0.7,3-2.1,3.8-3c2.4,0.8,2.9-3.8,5.2-3l2.2-3c1.9,0-0.3-1.2-0.8-1.5
c0.2-1-0.3-1.9-1.3-2.2h-0.2c-0.5-1.3-0.5-3.6-2.2-3.8c0.4-2.6-1.9-0.9-2.2-5.2c-2.7-0.8-0.4-2.2-3-3c-0.4-0.6,0.5-1.8-0.8-1.5
c-0.6-0.5-0.3-2.8-1.5-2.2c0.4-2.5-1.9-1.4-2.2-4.5c-1.2,0.7-1.2-2.5-1.5-3c-1.4-0.2-2-1.9-2.2-3c-1.2,0.7-1.2-2.5-1.5-3
c-1-0.1-1.7-1-1.6-1.9c0,0,0,0,0-0.1s0-0.2,0-0.3c-1-0.1-1.7-1-1.6-1.9l0,0c0-0.1,0-0.2,0.1-0.3c-1.7-0.1-2-2.5-2.2-3.8
c-1-0.1-1.7-1-1.6-1.9l0,0c0-0.1,0-0.2,0.1-0.3c-1-0.1-1.7-1-1.6-1.9l0,0c0-0.1,0-0.2,0.1-0.3c-1.2,0.4-0.6-0.9-0.8-1.5
c-1-0.1-1.7-1-1.6-1.9l0,0c0-0.1,0-0.2,0.1-0.3c-1-0.1-1.7-1-1.6-1.9l0,0c0-0.1,0-0.2,0.1-0.3c-1.6-0.1-2-2.5-2.2-3.8
c-1.4-0.2-2-1.9-2.2-3c-1.2,0.7-1.2-2.5-1.5-3c-1.6,0.1-0.8-2.7-3-3c-0.6-2.9-7.4-9.6-4.5-10.5c0.5-0.8,1.6-3,3-2.2
c0.2-1.5,3.5-3.6,4.5-4.5c1.9-2.5,22.7-24.1,21.8-26.2c0.8-0.3,2.9-1.8,2.2-3c0.8-0.3,2.9-1.8,2.2-3l1.5-0.8
c0,0,0.6-3.1,1.5-2.2c-0.5-1,0.5-2.1,1.5-2.2c-0.5-0.9,0.5-2.1,1.5-2.2v-1.5l1.5-0.8l0.8-2.2c1,0.6,0.7-1,0.8-1.5
c1.6,0.5-0.1-2,1.5-1.5v-1.5l1.5-0.8V477h0.8v-1.5h0.8V474h0.8v-1.5l1.5-0.8c0.1,0,0.5-4,1.5-3l1.5-4.5c1.2,0.7,0.6-1.8,0.8-2.2
c1.6,0.7,0.6-3.7,2.2-3v-1.5h0.8c0-0.2-0.4-3.1,0.8-2.2c0.2-0.1,0.4-4,1.5-3c0.2,0,0.2-5.7,1.5-4.5v-1.5
c1.4,0.8,1.1-4.1,1.5-4.5C449.2,416.4,456,357.4,445.1,321z M407.6,374.2c0.3,4.9-1.1,11.6-0.8,16.5c-2.1-0.9,0.6,6.1-1.5,5.2
v5.2c-1.4-0.8-0.5,3.3-0.8,3.8c-1.4-0.8-0.5,3.3-0.8,3.8c-1.4-0.7-0.5,2.5-0.8,3c-1.9-0.7,0.4,3.7-1.5,3c-0.7,0.3,1,3.8-0.8,3
c-0.7,0.3,1,3.8-0.8,3c-0.1,0.5,0.5,2.8-0.8,2.2v2.2c-1.4-0.6-0.5,1.8-0.8,2.2c-1.2-0.8-1.2,4.1-1.5,4.5c-1.4-0.5-0.5,1-0.8,1.5
c-1.4-0.6-0.5,1.8-0.8,2.2c-1.4-0.5-0.5,1-0.8,1.5c-1.4-0.6-0.5,1.8-0.8,2.2c-1.2-0.7-1.2,2.5-1.5,3c-1.4-0.5-0.5,1-0.8,1.5
c-1.4-0.6-0.5,1.8-0.8,2.2c-1.2-0.7-1.2,2.5-1.5,3c-1.4-0.5-0.5,1-0.8,1.5c-1.5,0.4-1.5,1-1.5,2.2c-1.4-0.5-0.5,1-0.8,1.5
c-1.4-0.5-0.5,1-0.8,1.5c-1.4-0.5-0.5,1-0.8,1.5c-2.5,0.4-1.3,4.1-3.8,4.5c-0.4,4.3-2.6,2.6-2.2,5.2c-0.9,0.9-2.9,1.4-2.2,3
c-1.4,0.4-1.6,1-1.5,2.2c-0.9,0.9-2.9,1.4-2.2,3c-0.9,0.9-2.9,1.4-2.2,3c-0.8,1-3.8,2-3,3.8c-0.6,1.2-5.6,3.5-4.5,5.2l-10.5,11
c-1.5-0.1-6.3,9.2-8.3,7.5c-1.3,0.2-2.6,5-4.5,3.8c-0.7,1-2.1,3.6-3.8,3c-1.9,3.7-2.7,0.8-4.5,4.5c-1.4-0.6-1.8,0.7-2.2,1.5
c-0.6,0.2-2.7,0.6-2.2,1.5c-1.4-0.6-1.8,0.7-2.2,1.5l-2.2,0.8v0.8l-3,0.8l-0.8,1.5c-0.7,0.1-1.8-0.3-1.5,0.8
c-2.5-0.3-0.6,1.1-3,0.8v0.8h-1.5c-0.2,1.5-2.5,2.1-3.8,2.2c0.4,1.5-2,0-1.5,1.5c-0.4,0.1-5.3,1.2-4.5,2.2h-2.2
c0.7,1.7-3.7,0.6-3,2.2h-2.2v0.8c-0.7,0-1.8-0.2-1.5,0.8h-2.2c0.4,1.5-2,0-1.5,1.5c-16.7,4.4-39.4,11.6-54.8,10.5
c-6.5,1.7-19.9,0.6-26.2,0c0-1.2-14.9-0.1-13.5-2.2c0-1.1-9.5,0.6-8.2-1.5c-0.2-0.6-4.7,1-3.8-0.8c0-1.1-9.6-0.3-8.2-2.2h-2.2
v-0.8c0-1-8.8-0.4-7.5-2.2h-1.5v-0.8l-4.5-0.8c0.5-1.4-1-0.5-1.5-0.8c0.6-1.4-1.8-0.5-2.2-0.8c0.5-1.4-1-0.5-1.5-0.8
c0.6-1.4-1.8-0.5-2.2-0.8c0.7-1-4.1-2-4.5-2.2c0.5-1.4-1-0.5-1.5-0.8c0.5-1.4-1-0.5-1.5-0.8c0.5-1.6-2,0.1-1.5-1.5h-1.5
c0.6-1.4-1-0.5-1.5-0.8c0.5-1.6-2,0.1-1.5-1.5h-1.5c0.6-1.4-1-0.5-1.5-0.8c0.6-1.4-1.1-0.5-1.5-0.8c-0.4-2.5-4.1-1.3-4.5-3.8
c-1.6-0.4-4-1-4.5-3h-1.5V518l-2.2-0.8c-0.4-1.2-1.1-1.7-2.2-1.5c-0.1-1.5-2-1.9-3-2.2c-0.9-0.9-1.4-2.9-3-2.2
c-1.1-0.7-2-3.9-3.8-3c-1.3-0.4-3.4-5.7-5.2-4.5l-8.2-9c-0.7-0.7-11-9.2-9.8-10.5c-0.7-0.8-4.6-2.8-3.8-4.5L81,479
c0.5-1-1.1-1.1-1.5-1.5c0.8-1.6-1.4-2.3-2.2-3c-0.5-1.1-0.8-2.8-2.2-3c0.7-1.4-0.7-1.8-1.5-2.2c0.7-1.4-0.7-1.8-1.5-2.2
c0.7-1.4-0.7-1.8-1.5-2.2l-0.8-2.2H69l-0.8-3c-2.4-0.4-1.3-4.1-3.8-4.5c-0.2-0.4-1.1-5.4-2.2-4.5v-1.5h-0.8v-1.5h-0.8
c-0.2-0.4-1.1-5.4-2.2-4.5V441c-1.7,0.7-0.6-3.7-2.2-3v-2.2h-0.8v-1.5h-0.8c-0.2-0.4-0.2-5.4-1.5-4.5v-2.2h-0.8v-2.2h-0.8V423
h-0.8v-2.2h-0.8c-0.1-0.4,0.6-3.8-0.8-3v-2.2h-0.8c-0.1-0.4,0.6-3.8-0.8-3c-0.2-0.4,0.7-4.7-0.8-3.8c-0.2-0.4,0.7-4.7-0.8-3.8
c-0.2-0.4,0.7-4.7-0.8-3.8c0.1-3.6-1.1-8.2-0.8-12c-1.6-6.5-2.2-22.8-1.5-31.5c1.3,1.3,1.3-15.6,1.5-15.8
c1.4,0.9,0.5-4.1,0.8-4.5c1.4,0.9,0.5-4.1,0.8-4.5c11.2-53.6,47.1-102.2,101.2-129h2.2v-0.8h1.5v-0.8c0.4-0.2,3.8-0.4,3-1.5h2.2
V200h1.5c-0.5-1.1,1.7-0.7,2.2-0.8v-0.8h1.5c-0.9-1.4,4.1-1.1,4.5-1.5c19.3-8.3,58.8-13.4,84-8.2c0.3,0.8,6.3-1.2,5.2,0.8
c0.3,0.7,5.5-1.1,4.5,0.8c0.4,0.5,2.9-0.8,2.2,0.8c0.3,0.7,4.7-1,3.8,0.8c0.2,0.9,7.9-0.4,6.8,1.5c0.2,0.8,6.3-0.3,5.2,1.5
c0.4,0.5,3-0.8,2.2,0.8c0.4,0.5,3-0.8,2.2,0.8c0.4,0.5,3-0.8,2.2,0.8l4.5,0.8c-0.5,1.5,1,0.4,1.5,0.8c-0.8,1.8,5.3,0.4,4.5,2.2
c0.2,0.9,3.9-0.1,3,1.5c0.4,0.5,3-0.8,2.2,0.8c0.1,1,5.5,0.6,4.5,2.2c0.5,0.2,1.9-0.5,1.5,0.8c0.5,0.2,1.9-0.5,1.5,0.8
c0.5,0.2,1.9-0.6,1.5,0.8c0.5,0.2,1.9-0.6,1.5,0.8c2.5-0.3,0.5,1.1,3,0.8c0,1.8,4,2.6,5.2,3c-0.6,1.1,1.8,1.1,2.2,1.5l0.8,1.5
c0.2,0.8,3.9-0.1,3,1.5c1.2,0.2,2.6,0.8,3,2.2c1.3-0.4,2.5,1.1,3,2.2c1.3-0.4,2.5,1.1,3,2.2c1.3-0.4,2.5,1.1,3,2.2h1.5
c0.4,0.5,0.6,1.9,1.5,1.5c0.4,1.2,1,1.7,2.2,1.5c1.3,0.5,2.7,4.8,4.5,3.8l12,12.8c0.8,0.9,5.4,3.5,4.5,5.2
c1.1,0.8,4.4,2.8,3.8,4.5c1.2,0.6,3.4,2.2,3,3.8c1.1,0.6,2.6,1.4,2.2,3c3.6,1.7,1,2.8,3.8,3.8l0.8,2.2h0.8
c-0.6,1.5,0.6,1.7,1.5,2.2l0.8,2.2h0.8l1.5,4.5c1.8,0,2.5,4.1,3,5.2c1.5,0.2,2.1,2.5,2.2,3.8c1.7-0.8,1.3,5.3,3,4.5v2.2h0.8
c0.1,0.7-0.3,1.8,0.8,1.5l0.8,3c1.1-0.5,0.7,1.7,0.8,2.2c1.6-0.7,0.6,3.7,2.2,3c0.2,0.4,0.2,5.4,1.5,4.5
c0.1,0.7-0.3,1.8,0.8,1.5v2.2h0.8v2.2c1.1-0.5,0.7,1.7,0.8,2.2c1.3-0.7,0.6,2.5,0.8,3c1.1-0.5,0.7,1.7,0.8,2.2
c1.3-0.7,0.6,2.5,0.8,3c1.9-0.7-0.4,3.7,1.5,3C405.4,340,408.4,357.9,407.6,374.2z"/>
<path class="st0" d="M371.6,354v-6h-0.8v-5.2H370V339h-0.8v-3.8h-0.8l-0.8-6h-0.8v-3H366V324h-0.8v-2.2h-0.8v-2.2h-0.8l-0.8-4.5
H362v-1.5h-0.8v-2.2h-0.8l-1.5-4.5h-0.8v-1.5h-0.8v-1.5h-0.8v-1.5h-0.8v-1.5h-0.8v-1.5h-0.8v-1.5h-0.8v-1.5l-1.5-0.8l-0.8-3
h-0.8l-0.8-2.2l-1.5-0.8V288h-0.8l-0.8-2.2l-1.5-0.8v-1.5l-1.5-0.8l-0.8-2.2l-3-2.2v-1.5L335,273v-1.5l-4.5-3.8l-6.8-7.5h-1.5
l-4.5-5.2h-1.5l-2.2-3h-1.5l-1.5-2.2h-1.5l-1.5-2.2h-1.5l-0.8-1.5h-1.5l-0.8-1.5l-2.2-0.8V243l-3-0.8
c-20.9-13.2-47-20.7-81.8-20.2c-2.3,2-12,0.4-15.8,1.5c-3.6,1-8.6,1.9-12,3h-3l-18,6v0.8h-1.5v0.8h-2.2v0.8l-4.5,1.5v0.8h-1.5
v0.8h-1.5v0.8l-4.5,1.5l-0.8,1.5l-3,0.8l-0.8,1.5h-1.5v0.8h-1.5l-1.5,2.2h-1.5v0.8l-2.2,0.8l-0.8,1.5h-1.5l-0.8,1.5h-0.8
l-0.8,1.5h-1.5l-2.2,3h-1.5l-4.5,5.2h-1.5l-5.2,6l-3,2.2v1.5l-5.2,4.5v1.5l-1.5,0.8v0.8l-2.2,1.5v1.5l-2.2,1.5l-0.8,2.2
l-1.5,0.8v1.5l-1.5,0.8l-0.8,2.2h-0.8l-0.8,3l-1.5,0.8l-0.8,3l-1.5,0.8v1.5h-0.8v1.5h-0.8v1.5h-0.8v1.5h-0.8v1.5h-0.8v1.5h-0.8
l-1.5,4.5h-0.8v2.2H86v1.5h-0.8l-0.8,4.5h-0.8v2.2h-0.8v2.2H82v2.2h-0.8v3h-0.8l-0.8,6h-0.8l-0.8,7.5h-0.8l-0.8,13.5
c-0.8,2.9-1.8,20.1-0.8,24h0.8v7.5h0.8v5.2H78v4.5h0.8v3.8h0.8v3h0.8l0.8,6H82v2.2h0.8v2.2h0.8v2.2h0.8l0.8,4.5H86v1.5h0.8v2.2
h0.8l1.5,4.5h0.8v1.5h0.8v1.5h0.8v1.5h0.8v1.5h0.8v1.5h0.8v1.5h0.8v1.5h0.8l0.8,2.2l1.5,0.8l0.8,3h0.8l0.8,2.2l1.5,0.8v1.5
l2.2,1.5v1.5l2.2,1.5v1.5l2.2,1.5v1.5l5.2,4.5v1.5l4.5,3.8l7.5,8.2h1.5l3.8,4.5h1.5l2.2,3h1.5l1.5,2.2h1.5l0.8,1.5h1.5l1.5,2.2
h1.5l0.8,1.5l3,0.8l0.8,1.5l4.5,1.5l0.8,1.5l3,0.8v0.8h1.5v0.8l4.5,1.5v0.8h2.2v0.8h1.5v0.8h2.2v0.8h1.5v0.8l4.5,0.8v0.8h2.2
v0.8h2.2v0.8h2.2v0.8h3v0.8h3v0.8h3v0.8h3.8v0.8h3.8v0.8l12.8,0.8v0.8h25.5v-0.8h7.5V513h5.2v-0.8h4.5v-0.8l6.8-0.8V510h3v-0.8
l5.2-0.8v-0.8h2.2V507l4.5-0.8v-0.8h1.5v-0.8h2.2V504h1.5v-0.8l3.8-0.8v-0.8l4.5-1.5v-0.8h1.5v-0.8h1.5V498l4.5-1.5l0.8-1.5
l3-0.8l0.8-1.5h1.5l0.8-1.5h1.5v-0.8l2.2-0.8l0.8-1.5h1.5l1.5-2.2h1.5l2.2-3h1.5l2.2-3h1.5l8.2-9l7.5-6.8v-1.5l4.5-3.8v-1.5
l2.2-1.5l0.8-2.2l1.5-0.8v-1.5l1.5-0.8V449l2.2-1.5l0.8-3l1.5-0.8l0.8-2.2h0.8V440h0.8v-1.5h0.8V437h0.8v-1.5h0.8V434h0.8v-1.5
h0.8V431h0.8v-1.5h0.8l1.5-4.5h0.8v-2h0.8v-1.5h0.8l0.8-4.5c5.5-13.9,8.2-28.6,8.2-43.5V354H371.6z M326.6,402.8l-0.8,4.5
c-7.3,16.6-18.4,32.8-32.2,42.8l-3,3.8h-1.5l-0.8,1.5h-1.5l-1.5,2.2h-1.5l-0.8,1.5h-1.5l-0.8,1.5l-4.5,1.5l-0.8,1.5h-2.2
l-0.8,1.5h-1.5v0.8l-22.5,7.5h-4.5v0.8h-5.2v0.8h-14.2c-16.7,0-27.6-2.5-39-7.5h-2.2v-0.8l-4.5-1.5v-0.8h-1.5v-0.8h-1.5v-0.8
l-4.5-1.5v-0.8l-2.2-0.8l-0.8-1.5h-1.5v-0.8l-2.2-0.8l-0.8-1.5h-1.5l-0.8-1.5l-2.2-0.8l-3.8-4.5H154l-6.8-7.5l-4.5-3.8v-1.5
l-3-2.2V432l-2.2-1.5l-0.8-2.2l-1.5-0.8l-0.8-3l-1.5-0.8l-0.8-2.2h-0.8l-1.5-4.5H129v-1.5h-0.8V414h-0.8l-1.5-4.5h-0.8v-2.2
h-0.8v-1.5h-0.8v-2.2h-0.8v-2.2h-0.8v-3h-0.8v-3h-0.8v-3h-0.8v-4.5h-0.8v-4.5h-0.8v-9.8h-0.8v-11.2h0.8l0.8-13.5h0.8v-4.5h0.8
l0.8-6h0.8V336h0.8v-2.2h0.8v-2.2h0.8l0.8-4.5h0.8l1.5-4.5h0.8V321h0.8l1.5-4.5l1.5-0.8l0.8-3h0.8l0.8-2.2l1.5-0.8v-1.5l2.2-1.5
v-1.5l2.2-1.5v-1.5l5.2-4.5v-1.5l3-2.2l6-6.8h1.5l2.2-3h1.5l1.5-2.2h1.5l1.5-2.2h1.5l0.8-1.5l3-0.8l0.8-1.5l3-0.8l0.8-1.5
l6.8-2.2v-0.8l3-0.8v-0.8h2.2v-0.8h1.5v-0.8h2.2V267h2.2v-0.8l5.2-0.8v-0.8l7.5-0.8V263c3.2-1,10.7,0.2,12.8-1.5
c8.1,0,16.9-0.3,23.2,1.5h5.2l18.8,5.2v0.8h1.5v0.8h2.2v0.8l4.5,1.5v0.8h1.5v0.8l3,0.8l0.8,1.5l3,0.8l0.8,1.5l3,0.8l0.8,1.5
l2.2,0.8l1.5,2.2h1.5l3,3.8h1.5l3,3.8l7.5,6.8v1.5l3.8,3l0.8,2.2l1.5,0.8v1.5l2.2,1.5v1.5l1.5,0.8l0.8,2.2h0.8l1.5,4.5l1.5,0.8
l2.2,6.8h0.8l0.8,3h0.8v2.2C333.8,349.8,334.9,381.5,326.6,402.8z"/>
</g>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 17 KiB

1
src/img/pokeball.svg Normal file

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 74 KiB

357
userconfig.js Normal file
View file

@ -0,0 +1,357 @@
let saved_config = JSON.parse(localStorage.getItem("CONFIG"));
const default_config = {
overrideStorage: true,
temperature: {
location: 'Espoo, Finland',
scale: "C",
},
clock: {
format: "h:i p",
iconColor: "#ea6962",
},
search: {
engines: {
w: ["https://whoogle.no-logs.com/search?q=", "Whoogle"],
d: ["https://duckduckgo.com/html?q=", "DuckDuckGo"],
y: ["https://youtube.com/results?search_query=", "Youtube"],
r: ["https://www.reddit.com/search/?q=", "Reddit"],
},
},
keybindings: {
"s": "search-bar",
"q": "config-tab",
},
disabled: [],
localIcons: false,
fastlink: "https://chat.openai.com/",
openLastVisitedTab: true,
tabs: [
{
name: "chi ll",
background_url: "src/img/banners/cbg-2.gif",
categories: [{
name: "Social Media",
links: [
{
name: "discord",
url: "https://app.discord.com/",
icon: "brand-discord",
icon_color: "#a9b665",
},
{
name: "twitter",
url: "https://twitter.com/home",
icon: "brand-twitter-filled",
icon_color: "#7daea3",
},
{
name: "reddit",
url: "https://www.reddit.com/",
icon: "brand-reddit",
icon_color: "#e78a4e",
},
{
name: "mastodon",
url: "https://tech.lgbt/home/",
icon: "brand-mastodon",
icon_color: "#5B49E0"
},
],
}, {
name: "Games",
links: [
{
name: "chess",
url: "https://www.chess.com/home",
icon: "chess-queen-filled",
icon_color: "#a9b665",
},
{
name: "monkeytype",
url: "https://monkeytype.com/",
icon: "keyboard",
icon_color: "#e78a4e",
},
{
name: "tetris",
url: "https://tetris.com/",
icon: "brand-apple-arcade",
icon_color: "#ea6962",
},
],
}, {
name: "media",
links: [
{
name: "youtube",
url: "https://www.youtube.com/",
icon: "brand-youtube-filled",
icon_color: "#ea6962",
},
{
name: "anime",
url: "https://aniwave.to/home",
icon: "ripple",
icon_color: "#48257A",
},
{
name: "twitch",
url: "https://www.twitch.tv/",
icon: "brand-twitch",
icon_color: "#d3869b",
},
{
name: "spotify",
url: "https://open.spotify.com/",
icon: "brand-spotify",
icon_color: "#1ED760"
},
],
}],
},
{
name: "design",
background_url: "src/img/banners/cbg-6.gif",
categories: [
{
name: "inspiration",
links: [
{
name: "pinterest",
url: "https://www.pinterest.es/",
icon: "brand-pinterest",
icon_color: "#ea6962",
},
{
name: "artstation",
url: "https://www.artstation.com/?sort_by=community",
icon: "chart-area",
icon_color: "#7daea3",
},
{
name: "leonardo ai",
url: "https://app.leonardo.ai/",
icon: "brand-openai",
icon_color: "#89b482",
},
{
name: "dribble",
url: "https://dribbble.com/following",
icon: "brand-dribbble-filled",
icon_color: "#d3869b",
},
],
},
{
name: "resources",
links: [
{
name: "figma",
url: "https://www.figma.com",
icon: "brand-figma",
icon_color: "#d3869b",
},
{
name: "uxpro",
url: "https://uxpro.cc/",
icon: "components",
icon_color: "#a9b665",
},
{
name: "colorhunt",
url: "https://colorhunt.co/",
icon: "color-picker",
icon_color: "#ea6962",
},
{
name: "adobe color",
url: "https://color.adobe.com/es/create/color-wheel",
icon: "brand-adobe",
icon_color: "#7daea3",
},
{
name: "terminalsexy",
url: "https://terminal.sexy",
icon: "prompt",
icon_color: "#e78a4e",
},
],
},
{
name: "resources 3d",
links: [
{
name: "thingiverse",
url: "https://www.thingiverse.com/",
icon: "circle-letter-t",
icon_color: "#7daea3",
},
],
},
],
},
{
name: "dev",
background_url: "src/img/banners/cbg-7.gif",
categories: [
{
name: "repositories",
links: [
{
name: "github",
url: "https://github.com/",
icon: "brand-github",
icon_color: "#7daea3",
},
{
name: "gitlab",
url: "https://gitlab.com/",
icon: "brand-gitlab",
icon_color: "#e78a4e",
},
{
name: "haitea",
url: "https://git.blahai.gay/",
icon: "teapot",
icon_color: "#609926"
}
],
},
{
name: "resources",
links: [
{
name: "phind",
url: "https://www.phind.com/",
icon: "brand-openai",
icon_color: "#89b482",
},
{
name: "flutter",
url: "https://docs.flutter.dev/ui",
icon: "brand-flutter",
icon_color: "#7daea3",
},
{
name: "hacktricks",
url: "https://book.hacktricks.xyz/welcome/readme",
icon: "biohazard",
icon_color: "#ea6962",
},
{
name: "vscode",
url: "https://vscode.dev/",
icon: "brand-vscode",
icon_color: "#7daea3",
},
],
},
{
name: "challenges",
links: [
{
name: "hackthebox",
url: "https://app.hackthebox.com",
icon: "box",
icon_color: "#a9b665",
},
{
name: "cryptohack",
url: "https://cryptohack.org/challenges/",
icon: "brain",
icon_color: "#e78a4e",
},
{
name: "tryhackme",
url: "https://tryhackme.com/dashboard",
icon: "brand-onedrive",
icon_color: "#ea6962",
},
{
name: "hackerrank",
url: "https://www.hackerrank.com/dashboard",
icon: "code-asterix",
icon_color: "#a9b665",
},
],
},
],
},
{
name: "myself",
background_url: "src/img/banners/cbg-9.gif",
categories: [
{
name: "mails",
links: [
{
name: "gmail",
url: "https://mail.google.com/mail/u/0/",
icon: "brand-gmail",
icon_color: "#ea6962",
},
{
name: "protonmail",
url: "https://mail.proton.me/u/1/inbox",
icon: "brand-campaignmonitor",
icon_color: "#48257",
},
],
},
{
name: "storage",
links: [
{
name: "drive",
url: "https://drive.google.com/drive/u/0/my-drive",
icon: "brand-google-drive",
icon_color: "#e78a4e",
},
{
name: "fotos",
url: "https://photos.google.com/u/1",
icon: "photo-filled",
icon_color: "#ea6962",
},
],
},
{
name: "school",
links: [
{
name: "classroom",
url: "https://classroom.google.com/u/2/?pli=1",
icon: "chalkboard",
icon_color: "#7daea3",
},
{
name: "wilma",
url: "https://vantaa.inschool.fi/",
icon: "letter-w",
icon_color: "#7daea3",
},
{
name: "otava",
url: "https://opiskelija.otava.fi/",
icon: "star",
icon_color: "#7daea3",
},
],
},
],
},
],
};
const CONFIG = new Config(saved_config ?? default_config);
// const CONFIG = new Config(default_config);
(function() {
var css = document.createElement('link');
css.href = 'src/css/tabler-icons.min.css';
css.rel = 'stylesheet';
css.type = 'text/css';
if (!CONFIG.config.localIcons)
document.getElementsByTagName('head')[0].appendChild(css);
})();