jekyll build from Action a5e9a9ab01
0
.nojekyll
Normal file
659
404.html
Normal file
|
@ -0,0 +1,659 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
|
<meta name="google-translate-customization" content="108d9124921d80c3-80e20d618ff053c8-g4f02ec6f3dba68b7-c">
|
||||||
|
<!-- Begin Jekyll SEO tag v2.8.0 -->
|
||||||
|
<title>Matyáš Caras | Welcome to my website/blog, full of weird stuff written by yours truly.</title>
|
||||||
|
<meta name="generator" content="Jekyll v4.3.1">
|
||||||
|
<meta property="og:title" content="Matyáš Caras">
|
||||||
|
<meta name="author" content="hernikplays">
|
||||||
|
<meta property="og:locale" content="en_US">
|
||||||
|
<meta name="description" content="Welcome to my website/blog, full of weird stuff written by yours truly.">
|
||||||
|
<meta property="og:description" content="Welcome to my website/blog, full of weird stuff written by yours truly.">
|
||||||
|
<link rel="canonical" href="https://caras.cafe/404.html">
|
||||||
|
<meta property="og:url" content="https://caras.cafe/404.html">
|
||||||
|
<meta property="og:site_name" content="Matyáš Caras">
|
||||||
|
<meta property="og:type" content="website">
|
||||||
|
<meta name="twitter:card" content="summary">
|
||||||
|
<meta property="twitter:title" content="Matyáš Caras">
|
||||||
|
<script type="application/ld+json">
|
||||||
|
{"@context":"https://schema.org","@type":"WebPage","author":{"@type":"Person","name":"hernikplays"},"description":"Welcome to my website/blog, full of weird stuff written by yours truly.","headline":"Matyáš Caras","url":"https://caras.cafe/404.html"}</script>
|
||||||
|
<!-- End Jekyll SEO tag -->
|
||||||
|
<link rel="shortcut icon" href="">
|
||||||
|
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
|
||||||
|
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/typeface-noto-sans@0.0.72/index.min.css">
|
||||||
|
<link rel="stylesheet" href="/assets/css/main.css">
|
||||||
|
<script src="/assets/js/main.js"></script><link type="application/atom+xml" rel="alternate" href="https://caras.cafe/feed.xml" title="Matyáš Caras">
|
||||||
|
<link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/highlight.js/10.1.1/styles/default.min.css">
|
||||||
|
<script src="//cdnjs.cloudflare.com/ajax/libs/highlight.js/10.1.1/highlight.min.js"></script>
|
||||||
|
<!-- and it's easy to individually load additional languages -->
|
||||||
|
<script charset="UTF-8" src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.1.1/languages/go.min.js"></script>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<script>
|
||||||
|
// Init highlight js
|
||||||
|
document.addEventListener('DOMContentLoaded', function(event) {
|
||||||
|
var els = document.querySelectorAll('pre code')
|
||||||
|
|
||||||
|
function addLangData(block) {
|
||||||
|
var outer = block.parentElement.parentElement.parentElement;
|
||||||
|
var lang = block.getAttribute('data-lang');
|
||||||
|
for (var i = 0; i < outer.classList.length; i++) {
|
||||||
|
var cls = outer.classList[i];
|
||||||
|
if (cls.startsWith('language-')) {
|
||||||
|
lang = cls;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!lang) {
|
||||||
|
cls = block.getAttribute('class');
|
||||||
|
lang = cls ? cls.replace('hljs ', '') : '';
|
||||||
|
}
|
||||||
|
if (lang.startsWith('language-')) {
|
||||||
|
lang = lang.substr(9);
|
||||||
|
}
|
||||||
|
block.setAttribute('class', 'hljs ' + lang);
|
||||||
|
block.parentNode.setAttribute('data-lang', lang);
|
||||||
|
}
|
||||||
|
|
||||||
|
function addBadge(block) {
|
||||||
|
var enabled = ('true' || 'true').toLowerCase();
|
||||||
|
if (enabled == 'true') {
|
||||||
|
var pre = block.parentElement;
|
||||||
|
pre.classList.add('badge');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function handle(block) {
|
||||||
|
addLangData(block);
|
||||||
|
addBadge(block)
|
||||||
|
hljs.highlightBlock(block);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (var i = 0; i < els.length; i++) {
|
||||||
|
var el = els[i];
|
||||||
|
handle(el);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
/* code language badge */
|
||||||
|
pre.badge::before {
|
||||||
|
content: attr(data-lang);
|
||||||
|
color: #fff;
|
||||||
|
background-color: #ff4e00;
|
||||||
|
padding: 0 .5em;
|
||||||
|
border-radius: 0 2px;
|
||||||
|
text-transform: uppercase;
|
||||||
|
text-align: center;
|
||||||
|
min-width: 32px;
|
||||||
|
display: inline-block;
|
||||||
|
position: absolute;
|
||||||
|
right: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* fix wrong badge display for firefox browser */
|
||||||
|
code > table pre::before {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<header class="site-header " role="banner">
|
||||||
|
|
||||||
|
<div class="wrapper">
|
||||||
|
<div class="site-header-inner">
|
||||||
|
<span class="site-brand"><a class="site-brand-inner" rel="author" href="/">
|
||||||
|
<img class="site-favicon" title="Matyáš Caras" src="" onerror="this.style.display='none'">
|
||||||
|
Matyáš Caras
|
||||||
|
</a>
|
||||||
|
</span><nav class="site-nav">
|
||||||
|
<input type="checkbox" id="nav-trigger" class="nav-trigger">
|
||||||
|
<label for="nav-trigger">
|
||||||
|
<span class="menu-icon">
|
||||||
|
<svg viewbox="0 0 18 15" width="18px" height="15px">
|
||||||
|
<path d="M18,1.484c0,0.82-0.665,1.484-1.484,1.484H1.484C0.665,2.969,0,2.304,0,1.484l0,0C0,0.665,0.665,0,1.484,0 h15.032C17.335,0,18,0.665,18,1.484L18,1.484z M18,7.516C18,8.335,17.335,9,16.516,9H1.484C0.665,9,0,8.335,0,7.516l0,0 c0-0.82,0.665-1.484,1.484-1.484h15.032C17.335,6.031,18,6.696,18,7.516L18,7.516z M18,13.516C18,14.335,17.335,15,16.516,15H1.484 C0.665,15,0,14.335,0,13.516l0,0c0-0.82,0.665-1.483,1.484-1.483h15.032C17.335,12.031,18,12.695,18,13.516L18,13.516z"></path>
|
||||||
|
</svg>
|
||||||
|
</span>
|
||||||
|
</label>
|
||||||
|
|
||||||
|
<div class="trigger">
|
||||||
|
<a class="page-link" href="/about.html">ABOUT</a><a class="page-link" href="/archives.html">ARCHIVES</a><a class="page-link" href="/categories.html">CATEGORIES</a><a class="page-link" href="/">HOME</a><a class="page-link" href="/tags.html">TAGS</a>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</nav>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</header>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
function initHeader() {
|
||||||
|
var lastScrollY = getScrollPos().y;
|
||||||
|
var documentElement = document.documentElement;
|
||||||
|
|
||||||
|
function storeScrollData() {
|
||||||
|
var y = getScrollPos().y;var scrollStatus = "";
|
||||||
|
|
||||||
|
if (y <= 0) {
|
||||||
|
scrollStatus = "top";
|
||||||
|
} else if ((window.innerHeight + y) >= document.body.offsetHeight) {
|
||||||
|
scrollStatus = "bottom";
|
||||||
|
} else {
|
||||||
|
var isScrollDown = (y - lastScrollY > 0) ? true : false;
|
||||||
|
scrollStatus = isScrollDown ? "down" : "up";
|
||||||
|
}
|
||||||
|
|
||||||
|
lastScrollY = y;
|
||||||
|
documentElement.setAttribute("data-scroll-status", scrollStatus);
|
||||||
|
}
|
||||||
|
|
||||||
|
window.addEventListener('scroll', function(e) {
|
||||||
|
storeScrollData();
|
||||||
|
});
|
||||||
|
|
||||||
|
storeScrollData();
|
||||||
|
}
|
||||||
|
document.addEventListener('DOMContentLoaded', initHeader);
|
||||||
|
</script>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<script>
|
||||||
|
function hashLocate(hashValue) {
|
||||||
|
hashValue = hashValue.replace(/^.*#h-/, '');
|
||||||
|
hashValue = decodeURIComponent(hashValue);
|
||||||
|
var element = document.getElementById(hashValue);
|
||||||
|
|
||||||
|
if (!element) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var header = document.querySelector('header.site-header');
|
||||||
|
var headerRect = header.getBoundingClientRect();
|
||||||
|
var headerTop = Math.floor(headerRect.top);
|
||||||
|
var headerHeight = Math.floor(headerRect.height);
|
||||||
|
var scrollPos = getScrollPos();
|
||||||
|
var offsetY = element.offsetTop - (headerTop + headerHeight + 20);
|
||||||
|
|
||||||
|
if (offsetY == scrollPos.y) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (headerTop == 0 && offsetY > scrollPos.y) {
|
||||||
|
offsetY += headerHeight + 2;
|
||||||
|
} else if (headerTop < 0 && offsetY < scrollPos.y) {
|
||||||
|
offsetY -= headerHeight - 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
smoothScrollTo(offsetY);
|
||||||
|
}
|
||||||
|
|
||||||
|
// The first event occurred
|
||||||
|
window.addEventListener('load', function(event) {
|
||||||
|
if (window.location.hash) {
|
||||||
|
hashLocate(window.location.hash);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// The first event occurred
|
||||||
|
window.addEventListener('click', function(event) {
|
||||||
|
if (event.target.tagName.toLowerCase() == 'a') {
|
||||||
|
hashLocate(event.target.getAttribute('href'));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
<div class="theme-toggle">
|
||||||
|
<input type="checkbox" id="theme-switch">
|
||||||
|
<label for="theme-switch">
|
||||||
|
<div class="toggle"></div>
|
||||||
|
<div class="names">
|
||||||
|
<p class="light">Light</p>
|
||||||
|
<p class="dark">Dark</p>
|
||||||
|
</div>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<script>
|
||||||
|
(function() {
|
||||||
|
var sw = document.getElementById('theme-switch');
|
||||||
|
var html = document.getElementsByTagName('html')[0];
|
||||||
|
var nightModeOption = ('auto' || 'auto').toLowerCase();
|
||||||
|
var storage = nightModeOption === 'manual'
|
||||||
|
? localStorage
|
||||||
|
: sessionStorage;
|
||||||
|
var themeData = loadThemeData();
|
||||||
|
|
||||||
|
function saveThemeData(data) {
|
||||||
|
storage.setItem('theme', JSON.stringify(data));
|
||||||
|
}
|
||||||
|
|
||||||
|
function loadThemeData() {
|
||||||
|
var data = storage.getItem('theme');
|
||||||
|
try {
|
||||||
|
data = JSON.parse(data ? data : '');
|
||||||
|
} catch(e) {
|
||||||
|
data = { nightShift: undefined, autoToggleAt: 0 };
|
||||||
|
saveThemeData(data);
|
||||||
|
}
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleThemeToggle(nightShift) {
|
||||||
|
themeData.nightShift = nightShift;
|
||||||
|
saveThemeData(themeData);
|
||||||
|
html.dataset.theme = nightShift ? 'dark' : 'light';
|
||||||
|
setTimeout(function() {
|
||||||
|
sw.checked = nightShift ? true : false;
|
||||||
|
}, 50);
|
||||||
|
}
|
||||||
|
|
||||||
|
function autoThemeToggle() {
|
||||||
|
// Next time point of theme toggle
|
||||||
|
var now = new Date();
|
||||||
|
var toggleAt = new Date();
|
||||||
|
var hours = now.getHours();
|
||||||
|
var nightShift = hours >= 19 || hours <=7;
|
||||||
|
|
||||||
|
if (nightShift) {
|
||||||
|
if (hours > 7) {
|
||||||
|
toggleAt.setDate(toggleAt.getDate() + 1);
|
||||||
|
}
|
||||||
|
toggleAt.setHours(7);
|
||||||
|
} else {
|
||||||
|
toggleAt.setHours(19);
|
||||||
|
}
|
||||||
|
|
||||||
|
toggleAt.setMinutes(0);
|
||||||
|
toggleAt.setSeconds(0);
|
||||||
|
toggleAt.setMilliseconds(0)
|
||||||
|
|
||||||
|
var delay = toggleAt.getTime() - now.getTime();
|
||||||
|
|
||||||
|
// auto toggle theme mode
|
||||||
|
setTimeout(function() {
|
||||||
|
handleThemeToggle(!nightShift);
|
||||||
|
}, delay);
|
||||||
|
|
||||||
|
return {
|
||||||
|
nightShift: nightShift,
|
||||||
|
toggleAt: toggleAt.getTime()
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// Listen the theme toggle event
|
||||||
|
sw.addEventListener('change', function(event) {
|
||||||
|
handleThemeToggle(event.target.checked);
|
||||||
|
});
|
||||||
|
|
||||||
|
if (nightModeOption == 'auto') {
|
||||||
|
var data = autoThemeToggle();
|
||||||
|
|
||||||
|
// Toggle theme by local setting
|
||||||
|
if (data.toggleAt > themeData.autoToggleAt) {
|
||||||
|
themeData.autoToggleAt = data.toggleAt;
|
||||||
|
handleThemeToggle(data.nightShift);
|
||||||
|
} else {
|
||||||
|
handleThemeToggle(themeData.nightShift);
|
||||||
|
}
|
||||||
|
} else if (nightModeOption == 'manual') {
|
||||||
|
handleThemeToggle(themeData.nightShift);
|
||||||
|
} else {
|
||||||
|
var nightShift = themeData.nightShift;
|
||||||
|
if (nightShift === undefined) {
|
||||||
|
nightShift = nightModeOption === 'on';
|
||||||
|
}
|
||||||
|
handleThemeToggle(nightShift);
|
||||||
|
}
|
||||||
|
})();
|
||||||
|
</script>
|
||||||
|
<div id="click-to-top" class="click-to-top">
|
||||||
|
<i class="fa fa-arrow-up"></i>
|
||||||
|
</div>
|
||||||
|
<script>
|
||||||
|
(function () {
|
||||||
|
const clickToTop = document.getElementById('click-to-top');
|
||||||
|
window.addEventListener('scroll', () => {
|
||||||
|
if (window.scrollY > 100) {
|
||||||
|
clickToTop.classList.add('show')
|
||||||
|
}else {
|
||||||
|
clickToTop.classList.remove('show')
|
||||||
|
}
|
||||||
|
});
|
||||||
|
clickToTop.addEventListener('click', () => {
|
||||||
|
window.smoothScrollTo(0);
|
||||||
|
});
|
||||||
|
})();
|
||||||
|
</script>
|
||||||
|
<main class="page-content" aria-label="Content">
|
||||||
|
<div class="wrapper">
|
||||||
|
<style type="text/css" media="screen">
|
||||||
|
.container {
|
||||||
|
margin: 10px auto;
|
||||||
|
max-width: 600px;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
h1 {
|
||||||
|
margin: 30px 0;
|
||||||
|
font-size: 4em;
|
||||||
|
line-height: 1;
|
||||||
|
letter-spacing: -1px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<div class="container">
|
||||||
|
<h1>404</h1>
|
||||||
|
|
||||||
|
<p><strong>Page not found :(</strong></p>
|
||||||
|
<p>Try to check other pages through the menu. </p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</main><footer class="site-footer h-card">
|
||||||
|
<data class="u-url" href="/"></data>
|
||||||
|
|
||||||
|
<div class="wrapper">
|
||||||
|
<div class="site-footer-inner">
|
||||||
|
<div>Copyright © 2021-2022 hernikplays</div>
|
||||||
|
<div>Powered by <a title="Jekyll is a simple, blog-aware, static site
|
||||||
|
generator." href="https://jekyllrb.com/">Jekyll</a> & <a title="Yat, yet
|
||||||
|
another theme." href="https://github.com/jeffreytse/jekyll-theme-yat">Yat Theme</a>.</div>
|
||||||
|
<div><a rel="me" href="https://social.linux.pizza/@hernik">Mastodon</a></div>
|
||||||
|
<div class="footer-col rss-subscribe">Subscribe <a href="/feed.xml">via RSS</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</footer>
|
||||||
|
</body>
|
||||||
|
</html>
|
1
CNAME
Normal file
|
@ -0,0 +1 @@
|
||||||
|
caras.cafe
|
21
LICENSE.txt
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
The MIT License (MIT)
|
||||||
|
|
||||||
|
Copyright (c) 2019 Jeffrey Tse
|
||||||
|
|
||||||
|
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.
|
54
README.md
Normal file
|
@ -0,0 +1,54 @@
|
||||||
|
<div align="center">
|
||||||
|
<br>
|
||||||
|
|
||||||
|
<a href="https://github.com/jeffreytse/jekyll-theme-yat">
|
||||||
|
<img alt="jekyll-theme-yat →~ jekyll" src="https://user-images.githubusercontent.com/9413601/106478481-346fdf00-64e4-11eb-9385-1ab5329c3234.png" width="600">
|
||||||
|
</a>
|
||||||
|
|
||||||
|
<h1>JEKYLL YAT THEME</h1>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<h4 align="center">
|
||||||
|
<a href="https://jekyllrb.com/" target="_blank"><code>Jekyll</code></a> theme for elegant writers.
|
||||||
|
</h4>
|
||||||
|
|
||||||
|
<p align="center">
|
||||||
|
<a href="https://jeffreytse.github.io/jekyll-theme-yat">
|
||||||
|
<img src="https://github.com/jeffreytse/jekyll-theme-yat/workflows/Github%20Pages/badge.svg"
|
||||||
|
alt="Github Pages" />
|
||||||
|
</a>
|
||||||
|
|
||||||
|
<a href="https://badge.fury.io/rb/jekyll-theme-yat">
|
||||||
|
<img src="https://badge.fury.io/rb/jekyll-theme-yat.svg"
|
||||||
|
alt="Gem Version" />
|
||||||
|
</a>
|
||||||
|
|
||||||
|
<a href="https://opensource.org/licenses/MIT">
|
||||||
|
<img src="https://img.shields.io/badge/License-MIT-brightgreen.svg"
|
||||||
|
alt="License: MIT" />
|
||||||
|
</a>
|
||||||
|
|
||||||
|
<a href="https://liberapay.com/jeffreytse">
|
||||||
|
<img src="https://img.shields.io/liberapay/goal/jeffreytse.svg?logo=liberapay"
|
||||||
|
alt="Donate (Liberapay)" />
|
||||||
|
</a>
|
||||||
|
|
||||||
|
<a href="https://patreon.com/jeffreytse">
|
||||||
|
<img src="https://img.shields.io/badge/support-patreon-F96854.svg?style=flat-square"
|
||||||
|
alt="Donate (Patreon)" />
|
||||||
|
</a>
|
||||||
|
|
||||||
|
<a href="https://ko-fi.com/jeffreytse">
|
||||||
|
<img height="20" src="https://www.ko-fi.com/img/githubbutton_sm.svg"
|
||||||
|
alt="Donate (Ko-fi)" />
|
||||||
|
</a>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<div align="center">
|
||||||
|
<sub>Built with ❤︎ by
|
||||||
|
<a href="https://jeffreytse.net">jeffreytse</a> and
|
||||||
|
<a href="https://github.com/jeffreytse/jekyll-theme-yat/graphs/contributors">contributors </a>
|
||||||
|
</sub>
|
||||||
|
</div>
|
||||||
|
|
803
about.html
Normal file
|
@ -0,0 +1,803 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
|
<meta name="google-translate-customization" content="108d9124921d80c3-80e20d618ff053c8-g4f02ec6f3dba68b7-c">
|
||||||
|
<!-- Begin Jekyll SEO tag v2.8.0 -->
|
||||||
|
<title>About | Matyáš Caras</title>
|
||||||
|
<meta name="generator" content="Jekyll v4.3.1">
|
||||||
|
<meta property="og:title" content="About">
|
||||||
|
<meta name="author" content="hernikplays">
|
||||||
|
<meta property="og:locale" content="en_US">
|
||||||
|
<meta name="description" content="Welcome to my website/blog, full of weird stuff written by yours truly.">
|
||||||
|
<meta property="og:description" content="Welcome to my website/blog, full of weird stuff written by yours truly.">
|
||||||
|
<link rel="canonical" href="https://caras.cafe/about.html">
|
||||||
|
<meta property="og:url" content="https://caras.cafe/about.html">
|
||||||
|
<meta property="og:site_name" content="Matyáš Caras">
|
||||||
|
<meta property="og:type" content="website">
|
||||||
|
<meta name="twitter:card" content="summary">
|
||||||
|
<meta property="twitter:title" content="About">
|
||||||
|
<script type="application/ld+json">
|
||||||
|
{"@context":"https://schema.org","@type":"WebPage","author":{"@type":"Person","name":"hernikplays"},"description":"Welcome to my website/blog, full of weird stuff written by yours truly.","headline":"About","url":"https://caras.cafe/about.html"}</script>
|
||||||
|
<!-- End Jekyll SEO tag -->
|
||||||
|
<link rel="shortcut icon" href="">
|
||||||
|
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
|
||||||
|
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/typeface-noto-sans@0.0.72/index.min.css">
|
||||||
|
<link rel="stylesheet" href="/assets/css/main.css">
|
||||||
|
<script src="/assets/js/main.js"></script><link type="application/atom+xml" rel="alternate" href="https://caras.cafe/feed.xml" title="Matyáš Caras">
|
||||||
|
<link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/highlight.js/10.1.1/styles/default.min.css">
|
||||||
|
<script src="//cdnjs.cloudflare.com/ajax/libs/highlight.js/10.1.1/highlight.min.js"></script>
|
||||||
|
<!-- and it's easy to individually load additional languages -->
|
||||||
|
<script charset="UTF-8" src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.1.1/languages/go.min.js"></script>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<script>
|
||||||
|
// Init highlight js
|
||||||
|
document.addEventListener('DOMContentLoaded', function(event) {
|
||||||
|
var els = document.querySelectorAll('pre code')
|
||||||
|
|
||||||
|
function addLangData(block) {
|
||||||
|
var outer = block.parentElement.parentElement.parentElement;
|
||||||
|
var lang = block.getAttribute('data-lang');
|
||||||
|
for (var i = 0; i < outer.classList.length; i++) {
|
||||||
|
var cls = outer.classList[i];
|
||||||
|
if (cls.startsWith('language-')) {
|
||||||
|
lang = cls;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!lang) {
|
||||||
|
cls = block.getAttribute('class');
|
||||||
|
lang = cls ? cls.replace('hljs ', '') : '';
|
||||||
|
}
|
||||||
|
if (lang.startsWith('language-')) {
|
||||||
|
lang = lang.substr(9);
|
||||||
|
}
|
||||||
|
block.setAttribute('class', 'hljs ' + lang);
|
||||||
|
block.parentNode.setAttribute('data-lang', lang);
|
||||||
|
}
|
||||||
|
|
||||||
|
function addBadge(block) {
|
||||||
|
var enabled = ('true' || 'true').toLowerCase();
|
||||||
|
if (enabled == 'true') {
|
||||||
|
var pre = block.parentElement;
|
||||||
|
pre.classList.add('badge');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function handle(block) {
|
||||||
|
addLangData(block);
|
||||||
|
addBadge(block)
|
||||||
|
hljs.highlightBlock(block);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (var i = 0; i < els.length; i++) {
|
||||||
|
var el = els[i];
|
||||||
|
handle(el);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
/* code language badge */
|
||||||
|
pre.badge::before {
|
||||||
|
content: attr(data-lang);
|
||||||
|
color: #fff;
|
||||||
|
background-color: #ff4e00;
|
||||||
|
padding: 0 .5em;
|
||||||
|
border-radius: 0 2px;
|
||||||
|
text-transform: uppercase;
|
||||||
|
text-align: center;
|
||||||
|
min-width: 32px;
|
||||||
|
display: inline-block;
|
||||||
|
position: absolute;
|
||||||
|
right: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* fix wrong badge display for firefox browser */
|
||||||
|
code > table pre::before {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<header class="site-header " role="banner">
|
||||||
|
|
||||||
|
<div class="wrapper">
|
||||||
|
<div class="site-header-inner">
|
||||||
|
<span class="site-brand"><a class="site-brand-inner" rel="author" href="/">
|
||||||
|
<img class="site-favicon" title="Matyáš Caras" src="" onerror="this.style.display='none'">
|
||||||
|
Matyáš Caras
|
||||||
|
</a>
|
||||||
|
</span><nav class="site-nav">
|
||||||
|
<input type="checkbox" id="nav-trigger" class="nav-trigger">
|
||||||
|
<label for="nav-trigger">
|
||||||
|
<span class="menu-icon">
|
||||||
|
<svg viewbox="0 0 18 15" width="18px" height="15px">
|
||||||
|
<path d="M18,1.484c0,0.82-0.665,1.484-1.484,1.484H1.484C0.665,2.969,0,2.304,0,1.484l0,0C0,0.665,0.665,0,1.484,0 h15.032C17.335,0,18,0.665,18,1.484L18,1.484z M18,7.516C18,8.335,17.335,9,16.516,9H1.484C0.665,9,0,8.335,0,7.516l0,0 c0-0.82,0.665-1.484,1.484-1.484h15.032C17.335,6.031,18,6.696,18,7.516L18,7.516z M18,13.516C18,14.335,17.335,15,16.516,15H1.484 C0.665,15,0,14.335,0,13.516l0,0c0-0.82,0.665-1.483,1.484-1.483h15.032C17.335,12.031,18,12.695,18,13.516L18,13.516z"></path>
|
||||||
|
</svg>
|
||||||
|
</span>
|
||||||
|
</label>
|
||||||
|
|
||||||
|
<div class="trigger">
|
||||||
|
<a class="page-link" href="/about.html">ABOUT</a><a class="page-link" href="/archives.html">ARCHIVES</a><a class="page-link" href="/categories.html">CATEGORIES</a><a class="page-link" href="/">HOME</a><a class="page-link" href="/tags.html">TAGS</a>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</nav>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</header>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
function initHeader() {
|
||||||
|
var lastScrollY = getScrollPos().y;
|
||||||
|
var documentElement = document.documentElement;
|
||||||
|
|
||||||
|
function storeScrollData() {
|
||||||
|
var y = getScrollPos().y;var scrollStatus = "";
|
||||||
|
|
||||||
|
if (y <= 0) {
|
||||||
|
scrollStatus = "top";
|
||||||
|
} else if ((window.innerHeight + y) >= document.body.offsetHeight) {
|
||||||
|
scrollStatus = "bottom";
|
||||||
|
} else {
|
||||||
|
var isScrollDown = (y - lastScrollY > 0) ? true : false;
|
||||||
|
scrollStatus = isScrollDown ? "down" : "up";
|
||||||
|
}
|
||||||
|
|
||||||
|
lastScrollY = y;
|
||||||
|
documentElement.setAttribute("data-scroll-status", scrollStatus);
|
||||||
|
}
|
||||||
|
|
||||||
|
window.addEventListener('scroll', function(e) {
|
||||||
|
storeScrollData();
|
||||||
|
});
|
||||||
|
|
||||||
|
storeScrollData();
|
||||||
|
}
|
||||||
|
document.addEventListener('DOMContentLoaded', initHeader);
|
||||||
|
</script>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<script>
|
||||||
|
function hashLocate(hashValue) {
|
||||||
|
hashValue = hashValue.replace(/^.*#h-/, '');
|
||||||
|
hashValue = decodeURIComponent(hashValue);
|
||||||
|
var element = document.getElementById(hashValue);
|
||||||
|
|
||||||
|
if (!element) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var header = document.querySelector('header.site-header');
|
||||||
|
var headerRect = header.getBoundingClientRect();
|
||||||
|
var headerTop = Math.floor(headerRect.top);
|
||||||
|
var headerHeight = Math.floor(headerRect.height);
|
||||||
|
var scrollPos = getScrollPos();
|
||||||
|
var offsetY = element.offsetTop - (headerTop + headerHeight + 20);
|
||||||
|
|
||||||
|
if (offsetY == scrollPos.y) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (headerTop == 0 && offsetY > scrollPos.y) {
|
||||||
|
offsetY += headerHeight + 2;
|
||||||
|
} else if (headerTop < 0 && offsetY < scrollPos.y) {
|
||||||
|
offsetY -= headerHeight - 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
smoothScrollTo(offsetY);
|
||||||
|
}
|
||||||
|
|
||||||
|
// The first event occurred
|
||||||
|
window.addEventListener('load', function(event) {
|
||||||
|
if (window.location.hash) {
|
||||||
|
hashLocate(window.location.hash);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// The first event occurred
|
||||||
|
window.addEventListener('click', function(event) {
|
||||||
|
if (event.target.tagName.toLowerCase() == 'a') {
|
||||||
|
hashLocate(event.target.getAttribute('href'));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
<div class="theme-toggle">
|
||||||
|
<input type="checkbox" id="theme-switch">
|
||||||
|
<label for="theme-switch">
|
||||||
|
<div class="toggle"></div>
|
||||||
|
<div class="names">
|
||||||
|
<p class="light">Light</p>
|
||||||
|
<p class="dark">Dark</p>
|
||||||
|
</div>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<script>
|
||||||
|
(function() {
|
||||||
|
var sw = document.getElementById('theme-switch');
|
||||||
|
var html = document.getElementsByTagName('html')[0];
|
||||||
|
var nightModeOption = ('auto' || 'auto').toLowerCase();
|
||||||
|
var storage = nightModeOption === 'manual'
|
||||||
|
? localStorage
|
||||||
|
: sessionStorage;
|
||||||
|
var themeData = loadThemeData();
|
||||||
|
|
||||||
|
function saveThemeData(data) {
|
||||||
|
storage.setItem('theme', JSON.stringify(data));
|
||||||
|
}
|
||||||
|
|
||||||
|
function loadThemeData() {
|
||||||
|
var data = storage.getItem('theme');
|
||||||
|
try {
|
||||||
|
data = JSON.parse(data ? data : '');
|
||||||
|
} catch(e) {
|
||||||
|
data = { nightShift: undefined, autoToggleAt: 0 };
|
||||||
|
saveThemeData(data);
|
||||||
|
}
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleThemeToggle(nightShift) {
|
||||||
|
themeData.nightShift = nightShift;
|
||||||
|
saveThemeData(themeData);
|
||||||
|
html.dataset.theme = nightShift ? 'dark' : 'light';
|
||||||
|
setTimeout(function() {
|
||||||
|
sw.checked = nightShift ? true : false;
|
||||||
|
}, 50);
|
||||||
|
}
|
||||||
|
|
||||||
|
function autoThemeToggle() {
|
||||||
|
// Next time point of theme toggle
|
||||||
|
var now = new Date();
|
||||||
|
var toggleAt = new Date();
|
||||||
|
var hours = now.getHours();
|
||||||
|
var nightShift = hours >= 19 || hours <=7;
|
||||||
|
|
||||||
|
if (nightShift) {
|
||||||
|
if (hours > 7) {
|
||||||
|
toggleAt.setDate(toggleAt.getDate() + 1);
|
||||||
|
}
|
||||||
|
toggleAt.setHours(7);
|
||||||
|
} else {
|
||||||
|
toggleAt.setHours(19);
|
||||||
|
}
|
||||||
|
|
||||||
|
toggleAt.setMinutes(0);
|
||||||
|
toggleAt.setSeconds(0);
|
||||||
|
toggleAt.setMilliseconds(0)
|
||||||
|
|
||||||
|
var delay = toggleAt.getTime() - now.getTime();
|
||||||
|
|
||||||
|
// auto toggle theme mode
|
||||||
|
setTimeout(function() {
|
||||||
|
handleThemeToggle(!nightShift);
|
||||||
|
}, delay);
|
||||||
|
|
||||||
|
return {
|
||||||
|
nightShift: nightShift,
|
||||||
|
toggleAt: toggleAt.getTime()
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// Listen the theme toggle event
|
||||||
|
sw.addEventListener('change', function(event) {
|
||||||
|
handleThemeToggle(event.target.checked);
|
||||||
|
});
|
||||||
|
|
||||||
|
if (nightModeOption == 'auto') {
|
||||||
|
var data = autoThemeToggle();
|
||||||
|
|
||||||
|
// Toggle theme by local setting
|
||||||
|
if (data.toggleAt > themeData.autoToggleAt) {
|
||||||
|
themeData.autoToggleAt = data.toggleAt;
|
||||||
|
handleThemeToggle(data.nightShift);
|
||||||
|
} else {
|
||||||
|
handleThemeToggle(themeData.nightShift);
|
||||||
|
}
|
||||||
|
} else if (nightModeOption == 'manual') {
|
||||||
|
handleThemeToggle(themeData.nightShift);
|
||||||
|
} else {
|
||||||
|
var nightShift = themeData.nightShift;
|
||||||
|
if (nightShift === undefined) {
|
||||||
|
nightShift = nightModeOption === 'on';
|
||||||
|
}
|
||||||
|
handleThemeToggle(nightShift);
|
||||||
|
}
|
||||||
|
})();
|
||||||
|
</script>
|
||||||
|
<div id="click-to-top" class="click-to-top">
|
||||||
|
<i class="fa fa-arrow-up"></i>
|
||||||
|
</div>
|
||||||
|
<script>
|
||||||
|
(function () {
|
||||||
|
const clickToTop = document.getElementById('click-to-top');
|
||||||
|
window.addEventListener('scroll', () => {
|
||||||
|
if (window.scrollY > 100) {
|
||||||
|
clickToTop.classList.add('show')
|
||||||
|
}else {
|
||||||
|
clickToTop.classList.remove('show')
|
||||||
|
}
|
||||||
|
});
|
||||||
|
clickToTop.addEventListener('click', () => {
|
||||||
|
window.smoothScrollTo(0);
|
||||||
|
});
|
||||||
|
})();
|
||||||
|
</script>
|
||||||
|
<main class="page-content" aria-label="Content">
|
||||||
|
<div class="wrapper">
|
||||||
|
<div class="framework">
|
||||||
|
<section class="main">
|
||||||
|
|
||||||
|
<div class="post">
|
||||||
|
<section>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<article class="post h-entry" itemscope itemtype="http://schema.org/BlogPosting">
|
||||||
|
|
||||||
|
<div class="post-content e-content" itemprop="articleBody">
|
||||||
|
|
||||||
|
<h2>About</h2>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
I'm Matyáš Caras, I study IT in the Czech Republic and create software projects.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</article>
|
||||||
|
<div class="post-comments"> <div id="gitment_thread" class="giscus"></div>
|
||||||
|
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/theme-next/theme-next-gitment@1/default.css">
|
||||||
|
<script src="https://cdn.jsdelivr.net/gh/theme-next/theme-next-gitment@1/gitment.browser.js"></script>
|
||||||
|
<script src="https://giscus.app/client.js" data-repo="hernikplays/blog" data-repo-id="R_kgDOHr2B6w" data-category="General" data-category-id="DIC_kwDOHr2B684CSIhA" data-mapping="pathname" data-strict="0" data-reactions-enabled="1" data-emit-metadata="0" data-input-position="top" data-theme="transparent_dark" data-lang="en" data-loading="lazy" crossorigin="anonymous" async>
|
||||||
|
</script>
|
||||||
|
</div></section>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
</section>
|
||||||
|
<section class="sidebar" style="margin-left: 15px;">
|
||||||
|
<!-- Get sidebar items --><style type="text/css" media="screen">
|
||||||
|
.post-menu ul {
|
||||||
|
list-style: none;
|
||||||
|
padding: 0;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<div class="post-menu">
|
||||||
|
<div class="post-menu-title">TOC</div>
|
||||||
|
<div class="post-menu-content"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
function generateContent() {
|
||||||
|
var menu = document.querySelector(".post-menu");
|
||||||
|
var menuContent = menu.querySelector(".post-menu-content");
|
||||||
|
var headings = document.querySelector(".post-content").querySelectorAll("h2, h3, h4, h5, h6");
|
||||||
|
|
||||||
|
// Hide menu when no headings
|
||||||
|
if (headings.length === 0) {
|
||||||
|
return menu.style.display = "none";
|
||||||
|
}
|
||||||
|
|
||||||
|
// Generate post menu
|
||||||
|
var menuHTML = '';
|
||||||
|
for (var i = 0; i < headings.length; i++) {
|
||||||
|
var h = headings[i];
|
||||||
|
menuHTML += (
|
||||||
|
'<li class="h-' + h.tagName.toLowerCase() + '">'
|
||||||
|
+ '<a href="#h-' + h.getAttribute('id') + '">' + h.textContent + '</a></li>');
|
||||||
|
}
|
||||||
|
|
||||||
|
menuContent.innerHTML = '<ul>' + menuHTML + '</ul>';
|
||||||
|
|
||||||
|
// The header element
|
||||||
|
var header = document.querySelector('header.site-header');
|
||||||
|
|
||||||
|
function doMenuCollapse(index, over_items) {
|
||||||
|
var items = menuContent.firstChild.children;
|
||||||
|
|
||||||
|
if (over_items == undefined) {
|
||||||
|
over_items = 20;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (items.length < over_items) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var activeItem = items[index];
|
||||||
|
var beginItem = activeItem
|
||||||
|
var endItem = activeItem
|
||||||
|
var beginIndex = index;
|
||||||
|
var endIndex = index + 1;
|
||||||
|
while (beginIndex >= 0
|
||||||
|
&& !items[beginIndex].classList.contains('h-h2')) {
|
||||||
|
beginIndex -= 1;
|
||||||
|
}
|
||||||
|
while (endIndex < items.length
|
||||||
|
&& !items[endIndex].classList.contains('h-h2')) {
|
||||||
|
endIndex += 1;
|
||||||
|
}
|
||||||
|
for (var i = 0; i < beginIndex; i++) {
|
||||||
|
item = items[i]
|
||||||
|
if (!item.classList.contains('h-h2')) {
|
||||||
|
item.style.display = 'none';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (var i = beginIndex + 1; i < endIndex; i++) {
|
||||||
|
item = items[i]
|
||||||
|
// if (!item.classList.contains('h-h2')) {
|
||||||
|
item.style.display = '';
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
for (var i = endIndex; i < items.length; i++) {
|
||||||
|
item = items[i]
|
||||||
|
if (!item.classList.contains('h-h2')) {
|
||||||
|
item.style.display = 'none';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Init menu collapsed
|
||||||
|
doMenuCollapse(-1);
|
||||||
|
|
||||||
|
// Active the menu item
|
||||||
|
window.addEventListener('scroll', function (event) {
|
||||||
|
var lastActive = menuContent.querySelector('.active');
|
||||||
|
var changed = true;
|
||||||
|
var activeIndex = -1;
|
||||||
|
for (var i = headings.length - 1; i >= 0; i--) {
|
||||||
|
var h = headings[i];
|
||||||
|
var headingRect = h.getBoundingClientRect();
|
||||||
|
var headerRect = header.getBoundingClientRect();
|
||||||
|
var headerTop = Math.floor(headerRect.top);
|
||||||
|
var headerHeight = Math.floor(headerRect.height);
|
||||||
|
var headerHeight = headerTop + headerHeight + 20;
|
||||||
|
if (headingRect.top <= headerHeight) {
|
||||||
|
var id = 'h-' + h.getAttribute('id');
|
||||||
|
var a = menuContent.querySelector('a[href="#' + id + '"]');
|
||||||
|
var curActive = a.parentNode;
|
||||||
|
if (curActive) {
|
||||||
|
curActive.classList.add('active');
|
||||||
|
activeIndex = i;
|
||||||
|
}
|
||||||
|
if (lastActive == curActive) {
|
||||||
|
changed = false;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (changed) {
|
||||||
|
if (lastActive) {
|
||||||
|
lastActive.classList.remove('active');
|
||||||
|
}
|
||||||
|
doMenuCollapse(activeIndex);
|
||||||
|
}
|
||||||
|
event.preventDefault();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
generateContent();
|
||||||
|
</script>
|
||||||
|
</section>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</main><footer class="site-footer h-card">
|
||||||
|
<data class="u-url" href="/"></data>
|
||||||
|
|
||||||
|
<div class="wrapper">
|
||||||
|
<div class="site-footer-inner">
|
||||||
|
<div>Copyright © 2021-2022 hernikplays</div>
|
||||||
|
<div>Powered by <a title="Jekyll is a simple, blog-aware, static site
|
||||||
|
generator." href="https://jekyllrb.com/">Jekyll</a> & <a title="Yat, yet
|
||||||
|
another theme." href="https://github.com/jeffreytse/jekyll-theme-yat">Yat Theme</a>.</div>
|
||||||
|
<div><a rel="me" href="https://social.linux.pizza/@hernik">Mastodon</a></div>
|
||||||
|
<div class="footer-col rss-subscribe">Subscribe <a href="/feed.xml">via RSS</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</footer>
|
||||||
|
</body>
|
||||||
|
</html>
|
772
archives.html
Normal file
|
@ -0,0 +1,772 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
|
<meta name="google-translate-customization" content="108d9124921d80c3-80e20d618ff053c8-g4f02ec6f3dba68b7-c">
|
||||||
|
<!-- Begin Jekyll SEO tag v2.8.0 -->
|
||||||
|
<title>Archives | Matyáš Caras</title>
|
||||||
|
<meta name="generator" content="Jekyll v4.3.1">
|
||||||
|
<meta property="og:title" content="Archives">
|
||||||
|
<meta name="author" content="hernikplays">
|
||||||
|
<meta property="og:locale" content="en_US">
|
||||||
|
<meta name="description" content="Welcome to my website/blog, full of weird stuff written by yours truly.">
|
||||||
|
<meta property="og:description" content="Welcome to my website/blog, full of weird stuff written by yours truly.">
|
||||||
|
<link rel="canonical" href="https://caras.cafe/archives.html">
|
||||||
|
<meta property="og:url" content="https://caras.cafe/archives.html">
|
||||||
|
<meta property="og:site_name" content="Matyáš Caras">
|
||||||
|
<meta property="og:type" content="website">
|
||||||
|
<meta name="twitter:card" content="summary">
|
||||||
|
<meta property="twitter:title" content="Archives">
|
||||||
|
<script type="application/ld+json">
|
||||||
|
{"@context":"https://schema.org","@type":"WebPage","author":{"@type":"Person","name":"hernikplays"},"description":"Welcome to my website/blog, full of weird stuff written by yours truly.","headline":"Archives","url":"https://caras.cafe/archives.html"}</script>
|
||||||
|
<!-- End Jekyll SEO tag -->
|
||||||
|
<link rel="shortcut icon" href="">
|
||||||
|
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
|
||||||
|
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/typeface-noto-sans@0.0.72/index.min.css">
|
||||||
|
<link rel="stylesheet" href="/assets/css/main.css">
|
||||||
|
<script src="/assets/js/main.js"></script><link type="application/atom+xml" rel="alternate" href="https://caras.cafe/feed.xml" title="Matyáš Caras">
|
||||||
|
<link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/highlight.js/10.1.1/styles/default.min.css">
|
||||||
|
<script src="//cdnjs.cloudflare.com/ajax/libs/highlight.js/10.1.1/highlight.min.js"></script>
|
||||||
|
<!-- and it's easy to individually load additional languages -->
|
||||||
|
<script charset="UTF-8" src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.1.1/languages/go.min.js"></script>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<script>
|
||||||
|
// Init highlight js
|
||||||
|
document.addEventListener('DOMContentLoaded', function(event) {
|
||||||
|
var els = document.querySelectorAll('pre code')
|
||||||
|
|
||||||
|
function addLangData(block) {
|
||||||
|
var outer = block.parentElement.parentElement.parentElement;
|
||||||
|
var lang = block.getAttribute('data-lang');
|
||||||
|
for (var i = 0; i < outer.classList.length; i++) {
|
||||||
|
var cls = outer.classList[i];
|
||||||
|
if (cls.startsWith('language-')) {
|
||||||
|
lang = cls;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!lang) {
|
||||||
|
cls = block.getAttribute('class');
|
||||||
|
lang = cls ? cls.replace('hljs ', '') : '';
|
||||||
|
}
|
||||||
|
if (lang.startsWith('language-')) {
|
||||||
|
lang = lang.substr(9);
|
||||||
|
}
|
||||||
|
block.setAttribute('class', 'hljs ' + lang);
|
||||||
|
block.parentNode.setAttribute('data-lang', lang);
|
||||||
|
}
|
||||||
|
|
||||||
|
function addBadge(block) {
|
||||||
|
var enabled = ('true' || 'true').toLowerCase();
|
||||||
|
if (enabled == 'true') {
|
||||||
|
var pre = block.parentElement;
|
||||||
|
pre.classList.add('badge');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function handle(block) {
|
||||||
|
addLangData(block);
|
||||||
|
addBadge(block)
|
||||||
|
hljs.highlightBlock(block);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (var i = 0; i < els.length; i++) {
|
||||||
|
var el = els[i];
|
||||||
|
handle(el);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
/* code language badge */
|
||||||
|
pre.badge::before {
|
||||||
|
content: attr(data-lang);
|
||||||
|
color: #fff;
|
||||||
|
background-color: #ff4e00;
|
||||||
|
padding: 0 .5em;
|
||||||
|
border-radius: 0 2px;
|
||||||
|
text-transform: uppercase;
|
||||||
|
text-align: center;
|
||||||
|
min-width: 32px;
|
||||||
|
display: inline-block;
|
||||||
|
position: absolute;
|
||||||
|
right: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* fix wrong badge display for firefox browser */
|
||||||
|
code > table pre::before {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<header class="site-header " role="banner">
|
||||||
|
|
||||||
|
<div class="wrapper">
|
||||||
|
<div class="site-header-inner">
|
||||||
|
<span class="site-brand"><a class="site-brand-inner" rel="author" href="/">
|
||||||
|
<img class="site-favicon" title="Matyáš Caras" src="" onerror="this.style.display='none'">
|
||||||
|
Matyáš Caras
|
||||||
|
</a>
|
||||||
|
</span><nav class="site-nav">
|
||||||
|
<input type="checkbox" id="nav-trigger" class="nav-trigger">
|
||||||
|
<label for="nav-trigger">
|
||||||
|
<span class="menu-icon">
|
||||||
|
<svg viewbox="0 0 18 15" width="18px" height="15px">
|
||||||
|
<path d="M18,1.484c0,0.82-0.665,1.484-1.484,1.484H1.484C0.665,2.969,0,2.304,0,1.484l0,0C0,0.665,0.665,0,1.484,0 h15.032C17.335,0,18,0.665,18,1.484L18,1.484z M18,7.516C18,8.335,17.335,9,16.516,9H1.484C0.665,9,0,8.335,0,7.516l0,0 c0-0.82,0.665-1.484,1.484-1.484h15.032C17.335,6.031,18,6.696,18,7.516L18,7.516z M18,13.516C18,14.335,17.335,15,16.516,15H1.484 C0.665,15,0,14.335,0,13.516l0,0c0-0.82,0.665-1.483,1.484-1.483h15.032C17.335,12.031,18,12.695,18,13.516L18,13.516z"></path>
|
||||||
|
</svg>
|
||||||
|
</span>
|
||||||
|
</label>
|
||||||
|
|
||||||
|
<div class="trigger">
|
||||||
|
<a class="page-link" href="/about.html">ABOUT</a><a class="page-link" href="/archives.html">ARCHIVES</a><a class="page-link" href="/categories.html">CATEGORIES</a><a class="page-link" href="/">HOME</a><a class="page-link" href="/tags.html">TAGS</a>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</nav>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</header>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
function initHeader() {
|
||||||
|
var lastScrollY = getScrollPos().y;
|
||||||
|
var documentElement = document.documentElement;
|
||||||
|
|
||||||
|
function storeScrollData() {
|
||||||
|
var y = getScrollPos().y;var scrollStatus = "";
|
||||||
|
|
||||||
|
if (y <= 0) {
|
||||||
|
scrollStatus = "top";
|
||||||
|
} else if ((window.innerHeight + y) >= document.body.offsetHeight) {
|
||||||
|
scrollStatus = "bottom";
|
||||||
|
} else {
|
||||||
|
var isScrollDown = (y - lastScrollY > 0) ? true : false;
|
||||||
|
scrollStatus = isScrollDown ? "down" : "up";
|
||||||
|
}
|
||||||
|
|
||||||
|
lastScrollY = y;
|
||||||
|
documentElement.setAttribute("data-scroll-status", scrollStatus);
|
||||||
|
}
|
||||||
|
|
||||||
|
window.addEventListener('scroll', function(e) {
|
||||||
|
storeScrollData();
|
||||||
|
});
|
||||||
|
|
||||||
|
storeScrollData();
|
||||||
|
}
|
||||||
|
document.addEventListener('DOMContentLoaded', initHeader);
|
||||||
|
</script>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<script>
|
||||||
|
function hashLocate(hashValue) {
|
||||||
|
hashValue = hashValue.replace(/^.*#h-/, '');
|
||||||
|
hashValue = decodeURIComponent(hashValue);
|
||||||
|
var element = document.getElementById(hashValue);
|
||||||
|
|
||||||
|
if (!element) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var header = document.querySelector('header.site-header');
|
||||||
|
var headerRect = header.getBoundingClientRect();
|
||||||
|
var headerTop = Math.floor(headerRect.top);
|
||||||
|
var headerHeight = Math.floor(headerRect.height);
|
||||||
|
var scrollPos = getScrollPos();
|
||||||
|
var offsetY = element.offsetTop - (headerTop + headerHeight + 20);
|
||||||
|
|
||||||
|
if (offsetY == scrollPos.y) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (headerTop == 0 && offsetY > scrollPos.y) {
|
||||||
|
offsetY += headerHeight + 2;
|
||||||
|
} else if (headerTop < 0 && offsetY < scrollPos.y) {
|
||||||
|
offsetY -= headerHeight - 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
smoothScrollTo(offsetY);
|
||||||
|
}
|
||||||
|
|
||||||
|
// The first event occurred
|
||||||
|
window.addEventListener('load', function(event) {
|
||||||
|
if (window.location.hash) {
|
||||||
|
hashLocate(window.location.hash);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// The first event occurred
|
||||||
|
window.addEventListener('click', function(event) {
|
||||||
|
if (event.target.tagName.toLowerCase() == 'a') {
|
||||||
|
hashLocate(event.target.getAttribute('href'));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
<div class="theme-toggle">
|
||||||
|
<input type="checkbox" id="theme-switch">
|
||||||
|
<label for="theme-switch">
|
||||||
|
<div class="toggle"></div>
|
||||||
|
<div class="names">
|
||||||
|
<p class="light">Light</p>
|
||||||
|
<p class="dark">Dark</p>
|
||||||
|
</div>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<script>
|
||||||
|
(function() {
|
||||||
|
var sw = document.getElementById('theme-switch');
|
||||||
|
var html = document.getElementsByTagName('html')[0];
|
||||||
|
var nightModeOption = ('auto' || 'auto').toLowerCase();
|
||||||
|
var storage = nightModeOption === 'manual'
|
||||||
|
? localStorage
|
||||||
|
: sessionStorage;
|
||||||
|
var themeData = loadThemeData();
|
||||||
|
|
||||||
|
function saveThemeData(data) {
|
||||||
|
storage.setItem('theme', JSON.stringify(data));
|
||||||
|
}
|
||||||
|
|
||||||
|
function loadThemeData() {
|
||||||
|
var data = storage.getItem('theme');
|
||||||
|
try {
|
||||||
|
data = JSON.parse(data ? data : '');
|
||||||
|
} catch(e) {
|
||||||
|
data = { nightShift: undefined, autoToggleAt: 0 };
|
||||||
|
saveThemeData(data);
|
||||||
|
}
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleThemeToggle(nightShift) {
|
||||||
|
themeData.nightShift = nightShift;
|
||||||
|
saveThemeData(themeData);
|
||||||
|
html.dataset.theme = nightShift ? 'dark' : 'light';
|
||||||
|
setTimeout(function() {
|
||||||
|
sw.checked = nightShift ? true : false;
|
||||||
|
}, 50);
|
||||||
|
}
|
||||||
|
|
||||||
|
function autoThemeToggle() {
|
||||||
|
// Next time point of theme toggle
|
||||||
|
var now = new Date();
|
||||||
|
var toggleAt = new Date();
|
||||||
|
var hours = now.getHours();
|
||||||
|
var nightShift = hours >= 19 || hours <=7;
|
||||||
|
|
||||||
|
if (nightShift) {
|
||||||
|
if (hours > 7) {
|
||||||
|
toggleAt.setDate(toggleAt.getDate() + 1);
|
||||||
|
}
|
||||||
|
toggleAt.setHours(7);
|
||||||
|
} else {
|
||||||
|
toggleAt.setHours(19);
|
||||||
|
}
|
||||||
|
|
||||||
|
toggleAt.setMinutes(0);
|
||||||
|
toggleAt.setSeconds(0);
|
||||||
|
toggleAt.setMilliseconds(0)
|
||||||
|
|
||||||
|
var delay = toggleAt.getTime() - now.getTime();
|
||||||
|
|
||||||
|
// auto toggle theme mode
|
||||||
|
setTimeout(function() {
|
||||||
|
handleThemeToggle(!nightShift);
|
||||||
|
}, delay);
|
||||||
|
|
||||||
|
return {
|
||||||
|
nightShift: nightShift,
|
||||||
|
toggleAt: toggleAt.getTime()
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// Listen the theme toggle event
|
||||||
|
sw.addEventListener('change', function(event) {
|
||||||
|
handleThemeToggle(event.target.checked);
|
||||||
|
});
|
||||||
|
|
||||||
|
if (nightModeOption == 'auto') {
|
||||||
|
var data = autoThemeToggle();
|
||||||
|
|
||||||
|
// Toggle theme by local setting
|
||||||
|
if (data.toggleAt > themeData.autoToggleAt) {
|
||||||
|
themeData.autoToggleAt = data.toggleAt;
|
||||||
|
handleThemeToggle(data.nightShift);
|
||||||
|
} else {
|
||||||
|
handleThemeToggle(themeData.nightShift);
|
||||||
|
}
|
||||||
|
} else if (nightModeOption == 'manual') {
|
||||||
|
handleThemeToggle(themeData.nightShift);
|
||||||
|
} else {
|
||||||
|
var nightShift = themeData.nightShift;
|
||||||
|
if (nightShift === undefined) {
|
||||||
|
nightShift = nightModeOption === 'on';
|
||||||
|
}
|
||||||
|
handleThemeToggle(nightShift);
|
||||||
|
}
|
||||||
|
})();
|
||||||
|
</script>
|
||||||
|
<div id="click-to-top" class="click-to-top">
|
||||||
|
<i class="fa fa-arrow-up"></i>
|
||||||
|
</div>
|
||||||
|
<script>
|
||||||
|
(function () {
|
||||||
|
const clickToTop = document.getElementById('click-to-top');
|
||||||
|
window.addEventListener('scroll', () => {
|
||||||
|
if (window.scrollY > 100) {
|
||||||
|
clickToTop.classList.add('show')
|
||||||
|
}else {
|
||||||
|
clickToTop.classList.remove('show')
|
||||||
|
}
|
||||||
|
});
|
||||||
|
clickToTop.addEventListener('click', () => {
|
||||||
|
window.smoothScrollTo(0);
|
||||||
|
});
|
||||||
|
})();
|
||||||
|
</script>
|
||||||
|
<main class="page-content" aria-label="Content">
|
||||||
|
<div class="wrapper">
|
||||||
|
<div class="framework">
|
||||||
|
<section class="main">
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<div class="page-segments">
|
||||||
|
<ul class="page-segments-list">
|
||||||
|
|
||||||
|
<h2 id="2022" class="segment-name">2022</h2>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<li>
|
||||||
|
<span class="post-meta">Oct 22, 2022</span>
|
||||||
|
<span>
|
||||||
|
<a class="post-link" href="/tutori%C3%A1l/2022/10/22/rpi-arch.html">
|
||||||
|
Instalujeme Arch Linux ARM na Raspberry Pi 3
|
||||||
|
</a>
|
||||||
|
</span>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<li>
|
||||||
|
<span class="post-meta">Jul 19, 2022</span>
|
||||||
|
<span>
|
||||||
|
<a class="post-link" href="/bezpe%C4%8D%C3%AD/2022/07/19/nordvpn.html">
|
||||||
|
NordVPN - Jste opravdu v takovém nebezpečí?
|
||||||
|
</a>
|
||||||
|
</span>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<li>
|
||||||
|
<span class="post-meta">May 31, 2022</span>
|
||||||
|
<span>
|
||||||
|
<a class="post-link" href="/vychyt%C3%A1vky/2022/05/31/codespaces.html">
|
||||||
|
GitHub Codespaces aneb VS Code na VPS
|
||||||
|
</a>
|
||||||
|
</span>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<li>
|
||||||
|
<span class="post-meta">May 22, 2022</span>
|
||||||
|
<span>
|
||||||
|
<a class="post-link" href="/programov%C3%A1n%C3%AD/2022/05/22/automatizace.html">
|
||||||
|
Automatizace, automatizace, automatizace
|
||||||
|
</a>
|
||||||
|
</span>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
</section>
|
||||||
|
<section class="sidebar" style="margin-left: 15px;">
|
||||||
|
<!-- Get sidebar items -->
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<div class="common-list">
|
||||||
|
<ul>
|
||||||
|
<li>
|
||||||
|
<a href="/index.html">
|
||||||
|
All<span>4</span>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
|
||||||
|
<li>
|
||||||
|
<a href="/archives.html#h-2022">
|
||||||
|
2022 <span>4</span>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</section>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</main><footer class="site-footer h-card">
|
||||||
|
<data class="u-url" href="/"></data>
|
||||||
|
|
||||||
|
<div class="wrapper">
|
||||||
|
<div class="site-footer-inner">
|
||||||
|
<div>Copyright © 2021-2022 hernikplays</div>
|
||||||
|
<div>Powered by <a title="Jekyll is a simple, blog-aware, static site
|
||||||
|
generator." href="https://jekyllrb.com/">Jekyll</a> & <a title="Yat, yet
|
||||||
|
another theme." href="https://github.com/jeffreytse/jekyll-theme-yat">Yat Theme</a>.</div>
|
||||||
|
<div><a rel="me" href="https://social.linux.pizza/@hernik">Mastodon</a></div>
|
||||||
|
<div class="footer-col rss-subscribe">Subscribe <a href="/feed.xml">via RSS</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</footer>
|
||||||
|
</body>
|
||||||
|
</html>
|
573
assets/css/main.css
Normal file
|
@ -0,0 +1,573 @@
|
||||||
|
/** Reset some basic elements */
|
||||||
|
body, h1, h2, h3, h4, h5, h6, p, blockquote, pre, hr, dl, dd, ol, ul, figure { margin: 0; padding: 0; }
|
||||||
|
|
||||||
|
/** Basic styling */
|
||||||
|
body { font-family: Helvetica, Arial, Oswald, sans-serif; font-weight: 400; font-size: 14px; font-display: swap; line-height: 1.6; color: #454545; background-color: #fff; -webkit-text-size-adjust: 100%; -webkit-font-feature-settings: "kern" 1; -moz-font-feature-settings: "kern" 1; -o-font-feature-settings: "kern" 1; font-feature-settings: "kern" 1; font-kerning: normal; display: flex; min-height: 100vh; flex-direction: column; }
|
||||||
|
|
||||||
|
/** Set `margin-bottom` to maintain vertical rhythm */
|
||||||
|
h1, h2, h3, h4, h5, h6, p, blockquote, pre, ul, ol, dl, figure { margin-bottom: 15px; }
|
||||||
|
|
||||||
|
/** `main` element */
|
||||||
|
main { display: block; /* Default value of `display` of `main` element is 'inline' in IE 11. */ }
|
||||||
|
|
||||||
|
/** Images */
|
||||||
|
img { max-width: 100%; vertical-align: middle; }
|
||||||
|
|
||||||
|
/** Figures */
|
||||||
|
figure > img { display: block; }
|
||||||
|
|
||||||
|
figcaption { font-size: 12.25px; }
|
||||||
|
|
||||||
|
/** Lists */
|
||||||
|
ul, ol { margin-left: 30px; }
|
||||||
|
|
||||||
|
li > ul, li > ol { margin-bottom: 0; }
|
||||||
|
|
||||||
|
/** Headings */
|
||||||
|
h1, h2, h3, h4, h5, h6 { font-weight: 600; }
|
||||||
|
|
||||||
|
/** Links */
|
||||||
|
a { color: #ff5100; text-decoration: none; }
|
||||||
|
|
||||||
|
a:hover { text-decoration: underline; }
|
||||||
|
|
||||||
|
.social-media-list a:hover { text-decoration: none; }
|
||||||
|
|
||||||
|
.social-media-list a:hover .username { text-decoration: underline; }
|
||||||
|
|
||||||
|
/** Blockquotes */
|
||||||
|
blockquote { color: #828282; border-left: 4px solid #e8e8e8; padding-left: 15px; font-size: 15.75px; letter-spacing: -1px; font-style: italic; }
|
||||||
|
|
||||||
|
blockquote > :last-child { margin-bottom: 0; }
|
||||||
|
|
||||||
|
/** Code formatting */
|
||||||
|
pre, code { font-size: 13.125px; color: #454545; }
|
||||||
|
|
||||||
|
*:not(pre) > code { padding: 3px 6px; border-radius: 3px; background-color: #eee; margin: 0 5px; }
|
||||||
|
|
||||||
|
pre { overflow-x: auto; position: relative; background-color: #f0f0f0; }
|
||||||
|
|
||||||
|
pre > code { display: inline-block; padding: 20px !important; background-color: transparent; border: 0; }
|
||||||
|
|
||||||
|
pre table, pre pre { margin-bottom: 0; }
|
||||||
|
|
||||||
|
pre table .gutter, pre table .code, pre pre .gutter, pre pre .code { padding: 6px; border: none; }
|
||||||
|
|
||||||
|
/** Wrapper */
|
||||||
|
.wrapper { max-width: 920px; margin: auto; padding-right: 30px; padding-left: 30px; }
|
||||||
|
|
||||||
|
/** Clearfix */
|
||||||
|
.wrapper:after { content: ""; display: table; clear: both; }
|
||||||
|
|
||||||
|
/** Tables */
|
||||||
|
table { display: block; margin-bottom: 30px; width: 100%; text-align: left; color: #525252; border-collapse: collapse; overflow: auto; }
|
||||||
|
|
||||||
|
table tr:nth-child(even) { background-color: #f7f7f7; }
|
||||||
|
|
||||||
|
table th, table td { padding: 10px 15px; }
|
||||||
|
|
||||||
|
table th { background-color: #f0f0f0; border: 1px solid #dedede; border-bottom-color: #c9c9c9; }
|
||||||
|
|
||||||
|
table td { border: 1px solid #e8e8e8; }
|
||||||
|
|
||||||
|
/** Flex layout */
|
||||||
|
.framework { display: flex; }
|
||||||
|
|
||||||
|
.framework .main, .page-content { flex: 1; min-width: 0; /* <-- fix flexbox width with pre tags */ }
|
||||||
|
|
||||||
|
/** Flex sticky */
|
||||||
|
/** Vertical center */
|
||||||
|
/** Horizontal center */
|
||||||
|
/** Center background image */
|
||||||
|
/** Animation for transparent header */
|
||||||
|
html[data-header-transparent] header.site-header { position: fixed; }
|
||||||
|
|
||||||
|
html[data-scroll-status='top'] header.site-header-transparent { height: 0; margin-top: 12px; background-color: transparent; transition: 0.1s height,background-color,box-shadow; }
|
||||||
|
|
||||||
|
html[data-scroll-status='top'] header.site-header-transparent.site-header .site-brand-inner, html[data-scroll-status='top'] header.site-header-transparent.site-header .page-link { color: #fff; transition: 0.1s color; }
|
||||||
|
|
||||||
|
@media screen and (max-width: 800px) { html[data-scroll-status='top'] header.site-header-transparent.site-header .page-link { color: black; } html[data-scroll-status='top'] header.site-header-transparent.site-header .menu-icon > svg { fill: #fdfdfd; } }
|
||||||
|
|
||||||
|
html[data-scroll-status='top'] footer.site-footer { color: unset; background-color: transparent; }
|
||||||
|
|
||||||
|
html[data-scroll-status='top'] footer.site-footer .site-footer-inner { border-top: solid 1px #eee; }
|
||||||
|
|
||||||
|
html[data-scroll-status='down'] header.site-header { top: -63.84px; }
|
||||||
|
|
||||||
|
html[data-scroll-status='down'] .framework .sidebar { top: 20px; }
|
||||||
|
|
||||||
|
/** Site header */
|
||||||
|
.site-header { background-color: #ffffff; height: 63.84px; width: 100%; transition: height 0.2s, text-shadow 0.2s, top 0.2s; box-shadow: 0 1px 0 0 rgba(0, 0, 0, 0.06); position: sticky; position: -moz-sticky; /* <-- fix sticky compatibility issue */ position: -ms-sticky; position: -o-sticky; position: -webkit-sticky; align-self: flex-start; /* <-- fix the sticky not work issue */ transform: scale(0.9999); /* <-- fix the sticky x overflow issue */ top: 0; z-index: 1000; }
|
||||||
|
|
||||||
|
.site-header > .wrapper { margin: 0 60px; padding: 0; max-width: 100%; transition: 0.2s margin; }
|
||||||
|
|
||||||
|
@media screen and (max-width: 1024px) { .site-header > .wrapper { margin: 0 20px; max-width: unset; } }
|
||||||
|
|
||||||
|
.site-header a { text-decoration: none; }
|
||||||
|
|
||||||
|
.site-header .site-header-inner { position: relative; }
|
||||||
|
|
||||||
|
.site-brand { line-height: 63.84px; margin-right: 50px; }
|
||||||
|
|
||||||
|
.site-brand .site-brand-inner { font-size: 15.75px; font-weight: 400; letter-spacing: -1px; transition: 0.1s filter color; }
|
||||||
|
|
||||||
|
.site-brand .site-brand-inner, .site-brand .site-brand-inner:visited { color: black; }
|
||||||
|
|
||||||
|
.site-brand .site-brand-inner .site-favicon { display: inline-block; height: 42.56px; margin-right: 5px; }
|
||||||
|
|
||||||
|
.site-nav { font-size: 15.75px; line-height: 63.84px; position: absolute; right: 0; top: 0; }
|
||||||
|
|
||||||
|
.site-nav .nav-trigger { display: none; }
|
||||||
|
|
||||||
|
.site-nav .menu-icon { display: none; }
|
||||||
|
|
||||||
|
.site-nav .page-link { line-height: 1.6; color: black; transition: 0.1s ease-in-out; }
|
||||||
|
|
||||||
|
.site-nav .page-link:not(:last-child) { margin-right: 24px; }
|
||||||
|
|
||||||
|
.site-nav .page-link:not(:last-child):hover { text-decoration: underline; }
|
||||||
|
|
||||||
|
@media screen and (max-width: 800px) { .site-nav { position: absolute; top: 0; text-align: left; } .site-nav label[for="nav-trigger"] { display: block; z-index: 2; cursor: pointer; } .site-nav .menu-icon { display: block; float: right; text-align: center; } .site-nav .menu-icon > svg { fill: black; transition: 0.1s fill; } .site-nav input ~ .trigger { clear: both; display: none; border-radius: 3px; box-shadow: 1px 1px 1px 1px rgba(0, 0, 0, 0.06); } .site-nav input:checked ~ .trigger { display: block; background: #ffffff; } .site-nav .page-link { display: block; padding: 5px 10px; color: black; margin: 0 25px; } }
|
||||||
|
|
||||||
|
/** Site footer */
|
||||||
|
.site-footer { font-size: 14px; color: #404040; background-color: #f2f2f2; text-align: left; transition: background-color 0.2s; }
|
||||||
|
|
||||||
|
.site-footer .site-footer-inner { transition: border-top 0.2s; padding: 54px 0; }
|
||||||
|
|
||||||
|
.site-footer a { color: #ff5100; }
|
||||||
|
|
||||||
|
.site-footer a:hover { color: #ff7433; }
|
||||||
|
|
||||||
|
.copyleft { display: inline-block; transform: rotate(180deg); }
|
||||||
|
|
||||||
|
/** Post header */
|
||||||
|
.post .post-header { margin-bottom: 30px; }
|
||||||
|
|
||||||
|
.post .post-title { font-size: 36.75px; letter-spacing: -1px; line-height: 1; }
|
||||||
|
|
||||||
|
@media screen and (max-width: 800px) { .post .post-title { font-size: 31.5px; } }
|
||||||
|
|
||||||
|
.post .post-tags { padding-right: 150px; }
|
||||||
|
|
||||||
|
.post .post-tags .post-tag { display: inline-block; margin: 0 12px 0 0; }
|
||||||
|
|
||||||
|
/** Page content */
|
||||||
|
.page-content { /* <-- Keep footer on the bottom */ -ms-flex: none; /* <-- Fix IE footer issue */ padding: 60px 0; padding-top: 72px; }
|
||||||
|
|
||||||
|
.page-heading { font-size: 28px; }
|
||||||
|
|
||||||
|
.post-list-heading { font-size: 24.5px; }
|
||||||
|
|
||||||
|
/** Pagination page */
|
||||||
|
.pagination .post-list { margin-left: 0; list-style: none; }
|
||||||
|
|
||||||
|
.pagination .post-list > li { margin-bottom: 45px; padding-bottom: 30px; }
|
||||||
|
|
||||||
|
.pagination .post-list > li:not(:last-child) { border-bottom: 1px solid #e3e3e3; }
|
||||||
|
|
||||||
|
.pagination .post-title { margin-bottom: 6px; transition: 0.2s all; }
|
||||||
|
|
||||||
|
.pagination .post-title a { text-decoration: none; }
|
||||||
|
|
||||||
|
.pagination .post-title a:after { content: 'NEW'; position: absolute; margin-left: 8px; margin-top: 3px; padding: 0px 3px; background-color: #ff5100; color: #fff; font-size: 10px; font-weight: 600; border-radius: 2px; }
|
||||||
|
|
||||||
|
.pagination .post-title a:visited:after { background-color: #fff; }
|
||||||
|
|
||||||
|
.pagination .post-meta { font-size: 14px; color: #828282; margin-bottom: 15px; }
|
||||||
|
|
||||||
|
.pagination .post-link { font-size: 23.1px; font-weight: 600; color: #333; }
|
||||||
|
|
||||||
|
.pagination .post-excerpt { color: #777; word-break: break-word; overflow-wrap: break-word; }
|
||||||
|
|
||||||
|
.pagination .post-tags .post-tag { display: inline-block; text-decoration: none; border: 1px solid; padding: 2px 4px; border-radius: 2px; transition: color 0.2s; margin-bottom: 8px; }
|
||||||
|
|
||||||
|
.pagination .post-tags .post-tag:not(:last-child) { margin-right: 8px; }
|
||||||
|
|
||||||
|
.pagination .post-tags .post-tag:hover { color: #787878; }
|
||||||
|
|
||||||
|
.pagination .paginator { text-align: center; }
|
||||||
|
|
||||||
|
.pagination .paginator > .previous:before { content: ' '; border: solid #787878; border-width: 0 2px 2px 0; display: inline-block; padding: 4px; margin-right: 8px; transform: rotate(135deg); -webkit-transform: rotate(135deg); }
|
||||||
|
|
||||||
|
.pagination .paginator > .next:after { content: ' '; border: solid #787878; border-width: 0 2px 2px 0; display: inline-block; padding: 4px; margin-left: 8px; transform: rotate(-45deg); -webkit-transform: rotate(-45deg); }
|
||||||
|
|
||||||
|
.pagination .paginator .previous span, .pagination .paginator .next span { color: #b3b3b3; }
|
||||||
|
|
||||||
|
.pagination .paginator .indicator { padding: 0 15px; }
|
||||||
|
|
||||||
|
/** Posts */
|
||||||
|
.post .post-header { margin: 50px auto 60px; padding: 0 0 20px; border-bottom: 1px solid #ebebeb; }
|
||||||
|
|
||||||
|
.post .post-header .post-title { margin-bottom: 6px; }
|
||||||
|
|
||||||
|
.post .post-header .post-subtitle { font-weight: lighter; }
|
||||||
|
|
||||||
|
.post .post-header .post-meta { color: #808080; }
|
||||||
|
|
||||||
|
.post .post-content { margin-bottom: 30px; overflow-wrap: normal; word-wrap: normal; word-break: normal; }
|
||||||
|
|
||||||
|
.post .post-content h2 { font-size: 28px; }
|
||||||
|
|
||||||
|
@media screen and (max-width: 800px) { .post .post-content h2 { font-size: 24.5px; } }
|
||||||
|
|
||||||
|
.post .post-content h3 { font-size: 22.75px; }
|
||||||
|
|
||||||
|
@media screen and (max-width: 800px) { .post .post-content h3 { font-size: 19.25px; } }
|
||||||
|
|
||||||
|
.post .post-content h4 { font-size: 17.5px; }
|
||||||
|
|
||||||
|
@media screen and (max-width: 800px) { .post .post-content h4 { font-size: 15.75px; } }
|
||||||
|
|
||||||
|
.post .post-content img, .post .post-content svg, .post .post-content iframe { margin-left: auto; margin-right: auto; display: block; }
|
||||||
|
|
||||||
|
.post .post-content h2, .post .post-content h3, .post .post-content h4, .post .post-content h5, .post .post-content h6 { margin: 60px 0 19px; }
|
||||||
|
|
||||||
|
.post .post-content p, .post .post-content hr { margin-bottom: 24px; }
|
||||||
|
|
||||||
|
.post .post-content hr { height: 1px; background-color: #ebebeb; border: none; }
|
||||||
|
|
||||||
|
.post .post-related > *:first-child { font-size: 19.95px; color: #333; margin-bottom: 14px; }
|
||||||
|
|
||||||
|
.post .post-related ul { margin-left: 15px; }
|
||||||
|
|
||||||
|
.post .post-related ul .post-link { font-size: 15.05px; }
|
||||||
|
|
||||||
|
.post .post-related ul a { color: #666; }
|
||||||
|
|
||||||
|
.post .post-related ul a:hover { color: #333; }
|
||||||
|
|
||||||
|
.post .post-related ul a:after { content: 'NEW'; position: absolute; margin-left: 8px; margin-top: 3px; padding: 0px 3px; background-color: #ff5100; color: #fff; font-size: 10px; font-weight: 600; border-radius: 2px; }
|
||||||
|
|
||||||
|
.post .post-related ul a:visited:after { background-color: #fff; }
|
||||||
|
|
||||||
|
.post-comments { padding-top: 25px; }
|
||||||
|
|
||||||
|
/** Posts misc */
|
||||||
|
.post-nav { display: flex; justify-content: space-between; margin: 72px 0 59px; padding: 31px 0 0; }
|
||||||
|
|
||||||
|
.post-nav a { font-size: 15.75px; line-height: 15px; color: #666; max-width: 50%; }
|
||||||
|
|
||||||
|
.post-nav .previous:before { content: ' '; border: solid #787878; border-width: 0 2px 2px 0; display: inline-block; padding: 4px; margin-right: 8px; transform: rotate(135deg); -webkit-transform: rotate(135deg); }
|
||||||
|
|
||||||
|
.post-nav .next:after { content: ' '; border: solid #787878; border-width: 0 2px 2px 0; display: inline-block; padding: 4px; margin-left: 8px; transform: rotate(-45deg); -webkit-transform: rotate(-45deg); }
|
||||||
|
|
||||||
|
/** Archives page */
|
||||||
|
.page-archives .page-archives-list { margin-left: 0; list-style: none; }
|
||||||
|
|
||||||
|
.page-archives .archives-time { font-size: 21px; margin-bottom: 8px; }
|
||||||
|
|
||||||
|
.page-archives .archives-time:not(:first-child) { margin-top: 18px; }
|
||||||
|
|
||||||
|
.page-archives .post-meta { font-size: 12.25px; color: #828282; }
|
||||||
|
|
||||||
|
/** Page banner */
|
||||||
|
.page-banner { display: block; position: relative; height: 640px; background-color: rgba(0, 0, 0, 0.8); transition: height 0.2s; }
|
||||||
|
|
||||||
|
.page-banner .page-banner-img { position: absolute; width: 100%; height: 100%; overflow: hidden; }
|
||||||
|
|
||||||
|
.page-banner .page-banner-img > *:first-child { height: 100%; max-width: 1000%; background-size: cover; background-position: center center; overflow: hidden; transition: 0.1s all ease-in-out; }
|
||||||
|
|
||||||
|
.page-banner .page-banner-img > video { width: 100vw; object-fit: cover; }
|
||||||
|
|
||||||
|
.page-banner .page-banner-img > img.img-placeholder { display: none; }
|
||||||
|
|
||||||
|
.page-banner .wrapper { height: 100%; }
|
||||||
|
|
||||||
|
.page-banner .page-banner-inner { position: relative; top: 50%; transform: translateY(-50%); color: #fdfdfd; padding: 10px 5px; text-shadow: 1px 1px 2px #33333355; }
|
||||||
|
|
||||||
|
.page-banner .page-banner-inner > *:first-child { margin: 0; }
|
||||||
|
|
||||||
|
.page-banner .page-banner-inner > *:first-child > :nth-child(1) { font-size: 54.6px; letter-spacing: -1px; margin-bottom: 0.1em; font-weight: normal; transition: 0.2s all; }
|
||||||
|
|
||||||
|
@media screen and (max-width: 600px) { .page-banner .page-banner-inner > *:first-child > :nth-child(1) { font-size: 27.65px; } }
|
||||||
|
|
||||||
|
.page-banner .page-banner-inner > *:first-child > :nth-child(2) { font-weight: lighter; margin-bottom: 0.8em; transition: 0.2s all; }
|
||||||
|
|
||||||
|
@media screen and (max-width: 600px) { .page-banner .page-banner-inner > *:first-child > :nth-child(2) { font-size: 16.45px; } }
|
||||||
|
|
||||||
|
.page-banner .page-banner-inner > *:first-child > :last-child { margin-bottom: 0; }
|
||||||
|
|
||||||
|
.page-banner .page-banner-inner .post-subtitle { font-size: 21.35px; color: #ffffffcc; padding-right: 280px; }
|
||||||
|
|
||||||
|
@media screen and (max-width: 600px) { .page-banner .page-banner-inner .post-subtitle { padding-right: 0; } }
|
||||||
|
|
||||||
|
.page-banner .page-banner-inner .post-meta { color: #ffffffcc; }
|
||||||
|
|
||||||
|
.page-banner .page-banner-inner .left-vsplit:before { background: #e3e3e388; }
|
||||||
|
|
||||||
|
.page-banner .page-banner-inner .post-tags { color: #999; padding-right: 280px; }
|
||||||
|
|
||||||
|
@media screen and (max-width: 600px) { .page-banner .page-banner-inner .post-tags { padding-right: 0; } }
|
||||||
|
|
||||||
|
.page-banner .page-banner-inner .post-tags .post-tag { font-size: 15.75px; display: inline-block; text-decoration: none; margin: 9px 12px 0 0; color: #fff; }
|
||||||
|
|
||||||
|
.page-banner .page-banner-inner .post-tags .post-tag:hover { text-decoration: underline; }
|
||||||
|
|
||||||
|
@media screen and (max-width: 600px) { .page-banner { height: 426.6666666667px; } }
|
||||||
|
|
||||||
|
/** Layout and sidebar */
|
||||||
|
.framework .sidebar { padding-left: 8px; transition: top 0.2s, display 0.2s; position: sticky; position: -moz-sticky; /* <-- fix sticky compatibility issue */ position: -ms-sticky; position: -o-sticky; position: -webkit-sticky; align-self: flex-start; /* <-- fix the sticky not work issue */ transform: scale(0.9999); /* <-- fix the sticky x overflow issue */ top: 83.84px; }
|
||||||
|
|
||||||
|
@media screen and (max-width: 800px) { .framework .sidebar { display: none; } }
|
||||||
|
|
||||||
|
/** Segments page */
|
||||||
|
.page-segments .page-segments-list { margin-left: 0; list-style: none; }
|
||||||
|
|
||||||
|
.page-segments .segment-name { font-weight: 600; margin-bottom: 8px; position: relative; font-size: 22.4px; }
|
||||||
|
|
||||||
|
.page-segments .segment-name:not(:first-child) { margin-top: 28px; }
|
||||||
|
|
||||||
|
.page-segments .segment-name:hover:before { content: '#'; left: -1em; position: absolute; }
|
||||||
|
|
||||||
|
.page-segments .post-meta { font-size: 12.25px; color: #828282; }
|
||||||
|
|
||||||
|
.page-segments li a { color: #303030; }
|
||||||
|
|
||||||
|
.page-segments li a.post-link { margin-left: 5px; }
|
||||||
|
|
||||||
|
.page-segments li a:hover { color: #000; }
|
||||||
|
|
||||||
|
.page-segments li a:after { content: 'NEW'; position: absolute; margin-left: 8px; margin-top: 3px; padding: 0px 3px; background-color: #ff5100; color: #fff; font-size: 10px; font-weight: 600; border-radius: 2px; }
|
||||||
|
|
||||||
|
.page-segments li a:visited:after { background-color: #fff; }
|
||||||
|
|
||||||
|
.left-vsplit:before { content: ""; display: inline-block; width: 1px; height: 10px; margin: 0 10px; background-color: #e3e3e3e3; vertical-align: baseline; }
|
||||||
|
|
||||||
|
@media screen and (max-width: 800px) { html[data-theme="dark"][data-scroll-status='top'] header.site-header-transparent.site-header .page-link { color: #f8f8f8; } }
|
||||||
|
|
||||||
|
html[data-theme="dark"][data-scroll-status='top'] footer.site-footer .site-footer-inner { border-top: solid 1px #2f2f2f !important; transition: 0s; }
|
||||||
|
|
||||||
|
html[data-theme="dark"] body { color: #bbb; background-color: #0e0e0e; }
|
||||||
|
|
||||||
|
html[data-theme="dark"] *:not(pre) > code { color: #bbb; background-color: #454545; }
|
||||||
|
|
||||||
|
html[data-theme="dark"] blockquote { border-left: 4px solid #484848; }
|
||||||
|
|
||||||
|
html[data-theme="dark"] table { color: #9d9d9d; }
|
||||||
|
|
||||||
|
html[data-theme="dark"] table th { background-color: #050505; }
|
||||||
|
|
||||||
|
html[data-theme="dark"] table tr:nth-child(even) { background-color: #080808; }
|
||||||
|
|
||||||
|
html[data-theme="dark"] .site-header { background-color: #090909; }
|
||||||
|
|
||||||
|
html[data-theme="dark"] .site-header .site-brand .site-brand-inner, html[data-theme="dark"] .site-header .site-brand .site-brand-inner:visited { color: #f8f8f8; }
|
||||||
|
|
||||||
|
html[data-theme="dark"] .site-header .site-nav .page-link { color: #f8f8f8; }
|
||||||
|
|
||||||
|
html[data-theme="dark"] .site-header .ct-language-dropdown { color: #f8f8f8; background-color: #0e0e0e; box-shadow: 0 0 3px 1px #0000005b; }
|
||||||
|
|
||||||
|
html[data-theme="dark"] .site-header .ct-language-selected, .ct-language-dropdown html[data-theme="dark"] .site-header li:hover, html[data-theme="dark"] .site-header .ct-language-dropdown li:hover { background-color: #222 !important; }
|
||||||
|
|
||||||
|
@media screen and (max-width: 800px) { html[data-theme="dark"] .site-header .menu-icon > svg { fill: #bbbbbb; } html[data-theme="dark"] .site-header .site-nav input:checked ~ .trigger { background-color: #090909; } }
|
||||||
|
|
||||||
|
html[data-theme="dark"] .site-footer { color: #fff; background-color: #000; }
|
||||||
|
|
||||||
|
html[data-theme="dark"] .left-vsplit:before { background-color: #9a9a9a; }
|
||||||
|
|
||||||
|
html[data-theme="dark"] .page-banner .page-banner-img > *:first-child { opacity: 0.718; }
|
||||||
|
|
||||||
|
html[data-theme="dark"] .pagination .post-link { color: #bbb; }
|
||||||
|
|
||||||
|
html[data-theme="dark"] .pagination .post-title a:visited:after { background-color: #0e0e0e; }
|
||||||
|
|
||||||
|
html[data-theme="dark"] .pagination .post-title a:after { color: #0e0e0e; }
|
||||||
|
|
||||||
|
html[data-theme="dark"] .pagination .post-list > li:not(:last-child) { border-bottom: 1px solid #545454; }
|
||||||
|
|
||||||
|
html[data-theme="dark"] .pagination .post-tags .post-tag:hover { color: #d7d7d7; }
|
||||||
|
|
||||||
|
html[data-theme="dark"] .page-segments li a { color: #ddd; }
|
||||||
|
|
||||||
|
html[data-theme="dark"] .page-segments li a:visited:after { background-color: #0e0e0e; }
|
||||||
|
|
||||||
|
html[data-theme="dark"] .page-segments li a:after { color: #0e0e0e; }
|
||||||
|
|
||||||
|
html[data-theme="dark"] .post .post-content img:not([raw]) { background-color: #ffffff33; }
|
||||||
|
|
||||||
|
html[data-theme="dark"] .post-related > *:first-child { color: #d7d7d7; }
|
||||||
|
|
||||||
|
html[data-theme="dark"] .post-related a:visited:after { background-color: #0e0e0e; }
|
||||||
|
|
||||||
|
html[data-theme="dark"] .post-related a:after { color: #0e0e0e; }
|
||||||
|
|
||||||
|
html[data-theme="dark"] .post-related a:hover { color: #aaa; }
|
||||||
|
|
||||||
|
html[data-theme="dark"] .common-list li { border-bottom: solid 1px #40404088; }
|
||||||
|
|
||||||
|
html[data-theme="dark"] .common-list li a { color: #aaa; }
|
||||||
|
|
||||||
|
html[data-theme="dark"] .common-list li a:hover { background-color: #272727; }
|
||||||
|
|
||||||
|
html[data-theme="dark"] .common-list li span { background-color: #333; }
|
||||||
|
|
||||||
|
html[data-theme="dark"] .post-menu .post-menu-title { color: #ddd; }
|
||||||
|
|
||||||
|
html[data-theme="dark"] .post-menu .post-menu-content ul { border-left: 1px solid #787878; }
|
||||||
|
|
||||||
|
html[data-theme="dark"] .post-menu .post-menu-content ul .active { background-color: #2d2d2d; border-left: 2px solid #aaa; }
|
||||||
|
|
||||||
|
html[data-theme="dark"] .post-menu .post-menu-content ul a { color: #bbb; }
|
||||||
|
|
||||||
|
html[data-theme="dark"] .post-menu .post-menu-content ul a:hover { color: #fff !important; }
|
||||||
|
|
||||||
|
.theme-toggle { position: relative; width: 107.1px; margin-top: 10px; margin-right: 60px; margin-left: auto; transition: 0.3s cubic-bezier(0.4, 0.03, 0, 1); /* Toggle */ }
|
||||||
|
|
||||||
|
.theme-toggle label, .theme-toggle .toggle { border-radius: 100px; }
|
||||||
|
|
||||||
|
.theme-toggle label { display: block; background-color: rgba(120, 120, 120, 0.15); cursor: pointer; }
|
||||||
|
|
||||||
|
.theme-toggle .toggle { position: absolute; width: 50%; height: 100%; background-color: #fff; box-shadow: 0 2px 15px rgba(0, 0, 0, 0.15); transition: transform 0.2s cubic-bezier(0.25, 0.46, 0.45, 0.94); }
|
||||||
|
|
||||||
|
.theme-toggle .names { font-size: 1em; font-weight: bolder; width: 76%; margin-left: 12%; position: relative; display: flex; justify-content: space-between; user-select: none; }
|
||||||
|
|
||||||
|
.theme-toggle .dark { opacity: .5; }
|
||||||
|
|
||||||
|
.theme-toggle p { color: #acacac; margin-bottom: 0; line-height: 24px; }
|
||||||
|
|
||||||
|
.theme-toggle [type="checkbox"] { display: none; }
|
||||||
|
|
||||||
|
.theme-toggle [type="checkbox"]:checked ~ label .toggle { transform: translateX(100%); background-color: #34323D; }
|
||||||
|
|
||||||
|
.theme-toggle [type="checkbox"]:checked ~ label .dark { opacity: 1; }
|
||||||
|
|
||||||
|
.theme-toggle [type="checkbox"]:checked ~ label .light { opacity: .5; }
|
||||||
|
|
||||||
|
@media screen and (max-width: 1024px) { .theme-toggle { margin-right: 35px; } }
|
||||||
|
|
||||||
|
@media screen and (max-width: 600px) { .theme-toggle { width: 93.1px; margin-right: 20px; } .theme-toggle .names { font-size: .85em; } }
|
||||||
|
|
||||||
|
/* Post menu */
|
||||||
|
.post-menu { padding-left: 20px; min-width: 200px; max-width: 230px; }
|
||||||
|
|
||||||
|
.post-menu .post-menu-title { font-size: 21px; margin-bottom: 14px; font-weight: 600; color: #222; }
|
||||||
|
|
||||||
|
.post-menu .post-menu-content ul { border-left: 1px solid #e9ecef; }
|
||||||
|
|
||||||
|
.post-menu .post-menu-content ul .h-h2 { padding-inline-start: 3.5px; font-size: 15.4px; line-height: 1.4; }
|
||||||
|
|
||||||
|
.post-menu .post-menu-content ul .h-h3 { padding-inline-start: 21.7px; font-size: 15.4px; line-height: 1.4; }
|
||||||
|
|
||||||
|
.post-menu .post-menu-content ul .h-h4 { padding-inline-start: 39.9px; font-size: 15.4px; line-height: 1.4; }
|
||||||
|
|
||||||
|
.post-menu .post-menu-content ul .h-h5 { padding-inline-start: 58.1px; font-size: 15.4px; line-height: 1.4; }
|
||||||
|
|
||||||
|
.post-menu .post-menu-content ul .h-h6 { padding-inline-start: 76.3px; font-size: 15.4px; line-height: 1.4; }
|
||||||
|
|
||||||
|
.post-menu .post-menu-content ul a { display: flex; padding: 2px 8px; color: #2c2c2c; }
|
||||||
|
|
||||||
|
.post-menu .post-menu-content ul a * { pointer-events: none; }
|
||||||
|
|
||||||
|
.post-menu .post-menu-content ul a:hover { text-decoration: none; color: #787878 !important; }
|
||||||
|
|
||||||
|
.post-menu .post-menu-content ul .active { background-color: #ecebec; transition: background 0.5s; border-left: 2px solid #202020; margin-left: -2px; }
|
||||||
|
|
||||||
|
.post-menu .post-menu-content ul .active:hover { background-color: #f1f0f1; }
|
||||||
|
|
||||||
|
.post-menu .post-menu-content ul .active a { color: #121416; }
|
||||||
|
|
||||||
|
/** Common list */
|
||||||
|
.common-list { font-size: 14px; min-width: 200px; }
|
||||||
|
|
||||||
|
.common-list ul { list-style: none; margin: 0; }
|
||||||
|
|
||||||
|
.common-list li { border-bottom: solid 1px #00000018; }
|
||||||
|
|
||||||
|
.common-list li:last-child { border-bottom: none; }
|
||||||
|
|
||||||
|
.common-list li a { display: flex; justify-content: space-between; padding: 8px 12px; text-decoration: none; font-weight: normal; color: #454545; transition: background 0.2s; }
|
||||||
|
|
||||||
|
.common-list li a:hover { background-color: #eeeeee; }
|
||||||
|
|
||||||
|
.common-list li span { font-size: 11.2px; display: inline-block; border-radius: 10px; align-self: center; background: #000000bd; padding: 0px 8px; margin-left: 20px; color: #fdfdfd; }
|
||||||
|
|
||||||
|
/* OVERRIDE GOOGLE TRANSLATE WIDGET CSS BEGIN */
|
||||||
|
div#google_translate_element div.goog-te-gadget-simple a.goog-te-menu-value { vertical-align: top !important; /* Remove the down arrow */ /* when dropdown open */ /* after clicked/touched */ /* on page load (not yet touched or clicked) */ /* Remove span with left border line | (next to the arrow) in Chrome & Firefox */ /* Remove span with left border line | (next to the arrow) in Edge & IE11 */ }
|
||||||
|
|
||||||
|
div#google_translate_element div.goog-te-gadget-simple a.goog-te-menu-value:hover { text-decoration: none; }
|
||||||
|
|
||||||
|
div#google_translate_element div.goog-te-gadget-simple a.goog-te-menu-value span { color: #aaa; }
|
||||||
|
|
||||||
|
div#google_translate_element div.goog-te-gadget-simple a.goog-te-menu-value span:hover { color: white; }
|
||||||
|
|
||||||
|
div#google_translate_element div.goog-te-gadget-simple a.goog-te-menu-value span[style="color: rgb(213, 213, 213);"] { display: none; }
|
||||||
|
|
||||||
|
div#google_translate_element div.goog-te-gadget-simple a.goog-te-menu-value span[style="color: rgb(118, 118, 118);"] { display: none; }
|
||||||
|
|
||||||
|
div#google_translate_element div.goog-te-gadget-simple a.goog-te-menu-value span[style="color: rgb(155, 155, 155);"] { display: none; }
|
||||||
|
|
||||||
|
div#google_translate_element div.goog-te-gadget-simple a.goog-te-menu-value span[style="border-left: 1px solid rgb(187, 187, 187);"] { display: none; }
|
||||||
|
|
||||||
|
div#google_translate_element div.goog-te-gadget-simple a.goog-te-menu-value span[style="border-left-color: rgb(187, 187, 187); border-left-width: 1px; border-left-style: solid;"] { display: none; }
|
||||||
|
|
||||||
|
div#google_translate_element { display: inline; }
|
||||||
|
|
||||||
|
div#google_translate_element div.goog-te-gadget { display: inline; font-size: 0; }
|
||||||
|
|
||||||
|
div#google_translate_element div[id=':0.targetLanguage'] { display: inline; }
|
||||||
|
|
||||||
|
div#google_translate_element div.goog-te-gadget-simple { border: none; background-color: transparent; }
|
||||||
|
|
||||||
|
div#google_translate_element a.goog-logo-link { display: none; }
|
||||||
|
|
||||||
|
div#google_translate_element .goog-te-gadget-icon { display: none !important; /*background: url("url for the icon") 0 0 no-repeat !important;*/ }
|
||||||
|
|
||||||
|
div#google_translate_element a.goog-te-menu-value { margin: 0; }
|
||||||
|
|
||||||
|
div#google_translate_element a.goog-te-menu-value span:first-child { display: none; }
|
||||||
|
|
||||||
|
div#google_translate_element a.goog-te-menu-value:before { content: "\f1ab \f0d7"; font-family: FontAwesome; font-size: initial; color: #fefefe; border: 1px solid #fefefe85; border-radius: 3px; padding: 3px 6px; }
|
||||||
|
|
||||||
|
.goog-te-menu-frame .goog-te-menu2 { max-width: 100%; overflow-x: auto; box-sizing: border-box; height: auto; }
|
||||||
|
|
||||||
|
/* HIDE the google translate toolbar */
|
||||||
|
.goog-te-banner-frame.skiptranslate { display: none !important; border: none; box-shadow: 0 0; -webkit-box-shadow: 0 0; }
|
||||||
|
|
||||||
|
body { top: 0px !important; }
|
||||||
|
|
||||||
|
/* OVERRIDE GOOGLE TRANSLATE WIDGET CSS END */
|
||||||
|
.ct-language-selected, .ct-language-dropdown li:hover { background-color: #f2f2f2 !important; }
|
||||||
|
|
||||||
|
.ct-language-dropdown { overflow: hidden; max-height: 0; position: absolute; top: 110%; right: -10px; background-color: white; -webkit-transition: all 0.25s ease-in-out; transition: all 0.25s ease-in-out; width: 100px; text-align: center; margin-top: 0; z-index: 200; border-radius: 3px; visibility: hidden; }
|
||||||
|
|
||||||
|
.ct-language-dropdown li { padding: 5px; }
|
||||||
|
|
||||||
|
.ct-language-dropdown li:first-child { padding-top: 12px; }
|
||||||
|
|
||||||
|
.ct-language-dropdown li:last-child { padding-bottom: 12px; }
|
||||||
|
|
||||||
|
.ct-language-dropdown li:not(:last-child) { border-bottom: 1px solid rgba(0, 0, 0, 0.04); }
|
||||||
|
|
||||||
|
.ct-language-dropdown li a { display: block; color: black; }
|
||||||
|
|
||||||
|
.ct-language-dropdown li a img { width: 24px; max-height: 24px; border: none; }
|
||||||
|
|
||||||
|
.list-unstyled { display: inline-block; list-style: none; margin-left: 0; }
|
||||||
|
|
||||||
|
.ct-language { display: inline-block; position: relative; background-color: #fefefe2b; padding: 3px 10px; border-radius: 3px; }
|
||||||
|
|
||||||
|
.ct-language:hover { cursor: pointer; }
|
||||||
|
|
||||||
|
.ct-language:hover .ct-language-dropdown { margin-top: 8px; max-height: 10000px; visibility: visible; box-shadow: 0 0 9px 3px rgba(0, 0, 0, 0.06); }
|
||||||
|
|
||||||
|
.ct-language:before { content: "\f1ab \f0d7"; font-family: FontAwesome; }
|
||||||
|
|
||||||
|
.gitment-container { color: #787878 !important; }
|
||||||
|
|
||||||
|
.gitment-editor-header { background-color: #fefefe; }
|
||||||
|
|
||||||
|
.gitment-comment-main, .gitment-editor-main { background-color: #fff; border-radius: 3px !important; }
|
||||||
|
|
||||||
|
.gitment-heart-icon { fill: #ff0808; }
|
||||||
|
|
||||||
|
.click-to-top { transition: 0.3s; display: flex; align-items: center; justify-content: center; position: fixed; width: 64px; height: 64px; border-radius: 32px; right: 60px; bottom: 48px; background: white; cursor: pointer; opacity: 0; transform: translateY(10px); box-shadow: 0 2px 15px rgba(0, 0, 0, 0.15); font-size: 24px; user-select: none; }
|
||||||
|
|
||||||
|
@media screen and (max-width: 1024px) { .click-to-top { width: 48px; height: 48px; border-radius: 24px; right: 35px; font-size: 20px; } }
|
||||||
|
|
||||||
|
@media screen and (max-width: 600px) { .click-to-top { width: 36px; height: 36px; border-radius: 18px; right: 20px; font-size: 16px; } }
|
||||||
|
|
||||||
|
.click-to-top.show { opacity: 1; transform: translateY(0); }
|
||||||
|
|
||||||
|
html[data-theme="dark"] .click-to-top { background: #34323D; }
|
||||||
|
|
||||||
|
/*# sourceMappingURL=main.css.map */
|
32
assets/css/main.css.map
Normal file
BIN
assets/images/banners/home.jpg
Normal file
After Width: | Height: | Size: 363 KiB |
BIN
assets/images/codespaces/1.jpg
Normal file
After Width: | Height: | Size: 22 KiB |
BIN
assets/images/codespaces/2.jpg
Normal file
After Width: | Height: | Size: 29 KiB |
BIN
assets/images/rpi-arch/01.png
Normal file
After Width: | Height: | Size: 25 KiB |
BIN
assets/images/rpi-arch/02.png
Normal file
After Width: | Height: | Size: 30 KiB |
BIN
assets/images/rpi-arch/03.png
Normal file
After Width: | Height: | Size: 29 KiB |
BIN
assets/images/rpi-arch/04.png
Normal file
After Width: | Height: | Size: 18 KiB |
BIN
assets/images/rpi-arch/05.png
Normal file
After Width: | Height: | Size: 45 KiB |
BIN
assets/images/vpn/1.png
Normal file
After Width: | Height: | Size: 36 KiB |
BIN
assets/images/vpn/10.png
Normal file
After Width: | Height: | Size: 97 KiB |
BIN
assets/images/vpn/11.png
Normal file
After Width: | Height: | Size: 30 KiB |
BIN
assets/images/vpn/12.png
Normal file
After Width: | Height: | Size: 31 KiB |
BIN
assets/images/vpn/13.png
Normal file
After Width: | Height: | Size: 41 KiB |
BIN
assets/images/vpn/14.png
Normal file
After Width: | Height: | Size: 12 KiB |
BIN
assets/images/vpn/2.png
Normal file
After Width: | Height: | Size: 56 KiB |
BIN
assets/images/vpn/3.png
Normal file
After Width: | Height: | Size: 48 KiB |
BIN
assets/images/vpn/4.png
Normal file
After Width: | Height: | Size: 31 KiB |
BIN
assets/images/vpn/5.png
Normal file
After Width: | Height: | Size: 51 KiB |
BIN
assets/images/vpn/6.png
Normal file
After Width: | Height: | Size: 8.4 KiB |
BIN
assets/images/vpn/7.png
Normal file
After Width: | Height: | Size: 1.2 MiB |
BIN
assets/images/vpn/8.png
Normal file
After Width: | Height: | Size: 60 KiB |
BIN
assets/images/vpn/9.png
Normal file
After Width: | Height: | Size: 80 KiB |
58
assets/js/main.js
Normal file
|
@ -0,0 +1,58 @@
|
||||||
|
// Fix DOM matches function
|
||||||
|
if (!Element.prototype.matches) {
|
||||||
|
Element.prototype.matches =
|
||||||
|
Element.prototype.matchesSelector ||
|
||||||
|
Element.prototype.mozMatchesSelector ||
|
||||||
|
Element.prototype.msMatchesSelector ||
|
||||||
|
Element.prototype.oMatchesSelector ||
|
||||||
|
Element.prototype.webkitMatchesSelector ||
|
||||||
|
function(s) {
|
||||||
|
var matches = (this.document || this.ownerDocument).querySelectorAll(s),
|
||||||
|
i = matches.length;
|
||||||
|
while (--i >= 0 && matches.item(i) !== this) {}
|
||||||
|
return i > -1;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get Scroll position
|
||||||
|
function getScrollPos() {
|
||||||
|
var supportPageOffset = window.pageXOffset !== undefined;
|
||||||
|
var isCSS1Compat = ((document.compatMode || "") === "CSS1Compat");
|
||||||
|
|
||||||
|
var x = supportPageOffset ? window.pageXOffset : isCSS1Compat ? document.documentElement.scrollLeft : document.body.scrollLeft;
|
||||||
|
var y = supportPageOffset ? window.pageYOffset : isCSS1Compat ? document.documentElement.scrollTop : document.body.scrollTop;
|
||||||
|
|
||||||
|
return { x: x, y: y };
|
||||||
|
}
|
||||||
|
|
||||||
|
var _scrollTimer = [];
|
||||||
|
|
||||||
|
// Smooth scroll
|
||||||
|
function smoothScrollTo(y, time) {
|
||||||
|
time = time == undefined ? 500 : time;
|
||||||
|
|
||||||
|
var scrollPos = getScrollPos();
|
||||||
|
var count = 60;
|
||||||
|
var length = (y - scrollPos.y);
|
||||||
|
|
||||||
|
function easeInOut(k) {
|
||||||
|
return .5 * (Math.sin((k - .5) * Math.PI) + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (var i = _scrollTimer.length - 1; i >= 0; i--) {
|
||||||
|
clearTimeout(_scrollTimer[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (var i = 0; i <= count; i++) {
|
||||||
|
(function() {
|
||||||
|
var cur = i;
|
||||||
|
_scrollTimer[cur] = setTimeout(function() {
|
||||||
|
window.scrollTo(
|
||||||
|
scrollPos.x,
|
||||||
|
scrollPos.y + length * easeInOut(cur/count)
|
||||||
|
);
|
||||||
|
}, (time / count) * cur);
|
||||||
|
})();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
853
bezpečí/2022/07/19/nordvpn.html
Normal file
|
@ -0,0 +1,853 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
|
<meta name="google-translate-customization" content="108d9124921d80c3-80e20d618ff053c8-g4f02ec6f3dba68b7-c">
|
||||||
|
<!-- Begin Jekyll SEO tag v2.8.0 -->
|
||||||
|
<title>NordVPN - Jste opravdu v takovém nebezpečí? | Matyáš Caras</title>
|
||||||
|
<meta name="generator" content="Jekyll v4.3.1">
|
||||||
|
<meta property="og:title" content="NordVPN - Jste opravdu v takovém nebezpečí?">
|
||||||
|
<meta name="author" content="hernikplays">
|
||||||
|
<meta property="og:locale" content="en_US">
|
||||||
|
<meta name="description" content="Pokud sledujete YouTube, určite jste už narazili na nespočet videí, které sponzoruje nějaký poskytovatel tzv. VPN. Většinou se dozvíte něco jako „vaše data jsou v nebezpečí“ a/nebo „použijte naše služby pro zabezpečení vašich dat před hackery“. Toto se samozřejmě netýká jen NordVPN, ale myslím, že ti mají tu nejagresivnější marketingovou strategii snad ze všech. ČÁST I: Kecy Kdo stojí za NordVPN NordVPN vzniklo v roce 2012 jako produkt Toma Okmana, Eimantase Sabaliauskase a Jonase Karklyse. Služba má sloužit jako tzv. Virtual Private Network neboli virtuální soukromá síť. Můžete se tak skrze NordVPN servery připojovat na internet třeba z Německa. Dle zvoleného protokolu je síťový provoz šifrován. NordVPN vlastní společnost Nord Security, která zastřešuje i ostatní produkty značky Nord. Sídlo má ve Velké Británii. Nord Security kromě VPN nabízí i vlastního správce hesel a šifrovaný cloud.">
|
||||||
|
<meta property="og:description" content="Pokud sledujete YouTube, určite jste už narazili na nespočet videí, které sponzoruje nějaký poskytovatel tzv. VPN. Většinou se dozvíte něco jako „vaše data jsou v nebezpečí“ a/nebo „použijte naše služby pro zabezpečení vašich dat před hackery“. Toto se samozřejmě netýká jen NordVPN, ale myslím, že ti mají tu nejagresivnější marketingovou strategii snad ze všech. ČÁST I: Kecy Kdo stojí za NordVPN NordVPN vzniklo v roce 2012 jako produkt Toma Okmana, Eimantase Sabaliauskase a Jonase Karklyse. Služba má sloužit jako tzv. Virtual Private Network neboli virtuální soukromá síť. Můžete se tak skrze NordVPN servery připojovat na internet třeba z Německa. Dle zvoleného protokolu je síťový provoz šifrován. NordVPN vlastní společnost Nord Security, která zastřešuje i ostatní produkty značky Nord. Sídlo má ve Velké Británii. Nord Security kromě VPN nabízí i vlastního správce hesel a šifrovaný cloud.">
|
||||||
|
<link rel="canonical" href="https://caras.cafe/bezpe%C4%8D%C3%AD/2022/07/19/nordvpn.html">
|
||||||
|
<meta property="og:url" content="https://caras.cafe/bezpe%C4%8D%C3%AD/2022/07/19/nordvpn.html">
|
||||||
|
<meta property="og:site_name" content="Matyáš Caras">
|
||||||
|
<meta property="og:type" content="article">
|
||||||
|
<meta property="article:published_time" content="2022-07-19T00:00:00+00:00">
|
||||||
|
<meta name="twitter:card" content="summary">
|
||||||
|
<meta property="twitter:title" content="NordVPN - Jste opravdu v takovém nebezpečí?">
|
||||||
|
<script type="application/ld+json">
|
||||||
|
{"@context":"https://schema.org","@type":"BlogPosting","author":{"@type":"Person","name":"hernikplays"},"dateModified":"2022-07-19T00:00:00+00:00","datePublished":"2022-07-19T00:00:00+00:00","description":"Pokud sledujete YouTube, určite jste už narazili na nespočet videí, které sponzoruje nějaký poskytovatel tzv. VPN. Většinou se dozvíte něco jako „vaše data jsou v nebezpečí“ a/nebo „použijte naše služby pro zabezpečení vašich dat před hackery“. Toto se samozřejmě netýká jen NordVPN, ale myslím, že ti mají tu nejagresivnější marketingovou strategii snad ze všech. ČÁST I: Kecy Kdo stojí za NordVPN NordVPN vzniklo v roce 2012 jako produkt Toma Okmana, Eimantase Sabaliauskase a Jonase Karklyse. Služba má sloužit jako tzv. Virtual Private Network neboli virtuální soukromá síť. Můžete se tak skrze NordVPN servery připojovat na internet třeba z Německa. Dle zvoleného protokolu je síťový provoz šifrován. NordVPN vlastní společnost Nord Security, která zastřešuje i ostatní produkty značky Nord. Sídlo má ve Velké Británii. Nord Security kromě VPN nabízí i vlastního správce hesel a šifrovaný cloud.","headline":"NordVPN - Jste opravdu v takovém nebezpečí?","mainEntityOfPage":{"@type":"WebPage","@id":"https://caras.cafe/bezpe%C4%8D%C3%AD/2022/07/19/nordvpn.html"},"url":"https://caras.cafe/bezpe%C4%8D%C3%AD/2022/07/19/nordvpn.html"}</script>
|
||||||
|
<!-- End Jekyll SEO tag -->
|
||||||
|
<link rel="shortcut icon" href="">
|
||||||
|
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
|
||||||
|
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/typeface-noto-sans@0.0.72/index.min.css">
|
||||||
|
<link rel="stylesheet" href="/assets/css/main.css">
|
||||||
|
<script src="/assets/js/main.js"></script><link type="application/atom+xml" rel="alternate" href="https://caras.cafe/feed.xml" title="Matyáš Caras">
|
||||||
|
<link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/highlight.js/10.1.1/styles/default.min.css">
|
||||||
|
<script src="//cdnjs.cloudflare.com/ajax/libs/highlight.js/10.1.1/highlight.min.js"></script>
|
||||||
|
<!-- and it's easy to individually load additional languages -->
|
||||||
|
<script charset="UTF-8" src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.1.1/languages/go.min.js"></script>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<script>
|
||||||
|
// Init highlight js
|
||||||
|
document.addEventListener('DOMContentLoaded', function(event) {
|
||||||
|
var els = document.querySelectorAll('pre code')
|
||||||
|
|
||||||
|
function addLangData(block) {
|
||||||
|
var outer = block.parentElement.parentElement.parentElement;
|
||||||
|
var lang = block.getAttribute('data-lang');
|
||||||
|
for (var i = 0; i < outer.classList.length; i++) {
|
||||||
|
var cls = outer.classList[i];
|
||||||
|
if (cls.startsWith('language-')) {
|
||||||
|
lang = cls;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!lang) {
|
||||||
|
cls = block.getAttribute('class');
|
||||||
|
lang = cls ? cls.replace('hljs ', '') : '';
|
||||||
|
}
|
||||||
|
if (lang.startsWith('language-')) {
|
||||||
|
lang = lang.substr(9);
|
||||||
|
}
|
||||||
|
block.setAttribute('class', 'hljs ' + lang);
|
||||||
|
block.parentNode.setAttribute('data-lang', lang);
|
||||||
|
}
|
||||||
|
|
||||||
|
function addBadge(block) {
|
||||||
|
var enabled = ('true' || 'true').toLowerCase();
|
||||||
|
if (enabled == 'true') {
|
||||||
|
var pre = block.parentElement;
|
||||||
|
pre.classList.add('badge');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function handle(block) {
|
||||||
|
addLangData(block);
|
||||||
|
addBadge(block)
|
||||||
|
hljs.highlightBlock(block);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (var i = 0; i < els.length; i++) {
|
||||||
|
var el = els[i];
|
||||||
|
handle(el);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
/* code language badge */
|
||||||
|
pre.badge::before {
|
||||||
|
content: attr(data-lang);
|
||||||
|
color: #fff;
|
||||||
|
background-color: #ff4e00;
|
||||||
|
padding: 0 .5em;
|
||||||
|
border-radius: 0 2px;
|
||||||
|
text-transform: uppercase;
|
||||||
|
text-align: center;
|
||||||
|
min-width: 32px;
|
||||||
|
display: inline-block;
|
||||||
|
position: absolute;
|
||||||
|
right: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* fix wrong badge display for firefox browser */
|
||||||
|
code > table pre::before {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<header class="site-header " role="banner">
|
||||||
|
|
||||||
|
<div class="wrapper">
|
||||||
|
<div class="site-header-inner">
|
||||||
|
<span class="site-brand"><a class="site-brand-inner" rel="author" href="/">
|
||||||
|
<img class="site-favicon" title="Matyáš Caras" src="" onerror="this.style.display='none'">
|
||||||
|
Matyáš Caras
|
||||||
|
</a>
|
||||||
|
</span><nav class="site-nav">
|
||||||
|
<input type="checkbox" id="nav-trigger" class="nav-trigger">
|
||||||
|
<label for="nav-trigger">
|
||||||
|
<span class="menu-icon">
|
||||||
|
<svg viewbox="0 0 18 15" width="18px" height="15px">
|
||||||
|
<path d="M18,1.484c0,0.82-0.665,1.484-1.484,1.484H1.484C0.665,2.969,0,2.304,0,1.484l0,0C0,0.665,0.665,0,1.484,0 h15.032C17.335,0,18,0.665,18,1.484L18,1.484z M18,7.516C18,8.335,17.335,9,16.516,9H1.484C0.665,9,0,8.335,0,7.516l0,0 c0-0.82,0.665-1.484,1.484-1.484h15.032C17.335,6.031,18,6.696,18,7.516L18,7.516z M18,13.516C18,14.335,17.335,15,16.516,15H1.484 C0.665,15,0,14.335,0,13.516l0,0c0-0.82,0.665-1.483,1.484-1.483h15.032C17.335,12.031,18,12.695,18,13.516L18,13.516z"></path>
|
||||||
|
</svg>
|
||||||
|
</span>
|
||||||
|
</label>
|
||||||
|
|
||||||
|
<div class="trigger">
|
||||||
|
<a class="page-link" href="/about.html">ABOUT</a><a class="page-link" href="/archives.html">ARCHIVES</a><a class="page-link" href="/categories.html">CATEGORIES</a><a class="page-link" href="/">HOME</a><a class="page-link" href="/tags.html">TAGS</a>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</nav>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</header>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
function initHeader() {
|
||||||
|
var lastScrollY = getScrollPos().y;
|
||||||
|
var documentElement = document.documentElement;
|
||||||
|
|
||||||
|
function storeScrollData() {
|
||||||
|
var y = getScrollPos().y;var scrollStatus = "";
|
||||||
|
|
||||||
|
if (y <= 0) {
|
||||||
|
scrollStatus = "top";
|
||||||
|
} else if ((window.innerHeight + y) >= document.body.offsetHeight) {
|
||||||
|
scrollStatus = "bottom";
|
||||||
|
} else {
|
||||||
|
var isScrollDown = (y - lastScrollY > 0) ? true : false;
|
||||||
|
scrollStatus = isScrollDown ? "down" : "up";
|
||||||
|
}
|
||||||
|
|
||||||
|
lastScrollY = y;
|
||||||
|
documentElement.setAttribute("data-scroll-status", scrollStatus);
|
||||||
|
}
|
||||||
|
|
||||||
|
window.addEventListener('scroll', function(e) {
|
||||||
|
storeScrollData();
|
||||||
|
});
|
||||||
|
|
||||||
|
storeScrollData();
|
||||||
|
}
|
||||||
|
document.addEventListener('DOMContentLoaded', initHeader);
|
||||||
|
</script>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<script>
|
||||||
|
function hashLocate(hashValue) {
|
||||||
|
hashValue = hashValue.replace(/^.*#h-/, '');
|
||||||
|
hashValue = decodeURIComponent(hashValue);
|
||||||
|
var element = document.getElementById(hashValue);
|
||||||
|
|
||||||
|
if (!element) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var header = document.querySelector('header.site-header');
|
||||||
|
var headerRect = header.getBoundingClientRect();
|
||||||
|
var headerTop = Math.floor(headerRect.top);
|
||||||
|
var headerHeight = Math.floor(headerRect.height);
|
||||||
|
var scrollPos = getScrollPos();
|
||||||
|
var offsetY = element.offsetTop - (headerTop + headerHeight + 20);
|
||||||
|
|
||||||
|
if (offsetY == scrollPos.y) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (headerTop == 0 && offsetY > scrollPos.y) {
|
||||||
|
offsetY += headerHeight + 2;
|
||||||
|
} else if (headerTop < 0 && offsetY < scrollPos.y) {
|
||||||
|
offsetY -= headerHeight - 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
smoothScrollTo(offsetY);
|
||||||
|
}
|
||||||
|
|
||||||
|
// The first event occurred
|
||||||
|
window.addEventListener('load', function(event) {
|
||||||
|
if (window.location.hash) {
|
||||||
|
hashLocate(window.location.hash);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// The first event occurred
|
||||||
|
window.addEventListener('click', function(event) {
|
||||||
|
if (event.target.tagName.toLowerCase() == 'a') {
|
||||||
|
hashLocate(event.target.getAttribute('href'));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
<div class="theme-toggle">
|
||||||
|
<input type="checkbox" id="theme-switch">
|
||||||
|
<label for="theme-switch">
|
||||||
|
<div class="toggle"></div>
|
||||||
|
<div class="names">
|
||||||
|
<p class="light">Light</p>
|
||||||
|
<p class="dark">Dark</p>
|
||||||
|
</div>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<script>
|
||||||
|
(function() {
|
||||||
|
var sw = document.getElementById('theme-switch');
|
||||||
|
var html = document.getElementsByTagName('html')[0];
|
||||||
|
var nightModeOption = ('auto' || 'auto').toLowerCase();
|
||||||
|
var storage = nightModeOption === 'manual'
|
||||||
|
? localStorage
|
||||||
|
: sessionStorage;
|
||||||
|
var themeData = loadThemeData();
|
||||||
|
|
||||||
|
function saveThemeData(data) {
|
||||||
|
storage.setItem('theme', JSON.stringify(data));
|
||||||
|
}
|
||||||
|
|
||||||
|
function loadThemeData() {
|
||||||
|
var data = storage.getItem('theme');
|
||||||
|
try {
|
||||||
|
data = JSON.parse(data ? data : '');
|
||||||
|
} catch(e) {
|
||||||
|
data = { nightShift: undefined, autoToggleAt: 0 };
|
||||||
|
saveThemeData(data);
|
||||||
|
}
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleThemeToggle(nightShift) {
|
||||||
|
themeData.nightShift = nightShift;
|
||||||
|
saveThemeData(themeData);
|
||||||
|
html.dataset.theme = nightShift ? 'dark' : 'light';
|
||||||
|
setTimeout(function() {
|
||||||
|
sw.checked = nightShift ? true : false;
|
||||||
|
}, 50);
|
||||||
|
}
|
||||||
|
|
||||||
|
function autoThemeToggle() {
|
||||||
|
// Next time point of theme toggle
|
||||||
|
var now = new Date();
|
||||||
|
var toggleAt = new Date();
|
||||||
|
var hours = now.getHours();
|
||||||
|
var nightShift = hours >= 19 || hours <=7;
|
||||||
|
|
||||||
|
if (nightShift) {
|
||||||
|
if (hours > 7) {
|
||||||
|
toggleAt.setDate(toggleAt.getDate() + 1);
|
||||||
|
}
|
||||||
|
toggleAt.setHours(7);
|
||||||
|
} else {
|
||||||
|
toggleAt.setHours(19);
|
||||||
|
}
|
||||||
|
|
||||||
|
toggleAt.setMinutes(0);
|
||||||
|
toggleAt.setSeconds(0);
|
||||||
|
toggleAt.setMilliseconds(0)
|
||||||
|
|
||||||
|
var delay = toggleAt.getTime() - now.getTime();
|
||||||
|
|
||||||
|
// auto toggle theme mode
|
||||||
|
setTimeout(function() {
|
||||||
|
handleThemeToggle(!nightShift);
|
||||||
|
}, delay);
|
||||||
|
|
||||||
|
return {
|
||||||
|
nightShift: nightShift,
|
||||||
|
toggleAt: toggleAt.getTime()
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// Listen the theme toggle event
|
||||||
|
sw.addEventListener('change', function(event) {
|
||||||
|
handleThemeToggle(event.target.checked);
|
||||||
|
});
|
||||||
|
|
||||||
|
if (nightModeOption == 'auto') {
|
||||||
|
var data = autoThemeToggle();
|
||||||
|
|
||||||
|
// Toggle theme by local setting
|
||||||
|
if (data.toggleAt > themeData.autoToggleAt) {
|
||||||
|
themeData.autoToggleAt = data.toggleAt;
|
||||||
|
handleThemeToggle(data.nightShift);
|
||||||
|
} else {
|
||||||
|
handleThemeToggle(themeData.nightShift);
|
||||||
|
}
|
||||||
|
} else if (nightModeOption == 'manual') {
|
||||||
|
handleThemeToggle(themeData.nightShift);
|
||||||
|
} else {
|
||||||
|
var nightShift = themeData.nightShift;
|
||||||
|
if (nightShift === undefined) {
|
||||||
|
nightShift = nightModeOption === 'on';
|
||||||
|
}
|
||||||
|
handleThemeToggle(nightShift);
|
||||||
|
}
|
||||||
|
})();
|
||||||
|
</script>
|
||||||
|
<div id="click-to-top" class="click-to-top">
|
||||||
|
<i class="fa fa-arrow-up"></i>
|
||||||
|
</div>
|
||||||
|
<script>
|
||||||
|
(function () {
|
||||||
|
const clickToTop = document.getElementById('click-to-top');
|
||||||
|
window.addEventListener('scroll', () => {
|
||||||
|
if (window.scrollY > 100) {
|
||||||
|
clickToTop.classList.add('show')
|
||||||
|
}else {
|
||||||
|
clickToTop.classList.remove('show')
|
||||||
|
}
|
||||||
|
});
|
||||||
|
clickToTop.addEventListener('click', () => {
|
||||||
|
window.smoothScrollTo(0);
|
||||||
|
});
|
||||||
|
})();
|
||||||
|
</script>
|
||||||
|
<main class="page-content" aria-label="Content">
|
||||||
|
<div class="wrapper">
|
||||||
|
<div class="framework">
|
||||||
|
<section class="main">
|
||||||
|
|
||||||
|
<div class="post">
|
||||||
|
<section>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<header class="post-header">
|
||||||
|
<h1 class="post-title p-name" itemprop="name headline">NordVPN - Jste opravdu v takovém nebezpečí?</h1>
|
||||||
|
<h2 class="post-subtitle">Ale je to špatná služba?</h2>
|
||||||
|
|
||||||
|
<p class="post-meta">
|
||||||
|
<time class="dt-published" datetime="2022-07-19T00:00:00+00:00" itemprop="datePublished"><i class="fa fa-calendar"></i> Jul 19, 2022
|
||||||
|
</time>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<span class="post-reading-time left-vsplit"><i class="fa fa-clock-o"></i> About 10 mins</span>
|
||||||
|
</p>
|
||||||
|
<div class="post-tags">
|
||||||
|
<a class="post-tag" href="/tags.html#vpn">#vpn</a><a class="post-tag" href="/tags.html#youtube">#youtube</a><a class="post-tag" href="/tags.html#reklamy">#reklamy</a>
|
||||||
|
</div></header>
|
||||||
|
<article class="post h-entry" itemscope itemtype="http://schema.org/BlogPosting">
|
||||||
|
|
||||||
|
<div class="post-content e-content" itemprop="articleBody">
|
||||||
|
|
||||||
|
<p>Pokud sledujete YouTube, určite jste už narazili na nespočet videí, které sponzoruje nějaký poskytovatel tzv. <strong>VPN</strong>. Většinou se dozvíte něco jako „vaše data jsou v nebezpečí“ a/nebo „použijte naše služby pro zabezpečení vašich dat před hackery“. Toto se samozřejmě netýká <em>jen</em> NordVPN, ale myslím, že ti mají tu nejagresivnější marketingovou strategii snad ze všech.</p>
|
||||||
|
<h1 id="část-i-kecy">ČÁST I: Kecy</h1>
|
||||||
|
<h2 id="kdo-stojí-za-nordvpn">Kdo stojí za NordVPN</h2>
|
||||||
|
<p>NordVPN vzniklo v roce 2012 jako produkt Toma Okmana, Eimantase Sabaliauskase a Jonase Karklyse. Služba má sloužit jako tzv. <strong>Virtual Private Network</strong> neboli virtuální soukromá síť. Můžete se tak skrze NordVPN servery připojovat na internet třeba z Německa. Dle zvoleného protokolu je síťový provoz šifrován. NordVPN vlastní společnost <a href="https://nordsecurity.com/">Nord Security</a>, která zastřešuje i ostatní produkty značky Nord. Sídlo má ve Velké Británii. Nord Security kromě VPN nabízí i vlastního správce hesel a šifrovaný cloud.</p>
|
||||||
|
|
||||||
|
<h2 id="nordvpn-a-reklamy-youtuberů">NordVPN a reklamy YouTuberů</h2>
|
||||||
|
<p>Reklamy uvnitř obsahu, tedy reklamy, které tvůrce přidává přímo do videa výměnou za přímou platbu od společnosti, jsou tu s námi celkem dlouho. Jsou <strong>efektivnější</strong> než běžné reklamy, protože je s běžným blokovačem reklam nepřeskočíte a často je tvůrci tvoří zábavným způsobem, aby je sledující sám nepřeskočil. Je to <strong>stabilnější příjem</strong> pro tvůrce obsahu, jelikož se nemusí spoléhat na výdělek z reklam, které YouTube často omezuje svými pravidli demonetizace. To je také jeden z důvodů, proč často youtubeři těmto druhům reklam vyjdou vstříc, i když nemusí mít o daném produktu žádnou znalost. Často tak ve svých videích poskytují nepravdivé či přímo zavádějící tvrzení. Než uvedu příklady, je nutné si uvědomit, že <strong>ne každý takový YouTuber poskytuje zavádějící informace</strong> nebo že <strong>NordVPN nejsou žádní podvodníci</strong>. Nejsem žádný „samozvaný IT expert“, takže mě neváhejte případně opravit. A o tvrzení „NordVPN je nejlepší VPN“ se bavit ani nebudu, o tom si udělejte obrázek sami.</p>
|
||||||
|
|
||||||
|
<h3 id="tvrzení-č-1">Tvrzení č. 1:</h3>
|
||||||
|
<p><strong><a href="https://youtu.be/51TNTCAD8fQ?t=68">Veřejné WiFi jsou nebezpečné a kdokoliv může sledovat, co na nich děláte</a></strong></p>
|
||||||
|
|
||||||
|
<p>Zalíbila se mi <a href="https://www.quora.com/Is-it-safe-to-use-internet-from-open-public-WiFi-hotspots/answer/Scott-Helms-8">odpověď Scotta Helmse</a>, který přirovnává veřejné WiFi sítě k veřejným ulicím. Pokud budete dělat hlouposti, jako je chození s přilepenou platební kartou na čele, samozřejmě vaše údaje budou odcizeny. Proto určitě není dobrý nápad dělat nákupy či se přihlašovat do bankovnictví skrz veřejné sítě. Když se na to podíváme realisticky, je relativně malá šance, že si zrovna k vám v mekáči sedl chlapec či dívka s laptopem, na kterém projíždí vaši historii vyhledávání. Navíc většina webů je zabezpečená pomocí SSL, takže přenos dat je šifrovaný. Takže při používání VPN to vlastně šifrujete ještě jednou (?), což už ale tak užitečné není. Jak <a href="https://www.eff.org/deeplinks/2020/01/why-public-wi-fi-lot-safer-you-think">píše</a> EFF, tyto hrozby jsou díky HTTPS/SSL spíše minulostí. Váš poskytovatel internetu může sledovat např. jakou stránku otevíráte (třeba github.com), nicméně neuvidí žádné parametry, které odesíláte, ani jestli navštěvujete github.com/hernikplays nebo github.com/ytdl. A to stejné mohou lidé, kteří jsou kolem vás připojení na veřejné WiFi. „V životě se bojíte spousty věcí, veřejné WiFi si můžete ze seznamu odškrtnout“.</p>
|
||||||
|
|
||||||
|
<h3 id="tvrzení-č-2">Tvrzení č. 2:</h3>
|
||||||
|
<p><strong><a href="https://youtu.be/a_LiGXtXXNQ?t=1642">[NordVPN poskytuje] maximální internetové bezpečí</a></strong></p>
|
||||||
|
|
||||||
|
<p>Jak už jsem řekl v předchozí části, před vlastní blbostí vás ani to nejlepší VPN nezachrání. Pokud máte selský rozum, tak poznáte, kam zadávat a nezadávat svoje osobní údaje, což se s rostoucí popularitou sociálního inženýrství o něco zhoršuje. A pokud si vás přecijen nějaký špičkový, státem placený hacker najde, tak mu VPN určitě nebude dělat problém.</p>
|
||||||
|
|
||||||
|
<h3 id="tvrzení-č-3">Tvrzení č. 3:</h3>
|
||||||
|
<p><strong><a href="https://youtu.be/sB8vHDS1Tcg?t=380">Zatímco [bez VPN] ti může jakýkoliv útočník vcelku jednoduše tvé zařízení nabourat, s ním jsi prakticky neviditelný […] smaže za tebou tvou stopu</a></strong></p>
|
||||||
|
|
||||||
|
<p>Toto tvrzení je možná pravdivé pro NordVPN, jelikož nabízejí službu „<a href="https://nordvpn.com/features/threat-protection/">Threat Protection</a>“, která slouží k blokování reklam, sledovacích prvků a nebezpečných webů, nicméně může vzbudit dojem, že takhle operuje každé VPN. Pokud vám jde o vaše bezpečí, neměli byste sázet na řešení jedním kliknutím, ale <a href="https://mullvad.net/en/help/first-steps-towards-online-privacy/">prozkoumat různé možnosti a nástroje</a>, včetně VPN. Pokud používáte např. služby od Googlu, už tak jim o sobě poskytujete dostatek údajů.
|
||||||
|
Útočník také nemůže „vcelku jednoduše“ vaše zařízení nabourat, to lze pouze pokud jste se rozhodli používat Windows 10 a nenainstalovali jste žádné aktualizace. V tom případě je váš systém děravý jak ementál a to už asi nikdo, kromě vás, nespraví. Takže aktualizujte svůj systém a aplikace jak to jen půjde!</p>
|
||||||
|
|
||||||
|
<h3 id="tvrzení-č-4">Tvrzení č. 4:</h3>
|
||||||
|
<p><strong>Můžeš sledovat obsah uzamknutý pro určité země</strong></p>
|
||||||
|
|
||||||
|
<p>To je samozřejmě pravda, nicméně některé služby se aktivně pokouší zamezit přístup uživatelům s VPN identifikováním IP adresy daného VPN serveru.</p>
|
||||||
|
|
||||||
|
<h3 id="tvrzení-č-5">Tvrzení č. 5:</h3>
|
||||||
|
<p><strong><a href="https://youtu.be/sB8vHDS1Tcg?t=436">[NordVPN] ti zrychlí internet</a></strong></p>
|
||||||
|
|
||||||
|
<p>Když máte od poskytovatele internetu omezené stahování na 10 MB/s, nemůžete očekávat, že když budete ze serveru, kde může být zároveň napojeno X tisíc lidí a je někde v tramtárii, stahovat soubor, že se bude stahovat rychleji. <a href="https://www.cloudflare.com/learning/access-management/vpn-speed/">Pouze ve specifických případech</a>, kdy například poskytovatel internetu záměrně zpomaluje připojení např. k Netflixu, můžete pocítit zrychlení.</p>
|
||||||
|
|
||||||
|
<h2 id="nordvpn-a-ještě-divnější-praktiky">NordVPN a ještě divnější praktiky</h2>
|
||||||
|
<p>Zavádějícími tvrzeními to však nekončí, věděli jste, že na mnoha webech s hodnoceními VPN služeb si můžete určitou pozici <strong>jednoduše koupit</strong>? Ano, dostáváme se do takzvaného <strong>provizního systému</strong>, tedy systému, ve kterém firma proplatí provizi z provedeného nákupu jistému zprostředkovateli. Vtipná věc je, že některé tyto firmy <a href="https://blog.windscribe.com/consolidation-of-the-vpn-industry-spells-trouble-for-the-consumer-57e638634cf0/">vlastní</a> zároveň takovéto <em>„publikace“</em> a samotné VPN služby, jako např. Kape Technologies, která se původně <strong>zabývala adwarem</strong>, nyní vlastní např. ExpressVPN a zároveň web VPNmentor. NordVPN není výjimkou s jejich provizním systémem nabízejícím až 40% část z ceny nákupu. Dá se těmto „hodnocením“ vůbec věřit? Některým nejspíš ano, je dobré však zkontrolovat, jestli publikaci nevlastní nějaká mediální společnost.</p>
|
||||||
|
|
||||||
|
<p>Dále můžeme na webu NordVPN, služby, která vám má pomoct chránit vaše soukromí a <em>„zneviditelnit se“</em>, <strong>najít spoustu sledovacích prvků</strong>, jako např. sledovací prvky Twitter Ads, Google Ads, Analytics a Bing.</p>
|
||||||
|
|
||||||
|
<p><img src="/assets/images/vpn/14.png" alt="Ukázka sledovacích prvků na stránce NordVPN"></p>
|
||||||
|
|
||||||
|
<h1 id="část-ii-vzhůru-dolů">Část II: Vzhůru dolů</h1>
|
||||||
|
<p>Ano, je čas, abych se vydal do králičí nory a NordVPN otestoval. Hned na úvodní stránce na vás vyskočí tuny slev. „Nakupte do X hodin a získejte slevu X%“. No tak to abych si pohnul, co? Samozřejmě, že ne. Úplně stejná stránka s úplně stejným odpočtem se mi zobrazila i včera. Navíc tato sleva platí jen na roční plány a já s NordVPN chci strávit co nejméně času. Takže beru jejich standardních 10,49 eur na měsíc, které naštěstí také nabízejí s garancí vrácení peněz. Samozřejmě k tomu ještě musíte přičíst daně, z čehož máme 12,69 <em>(nice)</em>. Použil jsem jejich <a href="https://www.theregister.com/2020/03/06/nordvpn_no_auth_needed_view_user_payments/">(ne)</a>bezpečnou bránu a vzdal se svých těžce vydělaných peněz.
|
||||||
|
Jejich stránka, ze které jsem měl stáhnout klienta, se chvástala „online zabezpečením pro všechny velké linuxové distribuce“, takže je super, že nabízejí stažení pouze pro distribuce založené na Debianu a RHEL, když jsem na Archu. Samozřejmě nic, co by Arch komunita nevyřešila.</p>
|
||||||
|
|
||||||
|
<p>Nemůžu hodnotit jednoduchost prostředí, protože <em>to na linuxu ani není</em>. Nicméně se podíváme na rychlost.</p>
|
||||||
|
<h2 id="rychlosti-velmi-stručně">Rychlosti (velmi stručně)</h2>
|
||||||
|
<p><img src="/assets/images/vpn/13.png" alt="Výchozí rychlost (bez VPN, WiFi)"></p>
|
||||||
|
|
||||||
|
<p>Výchozí rychlost (bez VPN, WiFi)</p>
|
||||||
|
|
||||||
|
<p><img src="/assets/images/vpn/12.png" alt="NordVPN Germany #1078"></p>
|
||||||
|
|
||||||
|
<p>NordVPN Germany #1078</p>
|
||||||
|
|
||||||
|
<p><img src="/assets/images/vpn/11.png" alt="Rychlost stahování torrentů na serverech v Německu"></p>
|
||||||
|
|
||||||
|
<p>Pokles rychlosti, úplně normální, protože pakety urazí větší vzdálenost. Streamování YouTube ve Full HD má pocititelné zpomalení/zasekávání. Rychlosti stahování torrentů se držely v průměru mezi 600 a 700 KB/s.</p>
|
||||||
|
|
||||||
|
<p><img src="/assets/images/vpn/10.png" alt="NordVPN USA #9363"></p>
|
||||||
|
|
||||||
|
<p>NordVPN USA #9363</p>
|
||||||
|
|
||||||
|
<p><img src="/assets/images/vpn/9.png" alt="Rychlost stahování torrentů na serverech v USA"></p>
|
||||||
|
|
||||||
|
<p>Tady už změnu pocítíte víc. Zajímavé však je, že se videa z YouTube ve Full HD načítají rychleji. Nicméně rychlosti stahování torrentů skákaly nahorů a dolů.</p>
|
||||||
|
|
||||||
|
<h2 id="threat-protection-lite">Threat Protection Lite</h2>
|
||||||
|
<p>Další funkce dostupná pro linux je <a href="https://support.nordvpn.com/General-info/Features/1047407402/What-are-Threat-Protection-and-Threat-Protection-Lite.htm">TPL</a>, který má blokovat reklamy, nebezpečné stránky a pochybná připojení během připojení na VPN.</p>
|
||||||
|
|
||||||
|
<p>Na webu NordVPN zablokoval sledovací prvky Twitteru, Bingu a Googlu, nicméně vynechal Google Analytics (což je asi pochopitelné, když o blokování sledujících prvků není ani zmínka).</p>
|
||||||
|
|
||||||
|
<p><img src="/assets/images/vpn/8.png" alt="Zablokované sledovací prvky na NordVPN.com"></p>
|
||||||
|
|
||||||
|
<p>Na YouTube neblokuje reklamy vůbec,
|
||||||
|
<img src="/assets/images/vpn/7.png" alt="Blokování reklam s TPL na YouTube"></p>
|
||||||
|
|
||||||
|
<p>ale na jiných webech ano.
|
||||||
|
<img src="/assets/images/vpn/6.png" alt="Blokování reklam s TPL na jiných webech"></p>
|
||||||
|
|
||||||
|
<p>Takže nahradí blokovače jako <a href="https://github.com/gorhill/uBlock#readme">uBlock Origin</a>? Řekl bych, že ne.</p>
|
||||||
|
<h1 id="část-iii-opouštíme-králičí-noru">Část III: Opouštíme králičí noru</h1>
|
||||||
|
<p>Dobře, mám trochu NordVPN na vlastní kůži, ale teď se ho chci zbavit. Takže jdeme žádat zpět peníze.
|
||||||
|
Zrušení obnovení předplatného bylo relativně snadné, v nastavení účtu stačilo kliknout na „Zrušit“.</p>
|
||||||
|
|
||||||
|
<p><img src="/assets/images/vpn/5.png" alt="Zrušení obnovení předplatného"></p>
|
||||||
|
|
||||||
|
<p>Teď přijde ta bolestivější část, a to žádání o vrácení peněz. Dle podmínek máte 30 dní od prvního nákupu nárok na vrácení peněz.
|
||||||
|
NordVPN říká, že podpora funguje 24/7. Na začátku jste spojeni s robotem, který vás postupně přepojí na živého člověka.</p>
|
||||||
|
|
||||||
|
<p><img src="/assets/images/vpn/4.png" alt="Robot na podpoře"></p>
|
||||||
|
|
||||||
|
<p>Člověk se skutečně objevil.</p>
|
||||||
|
|
||||||
|
<p><img src="/assets/images/vpn/3.png" alt="Chat s podporu část 1"></p>
|
||||||
|
|
||||||
|
<p>Chvilku mu to trvalo, takže jsem ho popostrčil.</p>
|
||||||
|
|
||||||
|
<p><img src="/assets/images/vpn/2.png" alt="Chat s podporu část 2"></p>
|
||||||
|
|
||||||
|
<p>Řekl jsem mu slušně „Ne, díky“, po čemž mi nastavil vrácení peněz.</p>
|
||||||
|
|
||||||
|
<p><img src="/assets/images/vpn/1.png" alt="Chat s podporu část 3"></p>
|
||||||
|
|
||||||
|
<p>Celkem rychle vyřízeno, dobrá práce. Zvláštní mi přišlo jen, že si mě nijak neověřil, pouze jsem na začátku poskytl e-mail, z čehož (doufám) vydedukoval, že to patří k mému účtu.
|
||||||
|
Další den mi skutečně odebrali přístup k jejich službě, nicméně peníze jsou stále zablokované, tak snad si banka pohne.</p>
|
||||||
|
|
||||||
|
<h1 id="část-v-závěr">Část V: Závěr</h1>
|
||||||
|
<p>Takže na závěr:
|
||||||
|
<strong>Je VPN úplně zbytečný nástroj?</strong> Určitě ne.</p>
|
||||||
|
|
||||||
|
<p><strong>Můžou youtubeři za to, že někdy neříkají pravdivé věci?</strong> Spíš ne, nemůžete čekat každého youtubera, že je expert přes sítě, jenom se snaží se uživit a vyloženě lži říkají opravdu málokdy.</p>
|
||||||
|
|
||||||
|
<p><strong>Snaží se NordVPN prodat hadí olej a moje děti na darknetu?</strong> Nejspíš ne, ale měli by víc sjednotit prezentování co se týče sponzorování youtuberů.</p>
|
||||||
|
|
||||||
|
<p><strong>Můžu důvěřovat NordVPN?</strong> S jejich velikostí nejspíš ano.</p>
|
||||||
|
|
||||||
|
<p><strong>Doporučil bych NordVPN?</strong> Ne. Pokud chcete opravdu 100% anonymitu a hlavně no-bullshit produkt, použijte něco jako Mullvad <em>(toto není sponzorováno, sám ho používám a je fajn)</em>, který nenabízí žádné posrané slevy kvůli všemu možnému a kde dokonce můžete platit v hotovosti, ale nezapomeňte, že VPNkem to nekončí. Podívejte se na <a href="https://ssd.eff.org/">Surveillance Self-Defense</a> od EFF pro více tipů na ochranu vašeho soukromí.</p>
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</article>
|
||||||
|
<div class="post-nav">
|
||||||
|
<a class="previous" href="/vychyt%C3%A1vky/2022/05/31/codespaces.html" title="GitHub Codespaces aneb VS Code na VPS">GitHub Codespaces aneb VS Code na...</a><a class="next" href="/tutori%C3%A1l/2022/10/22/rpi-arch.html" title="Instalujeme Arch Linux ARM na Raspberry Pi 3">Instalujeme Arch Linux ARM na Raspberry...</a>
|
||||||
|
</div>
|
||||||
|
<div class="post-related">
|
||||||
|
<div>Related Articles</div>
|
||||||
|
<ul>
|
||||||
|
<li><a class="post-link" href="/vychyt%C3%A1vky/2022/05/31/codespaces.html" title="Instalujeme Arch Linux ARM na Raspberry Pi 3">GitHub Codespaces aneb VS Code na VPS</a></li>
|
||||||
|
<li><a class="post-link" href="/programov%C3%A1n%C3%AD/2022/05/22/automatizace.html" title="Instalujeme Arch Linux ARM na Raspberry Pi 3">Automatizace, automatizace, automatizace</a></li>
|
||||||
|
<li><a class="post-link" href="/bezpe%C4%8D%C3%AD/2022/07/19/nordvpn.html" title="Instalujeme Arch Linux ARM na Raspberry Pi 3">NordVPN - Jste opravdu v takovém nebezpečí?</a></li>
|
||||||
|
<li><a class="post-link" href="/tutori%C3%A1l/2022/10/22/rpi-arch.html" title="Instalujeme Arch Linux ARM na Raspberry Pi 3">Instalujeme Arch Linux ARM na Raspberry Pi 3</a></li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
<div class="post-comments"> <div id="gitment_thread" class="giscus"></div>
|
||||||
|
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/theme-next/theme-next-gitment@1/default.css">
|
||||||
|
<script src="https://cdn.jsdelivr.net/gh/theme-next/theme-next-gitment@1/gitment.browser.js"></script>
|
||||||
|
<script src="https://giscus.app/client.js" data-repo="hernikplays/blog" data-repo-id="R_kgDOHr2B6w" data-category="General" data-category-id="DIC_kwDOHr2B684CSIhA" data-mapping="pathname" data-strict="0" data-reactions-enabled="1" data-emit-metadata="0" data-input-position="top" data-theme="transparent_dark" data-lang="en" data-loading="lazy" crossorigin="anonymous" async>
|
||||||
|
</script>
|
||||||
|
</div></section>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
</section>
|
||||||
|
<section class="sidebar" style="margin-left: 15px;">
|
||||||
|
<!-- Get sidebar items --></section>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</main><footer class="site-footer h-card">
|
||||||
|
<data class="u-url" href="/"></data>
|
||||||
|
|
||||||
|
<div class="wrapper">
|
||||||
|
<div class="site-footer-inner">
|
||||||
|
<div>Copyright © 2021-2022 hernikplays</div>
|
||||||
|
<div>Powered by <a title="Jekyll is a simple, blog-aware, static site
|
||||||
|
generator." href="https://jekyllrb.com/">Jekyll</a> & <a title="Yat, yet
|
||||||
|
another theme." href="https://github.com/jeffreytse/jekyll-theme-yat">Yat Theme</a>.</div>
|
||||||
|
<div><a rel="me" href="https://social.linux.pizza/@hernik">Mastodon</a></div>
|
||||||
|
<div class="footer-col rss-subscribe">Subscribe <a href="/feed.xml">via RSS</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</footer>
|
||||||
|
</body>
|
||||||
|
</html>
|
789
categories.html
Normal file
|
@ -0,0 +1,789 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
|
<meta name="google-translate-customization" content="108d9124921d80c3-80e20d618ff053c8-g4f02ec6f3dba68b7-c">
|
||||||
|
<!-- Begin Jekyll SEO tag v2.8.0 -->
|
||||||
|
<title>Categories | Matyáš Caras</title>
|
||||||
|
<meta name="generator" content="Jekyll v4.3.1">
|
||||||
|
<meta property="og:title" content="Categories">
|
||||||
|
<meta name="author" content="hernikplays">
|
||||||
|
<meta property="og:locale" content="en_US">
|
||||||
|
<meta name="description" content="Welcome to my website/blog, full of weird stuff written by yours truly.">
|
||||||
|
<meta property="og:description" content="Welcome to my website/blog, full of weird stuff written by yours truly.">
|
||||||
|
<link rel="canonical" href="https://caras.cafe/categories.html">
|
||||||
|
<meta property="og:url" content="https://caras.cafe/categories.html">
|
||||||
|
<meta property="og:site_name" content="Matyáš Caras">
|
||||||
|
<meta property="og:type" content="website">
|
||||||
|
<meta name="twitter:card" content="summary">
|
||||||
|
<meta property="twitter:title" content="Categories">
|
||||||
|
<script type="application/ld+json">
|
||||||
|
{"@context":"https://schema.org","@type":"WebPage","author":{"@type":"Person","name":"hernikplays"},"description":"Welcome to my website/blog, full of weird stuff written by yours truly.","headline":"Categories","url":"https://caras.cafe/categories.html"}</script>
|
||||||
|
<!-- End Jekyll SEO tag -->
|
||||||
|
<link rel="shortcut icon" href="">
|
||||||
|
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
|
||||||
|
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/typeface-noto-sans@0.0.72/index.min.css">
|
||||||
|
<link rel="stylesheet" href="/assets/css/main.css">
|
||||||
|
<script src="/assets/js/main.js"></script><link type="application/atom+xml" rel="alternate" href="https://caras.cafe/feed.xml" title="Matyáš Caras">
|
||||||
|
<link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/highlight.js/10.1.1/styles/default.min.css">
|
||||||
|
<script src="//cdnjs.cloudflare.com/ajax/libs/highlight.js/10.1.1/highlight.min.js"></script>
|
||||||
|
<!-- and it's easy to individually load additional languages -->
|
||||||
|
<script charset="UTF-8" src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.1.1/languages/go.min.js"></script>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<script>
|
||||||
|
// Init highlight js
|
||||||
|
document.addEventListener('DOMContentLoaded', function(event) {
|
||||||
|
var els = document.querySelectorAll('pre code')
|
||||||
|
|
||||||
|
function addLangData(block) {
|
||||||
|
var outer = block.parentElement.parentElement.parentElement;
|
||||||
|
var lang = block.getAttribute('data-lang');
|
||||||
|
for (var i = 0; i < outer.classList.length; i++) {
|
||||||
|
var cls = outer.classList[i];
|
||||||
|
if (cls.startsWith('language-')) {
|
||||||
|
lang = cls;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!lang) {
|
||||||
|
cls = block.getAttribute('class');
|
||||||
|
lang = cls ? cls.replace('hljs ', '') : '';
|
||||||
|
}
|
||||||
|
if (lang.startsWith('language-')) {
|
||||||
|
lang = lang.substr(9);
|
||||||
|
}
|
||||||
|
block.setAttribute('class', 'hljs ' + lang);
|
||||||
|
block.parentNode.setAttribute('data-lang', lang);
|
||||||
|
}
|
||||||
|
|
||||||
|
function addBadge(block) {
|
||||||
|
var enabled = ('true' || 'true').toLowerCase();
|
||||||
|
if (enabled == 'true') {
|
||||||
|
var pre = block.parentElement;
|
||||||
|
pre.classList.add('badge');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function handle(block) {
|
||||||
|
addLangData(block);
|
||||||
|
addBadge(block)
|
||||||
|
hljs.highlightBlock(block);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (var i = 0; i < els.length; i++) {
|
||||||
|
var el = els[i];
|
||||||
|
handle(el);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
/* code language badge */
|
||||||
|
pre.badge::before {
|
||||||
|
content: attr(data-lang);
|
||||||
|
color: #fff;
|
||||||
|
background-color: #ff4e00;
|
||||||
|
padding: 0 .5em;
|
||||||
|
border-radius: 0 2px;
|
||||||
|
text-transform: uppercase;
|
||||||
|
text-align: center;
|
||||||
|
min-width: 32px;
|
||||||
|
display: inline-block;
|
||||||
|
position: absolute;
|
||||||
|
right: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* fix wrong badge display for firefox browser */
|
||||||
|
code > table pre::before {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<header class="site-header " role="banner">
|
||||||
|
|
||||||
|
<div class="wrapper">
|
||||||
|
<div class="site-header-inner">
|
||||||
|
<span class="site-brand"><a class="site-brand-inner" rel="author" href="/">
|
||||||
|
<img class="site-favicon" title="Matyáš Caras" src="" onerror="this.style.display='none'">
|
||||||
|
Matyáš Caras
|
||||||
|
</a>
|
||||||
|
</span><nav class="site-nav">
|
||||||
|
<input type="checkbox" id="nav-trigger" class="nav-trigger">
|
||||||
|
<label for="nav-trigger">
|
||||||
|
<span class="menu-icon">
|
||||||
|
<svg viewbox="0 0 18 15" width="18px" height="15px">
|
||||||
|
<path d="M18,1.484c0,0.82-0.665,1.484-1.484,1.484H1.484C0.665,2.969,0,2.304,0,1.484l0,0C0,0.665,0.665,0,1.484,0 h15.032C17.335,0,18,0.665,18,1.484L18,1.484z M18,7.516C18,8.335,17.335,9,16.516,9H1.484C0.665,9,0,8.335,0,7.516l0,0 c0-0.82,0.665-1.484,1.484-1.484h15.032C17.335,6.031,18,6.696,18,7.516L18,7.516z M18,13.516C18,14.335,17.335,15,16.516,15H1.484 C0.665,15,0,14.335,0,13.516l0,0c0-0.82,0.665-1.483,1.484-1.483h15.032C17.335,12.031,18,12.695,18,13.516L18,13.516z"></path>
|
||||||
|
</svg>
|
||||||
|
</span>
|
||||||
|
</label>
|
||||||
|
|
||||||
|
<div class="trigger">
|
||||||
|
<a class="page-link" href="/about.html">ABOUT</a><a class="page-link" href="/archives.html">ARCHIVES</a><a class="page-link" href="/categories.html">CATEGORIES</a><a class="page-link" href="/">HOME</a><a class="page-link" href="/tags.html">TAGS</a>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</nav>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</header>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
function initHeader() {
|
||||||
|
var lastScrollY = getScrollPos().y;
|
||||||
|
var documentElement = document.documentElement;
|
||||||
|
|
||||||
|
function storeScrollData() {
|
||||||
|
var y = getScrollPos().y;var scrollStatus = "";
|
||||||
|
|
||||||
|
if (y <= 0) {
|
||||||
|
scrollStatus = "top";
|
||||||
|
} else if ((window.innerHeight + y) >= document.body.offsetHeight) {
|
||||||
|
scrollStatus = "bottom";
|
||||||
|
} else {
|
||||||
|
var isScrollDown = (y - lastScrollY > 0) ? true : false;
|
||||||
|
scrollStatus = isScrollDown ? "down" : "up";
|
||||||
|
}
|
||||||
|
|
||||||
|
lastScrollY = y;
|
||||||
|
documentElement.setAttribute("data-scroll-status", scrollStatus);
|
||||||
|
}
|
||||||
|
|
||||||
|
window.addEventListener('scroll', function(e) {
|
||||||
|
storeScrollData();
|
||||||
|
});
|
||||||
|
|
||||||
|
storeScrollData();
|
||||||
|
}
|
||||||
|
document.addEventListener('DOMContentLoaded', initHeader);
|
||||||
|
</script>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<script>
|
||||||
|
function hashLocate(hashValue) {
|
||||||
|
hashValue = hashValue.replace(/^.*#h-/, '');
|
||||||
|
hashValue = decodeURIComponent(hashValue);
|
||||||
|
var element = document.getElementById(hashValue);
|
||||||
|
|
||||||
|
if (!element) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var header = document.querySelector('header.site-header');
|
||||||
|
var headerRect = header.getBoundingClientRect();
|
||||||
|
var headerTop = Math.floor(headerRect.top);
|
||||||
|
var headerHeight = Math.floor(headerRect.height);
|
||||||
|
var scrollPos = getScrollPos();
|
||||||
|
var offsetY = element.offsetTop - (headerTop + headerHeight + 20);
|
||||||
|
|
||||||
|
if (offsetY == scrollPos.y) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (headerTop == 0 && offsetY > scrollPos.y) {
|
||||||
|
offsetY += headerHeight + 2;
|
||||||
|
} else if (headerTop < 0 && offsetY < scrollPos.y) {
|
||||||
|
offsetY -= headerHeight - 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
smoothScrollTo(offsetY);
|
||||||
|
}
|
||||||
|
|
||||||
|
// The first event occurred
|
||||||
|
window.addEventListener('load', function(event) {
|
||||||
|
if (window.location.hash) {
|
||||||
|
hashLocate(window.location.hash);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// The first event occurred
|
||||||
|
window.addEventListener('click', function(event) {
|
||||||
|
if (event.target.tagName.toLowerCase() == 'a') {
|
||||||
|
hashLocate(event.target.getAttribute('href'));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
<div class="theme-toggle">
|
||||||
|
<input type="checkbox" id="theme-switch">
|
||||||
|
<label for="theme-switch">
|
||||||
|
<div class="toggle"></div>
|
||||||
|
<div class="names">
|
||||||
|
<p class="light">Light</p>
|
||||||
|
<p class="dark">Dark</p>
|
||||||
|
</div>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<script>
|
||||||
|
(function() {
|
||||||
|
var sw = document.getElementById('theme-switch');
|
||||||
|
var html = document.getElementsByTagName('html')[0];
|
||||||
|
var nightModeOption = ('auto' || 'auto').toLowerCase();
|
||||||
|
var storage = nightModeOption === 'manual'
|
||||||
|
? localStorage
|
||||||
|
: sessionStorage;
|
||||||
|
var themeData = loadThemeData();
|
||||||
|
|
||||||
|
function saveThemeData(data) {
|
||||||
|
storage.setItem('theme', JSON.stringify(data));
|
||||||
|
}
|
||||||
|
|
||||||
|
function loadThemeData() {
|
||||||
|
var data = storage.getItem('theme');
|
||||||
|
try {
|
||||||
|
data = JSON.parse(data ? data : '');
|
||||||
|
} catch(e) {
|
||||||
|
data = { nightShift: undefined, autoToggleAt: 0 };
|
||||||
|
saveThemeData(data);
|
||||||
|
}
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleThemeToggle(nightShift) {
|
||||||
|
themeData.nightShift = nightShift;
|
||||||
|
saveThemeData(themeData);
|
||||||
|
html.dataset.theme = nightShift ? 'dark' : 'light';
|
||||||
|
setTimeout(function() {
|
||||||
|
sw.checked = nightShift ? true : false;
|
||||||
|
}, 50);
|
||||||
|
}
|
||||||
|
|
||||||
|
function autoThemeToggle() {
|
||||||
|
// Next time point of theme toggle
|
||||||
|
var now = new Date();
|
||||||
|
var toggleAt = new Date();
|
||||||
|
var hours = now.getHours();
|
||||||
|
var nightShift = hours >= 19 || hours <=7;
|
||||||
|
|
||||||
|
if (nightShift) {
|
||||||
|
if (hours > 7) {
|
||||||
|
toggleAt.setDate(toggleAt.getDate() + 1);
|
||||||
|
}
|
||||||
|
toggleAt.setHours(7);
|
||||||
|
} else {
|
||||||
|
toggleAt.setHours(19);
|
||||||
|
}
|
||||||
|
|
||||||
|
toggleAt.setMinutes(0);
|
||||||
|
toggleAt.setSeconds(0);
|
||||||
|
toggleAt.setMilliseconds(0)
|
||||||
|
|
||||||
|
var delay = toggleAt.getTime() - now.getTime();
|
||||||
|
|
||||||
|
// auto toggle theme mode
|
||||||
|
setTimeout(function() {
|
||||||
|
handleThemeToggle(!nightShift);
|
||||||
|
}, delay);
|
||||||
|
|
||||||
|
return {
|
||||||
|
nightShift: nightShift,
|
||||||
|
toggleAt: toggleAt.getTime()
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// Listen the theme toggle event
|
||||||
|
sw.addEventListener('change', function(event) {
|
||||||
|
handleThemeToggle(event.target.checked);
|
||||||
|
});
|
||||||
|
|
||||||
|
if (nightModeOption == 'auto') {
|
||||||
|
var data = autoThemeToggle();
|
||||||
|
|
||||||
|
// Toggle theme by local setting
|
||||||
|
if (data.toggleAt > themeData.autoToggleAt) {
|
||||||
|
themeData.autoToggleAt = data.toggleAt;
|
||||||
|
handleThemeToggle(data.nightShift);
|
||||||
|
} else {
|
||||||
|
handleThemeToggle(themeData.nightShift);
|
||||||
|
}
|
||||||
|
} else if (nightModeOption == 'manual') {
|
||||||
|
handleThemeToggle(themeData.nightShift);
|
||||||
|
} else {
|
||||||
|
var nightShift = themeData.nightShift;
|
||||||
|
if (nightShift === undefined) {
|
||||||
|
nightShift = nightModeOption === 'on';
|
||||||
|
}
|
||||||
|
handleThemeToggle(nightShift);
|
||||||
|
}
|
||||||
|
})();
|
||||||
|
</script>
|
||||||
|
<div id="click-to-top" class="click-to-top">
|
||||||
|
<i class="fa fa-arrow-up"></i>
|
||||||
|
</div>
|
||||||
|
<script>
|
||||||
|
(function () {
|
||||||
|
const clickToTop = document.getElementById('click-to-top');
|
||||||
|
window.addEventListener('scroll', () => {
|
||||||
|
if (window.scrollY > 100) {
|
||||||
|
clickToTop.classList.add('show')
|
||||||
|
}else {
|
||||||
|
clickToTop.classList.remove('show')
|
||||||
|
}
|
||||||
|
});
|
||||||
|
clickToTop.addEventListener('click', () => {
|
||||||
|
window.smoothScrollTo(0);
|
||||||
|
});
|
||||||
|
})();
|
||||||
|
</script>
|
||||||
|
<main class="page-content" aria-label="Content">
|
||||||
|
<div class="wrapper">
|
||||||
|
<div class="framework">
|
||||||
|
<section class="main">
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<div class="page-segments">
|
||||||
|
<ul class="page-segments-list">
|
||||||
|
|
||||||
|
<h2 id="bezpečí" class="segment-name">bezpečí</h2>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<li>
|
||||||
|
<span class="post-meta">Jul 19, 2022</span>
|
||||||
|
<span>
|
||||||
|
<a class="post-link" href="/bezpe%C4%8D%C3%AD/2022/07/19/nordvpn.html">
|
||||||
|
NordVPN - Jste opravdu v takovém nebezpečí?
|
||||||
|
</a>
|
||||||
|
</span>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<h2 id="programování" class="segment-name">programování</h2>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<li>
|
||||||
|
<span class="post-meta">May 22, 2022</span>
|
||||||
|
<span>
|
||||||
|
<a class="post-link" href="/programov%C3%A1n%C3%AD/2022/05/22/automatizace.html">
|
||||||
|
Automatizace, automatizace, automatizace
|
||||||
|
</a>
|
||||||
|
</span>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<h2 id="tutoriál" class="segment-name">tutoriál</h2>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<li>
|
||||||
|
<span class="post-meta">Oct 22, 2022</span>
|
||||||
|
<span>
|
||||||
|
<a class="post-link" href="/tutori%C3%A1l/2022/10/22/rpi-arch.html">
|
||||||
|
Instalujeme Arch Linux ARM na Raspberry Pi 3
|
||||||
|
</a>
|
||||||
|
</span>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<h2 id="vychytávky" class="segment-name">vychytávky</h2>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<li>
|
||||||
|
<span class="post-meta">May 31, 2022</span>
|
||||||
|
<span>
|
||||||
|
<a class="post-link" href="/vychyt%C3%A1vky/2022/05/31/codespaces.html">
|
||||||
|
GitHub Codespaces aneb VS Code na VPS
|
||||||
|
</a>
|
||||||
|
</span>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
</section>
|
||||||
|
<section class="sidebar" style="margin-left: 15px;">
|
||||||
|
<!-- Get sidebar items -->
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<div class="common-list">
|
||||||
|
<ul>
|
||||||
|
<li>
|
||||||
|
<a href="/index.html">
|
||||||
|
All<span>4</span>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
|
||||||
|
<li>
|
||||||
|
<a href="/categories.html#h-bezpe%C4%8D%C3%AD">
|
||||||
|
bezpečí <span>1</span>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<li>
|
||||||
|
<a href="/categories.html#h-programov%C3%A1n%C3%AD">
|
||||||
|
programování <span>1</span>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<li>
|
||||||
|
<a href="/categories.html#h-tutori%C3%A1l">
|
||||||
|
tutoriál <span>1</span>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<li>
|
||||||
|
<a href="/categories.html#h-vychyt%C3%A1vky">
|
||||||
|
vychytávky <span>1</span>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</section>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</main><footer class="site-footer h-card">
|
||||||
|
<data class="u-url" href="/"></data>
|
||||||
|
|
||||||
|
<div class="wrapper">
|
||||||
|
<div class="site-footer-inner">
|
||||||
|
<div>Copyright © 2021-2022 hernikplays</div>
|
||||||
|
<div>Powered by <a title="Jekyll is a simple, blog-aware, static site
|
||||||
|
generator." href="https://jekyllrb.com/">Jekyll</a> & <a title="Yat, yet
|
||||||
|
another theme." href="https://github.com/jeffreytse/jekyll-theme-yat">Yat Theme</a>.</div>
|
||||||
|
<div><a rel="me" href="https://social.linux.pizza/@hernik">Mastodon</a></div>
|
||||||
|
<div class="footer-col rss-subscribe">Subscribe <a href="/feed.xml">via RSS</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</footer>
|
||||||
|
</body>
|
||||||
|
</html>
|
247
feed.xml
Normal file
|
@ -0,0 +1,247 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="4.3.1">Jekyll</generator><link href="https://caras.cafe/feed.xml" rel="self" type="application/atom+xml" /><link href="https://caras.cafe/" rel="alternate" type="text/html" /><updated>2022-11-05T11:35:48+00:00</updated><id>https://caras.cafe/feed.xml</id><title type="html">Matyáš Caras</title><subtitle>Welcome to my website/blog, full of weird stuff written by yours truly.</subtitle><author><name>hernikplays</name></author><entry><title type="html">Instalujeme Arch Linux ARM na Raspberry Pi 3</title><link href="https://caras.cafe/tutori%C3%A1l/2022/10/22/rpi-arch.html" rel="alternate" type="text/html" title="Instalujeme Arch Linux ARM na Raspberry Pi 3" /><published>2022-10-22T00:00:00+00:00</published><updated>2022-10-22T00:00:00+00:00</updated><id>https://caras.cafe/tutori%C3%A1l/2022/10/22/rpi-arch</id><content type="html" xml:base="https://caras.cafe/tutori%C3%A1l/2022/10/22/rpi-arch.html"><![CDATA[<p><img src="https://archlinuxarm.org/public/images/alarm.png" alt="Arch Linux ARM logo" /></p>
|
||||||
|
|
||||||
|
<p>Raspbian OS už je ohraný. Pojďme si nainstalovat <a href="https://archlinuxarm.org/platforms/armv8/broadcom/raspberry-pi-3">ARM verzi Arch Linuxu</a> na Raspberry Pi 3. Proces je relativně prostý.</p>
|
||||||
|
|
||||||
|
<h1 id="připravujeme-sd-kartu">Připravujeme SD kartu</h1>
|
||||||
|
<p>Nejdřív je nutné SD kartu naformátovat a rozdělit oddíly. Můžete to udělat svým oblíbeným způsobem, já použiji GUI nástroj GParted.</p>
|
||||||
|
|
||||||
|
<p>Odstraníme všechny oddíly skrz kontextové menu pravého kliknutí a potvrzení fajfkou.</p>
|
||||||
|
|
||||||
|
<p><img src="/assets/images/rpi-arch/01.png" alt="Odstraněné oddíly v GParted" /></p>
|
||||||
|
|
||||||
|
<p>Následně vytvoříme jeden FAT32 oddíl, který bude sloužit jako bootovací. Bude stačit 128 MiB.</p>
|
||||||
|
|
||||||
|
<p><img src="/assets/images/rpi-arch/02.png" alt="Vytváření FAT32 oddílu v GParted" /></p>
|
||||||
|
|
||||||
|
<p>Druhý oddíl bude náš systémový, který bude ext4.</p>
|
||||||
|
|
||||||
|
<p><img src="/assets/images/rpi-arch/03.png" alt="Vytváření ext4 oddílu v GParted" /></p>
|
||||||
|
|
||||||
|
<p>Jakmile fajfkou potvrdíme a necháme oddíly vytvořit, můžete je ještě zformátovat, nicméně je nejdůležitější nastavit <code class="language-plaintext highlighter-rouge">boot</code> příznak na našem boot oddílu skrz kontextové menu.</p>
|
||||||
|
|
||||||
|
<p><img src="/assets/images/rpi-arch/04.png" alt="Výběr příznaků v GParted" /></p>
|
||||||
|
|
||||||
|
<p>Tak je všechno hotovo v GParted.</p>
|
||||||
|
|
||||||
|
<h1 id="přesouváme-systém">Přesouváme systém</h1>
|
||||||
|
<p>Dále připojíme naše oddíly podle jejich identifikátoru a čísla připojíme.</p>
|
||||||
|
|
||||||
|
<p>Nejdřív si vytvoříme složky, <code class="language-plaintext highlighter-rouge">sudo mkdir -p /mnt/archpi/{root,boot}</code> nám vytvoří složky <code class="language-plaintext highlighter-rouge">root</code> a <code class="language-plaintext highlighter-rouge">boot</code> pro naše oddíly.</p>
|
||||||
|
|
||||||
|
<p>Dále příkazem <code class="language-plaintext highlighter-rouge">sudo mount /dev/sdc1 /mnt/archpi/root</code> připojíme náš FAT32 bootovácí oddíl (<strong>Označení <code class="language-plaintext highlighter-rouge">sdc1</code> se u vás může lišit, podívejte se do GPartedu nebo skrz příkaz <code class="language-plaintext highlighter-rouge">lsblk</code> na označení jednotlivých oddílů</strong>) a příkazem <code class="language-plaintext highlighter-rouge">sudo mount /dev/sdc2 /mnt/archpi/boot</code> připojíme systémový oddíl.</p>
|
||||||
|
|
||||||
|
<p>Dle oficiální <a href="https://archlinuxarm.org/platforms/armv8/broadcom/raspberry-pi-3">dokumentace</a> se další proces má dělat skrz root uživatele, takže se přepneme příkazem <code class="language-plaintext highlighter-rouge">sudo su</code>.</p>
|
||||||
|
|
||||||
|
<p>Příkazem <code class="language-plaintext highlighter-rouge">wget http://os.archlinuxarm.org/os/ArchLinuxARM-rpi-armv7-latest.tar.gz</code> stáhneme archiv a příkazem <code class="language-plaintext highlighter-rouge">tar -xf ArchLinuxARM-rpi-armv7-latest.tar.gz -C /mnt/archpi/root</code> ho rozbalíme.</p>
|
||||||
|
|
||||||
|
<p>Pak musíme přesunout bootovací soubory do bootovacího oddílu: <code class="language-plaintext highlighter-rouge">mv /mnt/archpi/root/boot/* boot</code> a tím jsme hotovi, stačí oddíly odpojit příkazem <code class="language-plaintext highlighter-rouge">umount /mnt/archpi/root</code> a <code class="language-plaintext highlighter-rouge">umount /mnt/archpi/boot</code>. Jakmile se příkazy dokončí, můžete SD kartu vložit do RPi a zapnout.</p>
|
||||||
|
|
||||||
|
<p>Výchozí jméno a zároveň heslo uživatele je <code class="language-plaintext highlighter-rouge">alarm</code> a roota <code class="language-plaintext highlighter-rouge">root</code>. Než bude systém nastavený, doporučuji použít <code class="language-plaintext highlighter-rouge">root</code> účet.</p>
|
||||||
|
|
||||||
|
<h1 id="připojení-k-wi-fi-síti">Připojení k Wi-Fi síti</h1>
|
||||||
|
<p><em>Pokud používáte kabelové připojení, tak můžete přeskočit</em>
|
||||||
|
Nyní se připojíme skrz terminál k Wi-Fi síti. Předpokládám, že název (SSID) sítě a heslo znáte a že zabezpečení je WPA2 Personal. Jinak si můžete prohlédnout <a href="https://wiki.archlinux.org/title/Network_configuration/Wireless">Arch Wiki</a> pro více návodů.</p>
|
||||||
|
|
||||||
|
<p>Příkazem <code class="language-plaintext highlighter-rouge">iw dev</code> zjistíte název vašeho interfacu (např. já mám <code class="language-plaintext highlighter-rouge">wlan0</code>). Zapneme ho pomocí <code class="language-plaintext highlighter-rouge">ip link wlan0 up</code> (místo <code class="language-plaintext highlighter-rouge">wlan0</code> tedy použijte váš název interfacu).</p>
|
||||||
|
|
||||||
|
<p>Dále se tedy připojíme k nějaké Wi-Fi síti. Nejdřív musíme vytvořit konfigurační soubor pro <code class="language-plaintext highlighter-rouge">wpa_supplicant</code>, který slouží jako <a href="https://cs.wikipedia.org/wiki/Suplikant">suplikant</a> s podporou WPA, WPA2 a WPA3.</p>
|
||||||
|
|
||||||
|
<p>Pomocí příkazu <code class="language-plaintext highlighter-rouge">nano /etc/wpa_supplicant/wpa_supplicant.conf</code> vstoupíme do editace konfiguračního souboru. Do něj vložíme následující dva řádky:</p>
|
||||||
|
|
||||||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>ctrl_interface=/run/wpa_supplicant
|
||||||
|
update_config=1
|
||||||
|
</code></pre></div></div>
|
||||||
|
|
||||||
|
<p>Klávesovou zkratkou <code class="language-plaintext highlighter-rouge">Ctrl+X</code>, zadáním <code class="language-plaintext highlighter-rouge">y</code> a potvrzením enterem uložíme soubor a opustíme editaci. wpa_supplicant teď můžeme spustit příkazem <code class="language-plaintext highlighter-rouge">wpa_supplicant -B -i wlan0 -c /etc/wpa_supplicant/wpa_supplicant.conf</code>.</p>
|
||||||
|
|
||||||
|
<p>S běžícím wpa_supplicant můžeme použít příkaz <code class="language-plaintext highlighter-rouge">wpa_cli</code>, kde můžeme konfigurovat síť.</p>
|
||||||
|
|
||||||
|
<p>Sítě zde můžete hledat příkazem <a href="https://wiki.archlinux.org/title/Wpa_supplicant#Connecting_with_wpa_cli"><code class="language-plaintext highlighter-rouge">scan</code></a>, následováný <code class="language-plaintext highlighter-rouge">scan_results</code>.</p>
|
||||||
|
|
||||||
|
<p>Pro přidání sítě použijeme příkaz <code class="language-plaintext highlighter-rouge">add_network</code>. Terminál vrátí <code class="language-plaintext highlighter-rouge">0</code>, což je ID sítě, které můžeme konfigurovat. Příkazem <code class="language-plaintext highlighter-rouge">set_network 0 ssid "MYSSID"</code> nastavíme SSID (název) sítě na <code class="language-plaintext highlighter-rouge">MYSSID</code>. Příkazem <code class="language-plaintext highlighter-rouge">set_network 0 psk "passphrase"</code> nastavíme heslo na <code class="language-plaintext highlighter-rouge">passphrase</code>. Jakmile je nastaveno, můžeme povolit síť pomocí <code class="language-plaintext highlighter-rouge">enable_network 0</code>. Konfiguraci uložíme příkazem <code class="language-plaintext highlighter-rouge">save_config</code> a opustíme pomocí <code class="language-plaintext highlighter-rouge">quit</code>.</p>
|
||||||
|
|
||||||
|
<p>Jelikož ale právě teď nemáme IP adresu, musíme nastavit službu DHCP (pokud ji samozřejmě váš router má). Stačí zapnout službu <code class="language-plaintext highlighter-rouge">dhcpcd</code> pomocí příkazu <code class="language-plaintext highlighter-rouge">systemctl enable dhcpcd</code>. Abychom při každém zapnutí nemuseli síť manuálně zapínat, můžeme do <code class="language-plaintext highlighter-rouge">dhcpcd</code> přidat <a href="https://wiki.archlinux.org/title/Dhcpcd#10-wpa_supplicant">hook</a>, který ji automaticky zapne, stačí použít <code class="language-plaintext highlighter-rouge">ln -s /usr/share/dhcpcd/hooks/10-wpa_supplicant /usr/lib/dhcpcd/dhcpcd-hooks/</code>.</p>
|
||||||
|
|
||||||
|
<p>V tomto stádiu doporučuji restartovat příkazem <code class="language-plaintext highlighter-rouge">reboot</code>.</p>
|
||||||
|
|
||||||
|
<h1 id="nastavujeme-správce-balíků">Nastavujeme správce balíků</h1>
|
||||||
|
<p>Aktuálně bychom měli mít funkční síť, nicméně je potřeba pár dalších příkazů pokud chceme používat <code class="language-plaintext highlighter-rouge">pacman</code> správce balíků.</p>
|
||||||
|
|
||||||
|
<p>Nejdřív musíme vytvořit klíčenku příkazem <code class="language-plaintext highlighter-rouge">pacman-key --init</code>, poté přidáme klíče Arch ARM repozitářů příkazem <code class="language-plaintext highlighter-rouge">pacman-key --populate archlinuxarm</code>. Teď můžete příkazem <code class="language-plaintext highlighter-rouge">pacman -Sy</code> repozitáře synchronizovat.</p>
|
||||||
|
|
||||||
|
<p>Jako první balík bychom měli stáhnout <a href="https://wiki.archlinux.org/title/sudo"><code class="language-plaintext highlighter-rouge">sudo</code></a>, abychom nemuseli používat <code class="language-plaintext highlighter-rouge">root</code> uživatele pro všechno nastavování. Nainstalujeme ho příkazem <code class="language-plaintext highlighter-rouge">pacman -S sudo</code>. Dále příkazem <code class="language-plaintext highlighter-rouge">nano /etc/sudoers</code> upravíme konfiguraci. Najdeme následující řádky (<code class="language-plaintext highlighter-rouge">Ctrl+W</code> pro hledání):</p>
|
||||||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>## Uncomment to allow members of group wheel to execute any command
|
||||||
|
#%wheel ALL=(ALL:ALL) ALL
|
||||||
|
</code></pre></div></div>
|
||||||
|
<p>a odstraníme mřížku před <code class="language-plaintext highlighter-rouge">%</code> pro odstranění komentáře. Tím umožníme uživatelům v uživatelské skupině <code class="language-plaintext highlighter-rouge">wheel</code> používat příkaz <code class="language-plaintext highlighter-rouge">sudo</code>.</p>
|
||||||
|
|
||||||
|
<p>Nyní přidáme uživatele <code class="language-plaintext highlighter-rouge">alarm</code> do skupiny <code class="language-plaintext highlighter-rouge">wheel</code> příkazem <code class="language-plaintext highlighter-rouge">gpasswd -a alarm wheel</code>. A teď už můžeme používat uživatele <code class="language-plaintext highlighter-rouge">alarm</code> pro různé administrativní operace místo roota.</p>
|
||||||
|
|
||||||
|
<h1 id="nastavení-ssh-přístupu">Nastavení SSH přístupu</h1>
|
||||||
|
<p>Možná vás nebaví zapojovat RPi do monitoru nebo u něj klapat věci do klávesnice v terminálu nebo jen chcete vzdálený přístup. SSH lze povolit skrz OpenSSH, které je na Archu předinstalované. Stačí povolit službu pomocí <code class="language-plaintext highlighter-rouge">systemctl enable sshd</code>. Pro nějakou pokročilou konfiguraci si prohlédněte <a href="https://wiki.archlinux.org/title/OpenSSH#Server_usage">Arch Wiki</a>.</p>
|
||||||
|
|
||||||
|
<p>Nyní se stačí připojit skrz nějaký SSH klient na vaše zařízení (pokud neznáte IP, podívejte se skrz příkaz <code class="language-plaintext highlighter-rouge">ip a</code>), třeba skrz <code class="language-plaintext highlighter-rouge">ssh alarm@vase.ip.adresa</code>.</p>
|
||||||
|
|
||||||
|
<h1 id="https-problémy">HTTPS problémy</h1>
|
||||||
|
<p>Pokud máte problémy s SSL nebo komunikací se zabezpečenými servery, zkuste nainstalovat balík <code class="language-plaintext highlighter-rouge">ca-certificates</code> a nastavit systémový čas skrz <code class="language-plaintext highlighter-rouge">timedatectl set-time "2022-10-29 15:00:00</code> (samozřejmě vaše datum).</p>
|
||||||
|
|
||||||
|
<h1 id="závěr">Závěr</h1>
|
||||||
|
|
||||||
|
<p><img src="/assets/images/rpi-arch/05.png" alt="Arch neofetch" /></p>
|
||||||
|
|
||||||
|
<p>Instalace je opravdu prostý a snadný proces (i když jsem ho sám dělal asi 5x než mi to nabootovalo), takže určitě zkoušejte a zkoušejte.</p>]]></content><author><name>hernikplays</name></author><category term="tutoriál" /><category term="návod" /><category term="rpi" /><category term="arch" /><summary type="html"><![CDATA[]]></summary></entry><entry><title type="html">NordVPN - Jste opravdu v takovém nebezpečí?</title><link href="https://caras.cafe/bezpe%C4%8D%C3%AD/2022/07/19/nordvpn.html" rel="alternate" type="text/html" title="NordVPN - Jste opravdu v takovém nebezpečí?" /><published>2022-07-19T00:00:00+00:00</published><updated>2022-07-19T00:00:00+00:00</updated><id>https://caras.cafe/bezpe%C4%8D%C3%AD/2022/07/19/nordvpn</id><content type="html" xml:base="https://caras.cafe/bezpe%C4%8D%C3%AD/2022/07/19/nordvpn.html"><![CDATA[<p>Pokud sledujete YouTube, určite jste už narazili na nespočet videí, které sponzoruje nějaký poskytovatel tzv. <strong>VPN</strong>. Většinou se dozvíte něco jako „vaše data jsou v nebezpečí“ a/nebo „použijte naše služby pro zabezpečení vašich dat před hackery“. Toto se samozřejmě netýká <em>jen</em> NordVPN, ale myslím, že ti mají tu nejagresivnější marketingovou strategii snad ze všech.</p>
|
||||||
|
<h1 id="část-i-kecy">ČÁST I: Kecy</h1>
|
||||||
|
<h2 id="kdo-stojí-za-nordvpn">Kdo stojí za NordVPN</h2>
|
||||||
|
<p>NordVPN vzniklo v roce 2012 jako produkt Toma Okmana, Eimantase Sabaliauskase a Jonase Karklyse. Služba má sloužit jako tzv. <strong>Virtual Private Network</strong> neboli virtuální soukromá síť. Můžete se tak skrze NordVPN servery připojovat na internet třeba z Německa. Dle zvoleného protokolu je síťový provoz šifrován. NordVPN vlastní společnost <a href="https://nordsecurity.com/">Nord Security</a>, která zastřešuje i ostatní produkty značky Nord. Sídlo má ve Velké Británii. Nord Security kromě VPN nabízí i vlastního správce hesel a šifrovaný cloud.</p>
|
||||||
|
|
||||||
|
<h2 id="nordvpn-a-reklamy-youtuberů">NordVPN a reklamy YouTuberů</h2>
|
||||||
|
<p>Reklamy uvnitř obsahu, tedy reklamy, které tvůrce přidává přímo do videa výměnou za přímou platbu od společnosti, jsou tu s námi celkem dlouho. Jsou <strong>efektivnější</strong> než běžné reklamy, protože je s běžným blokovačem reklam nepřeskočíte a často je tvůrci tvoří zábavným způsobem, aby je sledující sám nepřeskočil. Je to <strong>stabilnější příjem</strong> pro tvůrce obsahu, jelikož se nemusí spoléhat na výdělek z reklam, které YouTube často omezuje svými pravidli demonetizace. To je také jeden z důvodů, proč často youtubeři těmto druhům reklam vyjdou vstříc, i když nemusí mít o daném produktu žádnou znalost. Často tak ve svých videích poskytují nepravdivé či přímo zavádějící tvrzení. Než uvedu příklady, je nutné si uvědomit, že <strong>ne každý takový YouTuber poskytuje zavádějící informace</strong> nebo že <strong>NordVPN nejsou žádní podvodníci</strong>. Nejsem žádný „samozvaný IT expert“, takže mě neváhejte případně opravit. A o tvrzení „NordVPN je nejlepší VPN“ se bavit ani nebudu, o tom si udělejte obrázek sami.</p>
|
||||||
|
|
||||||
|
<h3 id="tvrzení-č-1">Tvrzení č. 1:</h3>
|
||||||
|
<p><strong><a href="https://youtu.be/51TNTCAD8fQ?t=68">Veřejné WiFi jsou nebezpečné a kdokoliv může sledovat, co na nich děláte</a></strong></p>
|
||||||
|
|
||||||
|
<p>Zalíbila se mi <a href="https://www.quora.com/Is-it-safe-to-use-internet-from-open-public-WiFi-hotspots/answer/Scott-Helms-8">odpověď Scotta Helmse</a>, který přirovnává veřejné WiFi sítě k veřejným ulicím. Pokud budete dělat hlouposti, jako je chození s přilepenou platební kartou na čele, samozřejmě vaše údaje budou odcizeny. Proto určitě není dobrý nápad dělat nákupy či se přihlašovat do bankovnictví skrz veřejné sítě. Když se na to podíváme realisticky, je relativně malá šance, že si zrovna k vám v mekáči sedl chlapec či dívka s laptopem, na kterém projíždí vaši historii vyhledávání. Navíc většina webů je zabezpečená pomocí SSL, takže přenos dat je šifrovaný. Takže při používání VPN to vlastně šifrujete ještě jednou (?), což už ale tak užitečné není. Jak <a href="https://www.eff.org/deeplinks/2020/01/why-public-wi-fi-lot-safer-you-think">píše</a> EFF, tyto hrozby jsou díky HTTPS/SSL spíše minulostí. Váš poskytovatel internetu může sledovat např. jakou stránku otevíráte (třeba github.com), nicméně neuvidí žádné parametry, které odesíláte, ani jestli navštěvujete github.com/hernikplays nebo github.com/ytdl. A to stejné mohou lidé, kteří jsou kolem vás připojení na veřejné WiFi. „V životě se bojíte spousty věcí, veřejné WiFi si můžete ze seznamu odškrtnout“.</p>
|
||||||
|
|
||||||
|
<h3 id="tvrzení-č-2">Tvrzení č. 2:</h3>
|
||||||
|
<p><strong><a href="https://youtu.be/a_LiGXtXXNQ?t=1642">[NordVPN poskytuje] maximální internetové bezpečí</a></strong></p>
|
||||||
|
|
||||||
|
<p>Jak už jsem řekl v předchozí části, před vlastní blbostí vás ani to nejlepší VPN nezachrání. Pokud máte selský rozum, tak poznáte, kam zadávat a nezadávat svoje osobní údaje, což se s rostoucí popularitou sociálního inženýrství o něco zhoršuje. A pokud si vás přecijen nějaký špičkový, státem placený hacker najde, tak mu VPN určitě nebude dělat problém.</p>
|
||||||
|
|
||||||
|
<h3 id="tvrzení-č-3">Tvrzení č. 3:</h3>
|
||||||
|
<p><strong><a href="https://youtu.be/sB8vHDS1Tcg?t=380">Zatímco [bez VPN] ti může jakýkoliv útočník vcelku jednoduše tvé zařízení nabourat, s ním jsi prakticky neviditelný […] smaže za tebou tvou stopu</a></strong></p>
|
||||||
|
|
||||||
|
<p>Toto tvrzení je možná pravdivé pro NordVPN, jelikož nabízejí službu „<a href="https://nordvpn.com/features/threat-protection/">Threat Protection</a>“, která slouží k blokování reklam, sledovacích prvků a nebezpečných webů, nicméně může vzbudit dojem, že takhle operuje každé VPN. Pokud vám jde o vaše bezpečí, neměli byste sázet na řešení jedním kliknutím, ale <a href="https://mullvad.net/en/help/first-steps-towards-online-privacy/">prozkoumat různé možnosti a nástroje</a>, včetně VPN. Pokud používáte např. služby od Googlu, už tak jim o sobě poskytujete dostatek údajů.
|
||||||
|
Útočník také nemůže „vcelku jednoduše“ vaše zařízení nabourat, to lze pouze pokud jste se rozhodli používat Windows 10 a nenainstalovali jste žádné aktualizace. V tom případě je váš systém děravý jak ementál a to už asi nikdo, kromě vás, nespraví. Takže aktualizujte svůj systém a aplikace jak to jen půjde!</p>
|
||||||
|
|
||||||
|
<h3 id="tvrzení-č-4">Tvrzení č. 4:</h3>
|
||||||
|
<p><strong>Můžeš sledovat obsah uzamknutý pro určité země</strong></p>
|
||||||
|
|
||||||
|
<p>To je samozřejmě pravda, nicméně některé služby se aktivně pokouší zamezit přístup uživatelům s VPN identifikováním IP adresy daného VPN serveru.</p>
|
||||||
|
|
||||||
|
<h3 id="tvrzení-č-5">Tvrzení č. 5:</h3>
|
||||||
|
<p><strong><a href="https://youtu.be/sB8vHDS1Tcg?t=436">[NordVPN] ti zrychlí internet</a></strong></p>
|
||||||
|
|
||||||
|
<p>Když máte od poskytovatele internetu omezené stahování na 10 MB/s, nemůžete očekávat, že když budete ze serveru, kde může být zároveň napojeno X tisíc lidí a je někde v tramtárii, stahovat soubor, že se bude stahovat rychleji. <a href="https://www.cloudflare.com/learning/access-management/vpn-speed/">Pouze ve specifických případech</a>, kdy například poskytovatel internetu záměrně zpomaluje připojení např. k Netflixu, můžete pocítit zrychlení.</p>
|
||||||
|
|
||||||
|
<h2 id="nordvpn-a-ještě-divnější-praktiky">NordVPN a ještě divnější praktiky</h2>
|
||||||
|
<p>Zavádějícími tvrzeními to však nekončí, věděli jste, že na mnoha webech s hodnoceními VPN služeb si můžete určitou pozici <strong>jednoduše koupit</strong>? Ano, dostáváme se do takzvaného <strong>provizního systému</strong>, tedy systému, ve kterém firma proplatí provizi z provedeného nákupu jistému zprostředkovateli. Vtipná věc je, že některé tyto firmy <a href="https://blog.windscribe.com/consolidation-of-the-vpn-industry-spells-trouble-for-the-consumer-57e638634cf0/">vlastní</a> zároveň takovéto <em>„publikace“</em> a samotné VPN služby, jako např. Kape Technologies, která se původně <strong>zabývala adwarem</strong>, nyní vlastní např. ExpressVPN a zároveň web VPNmentor. NordVPN není výjimkou s jejich provizním systémem nabízejícím až 40% část z ceny nákupu. Dá se těmto „hodnocením“ vůbec věřit? Některým nejspíš ano, je dobré však zkontrolovat, jestli publikaci nevlastní nějaká mediální společnost.</p>
|
||||||
|
|
||||||
|
<p>Dále můžeme na webu NordVPN, služby, která vám má pomoct chránit vaše soukromí a <em>„zneviditelnit se“</em>, <strong>najít spoustu sledovacích prvků</strong>, jako např. sledovací prvky Twitter Ads, Google Ads, Analytics a Bing.</p>
|
||||||
|
|
||||||
|
<p><img src="/assets/images/vpn/14.png" alt="Ukázka sledovacích prvků na stránce NordVPN" /></p>
|
||||||
|
|
||||||
|
<h1 id="část-ii-vzhůru-dolů">Část II: Vzhůru dolů</h1>
|
||||||
|
<p>Ano, je čas, abych se vydal do králičí nory a NordVPN otestoval. Hned na úvodní stránce na vás vyskočí tuny slev. „Nakupte do X hodin a získejte slevu X%“. No tak to abych si pohnul, co? Samozřejmě, že ne. Úplně stejná stránka s úplně stejným odpočtem se mi zobrazila i včera. Navíc tato sleva platí jen na roční plány a já s NordVPN chci strávit co nejméně času. Takže beru jejich standardních 10,49 eur na měsíc, které naštěstí také nabízejí s garancí vrácení peněz. Samozřejmě k tomu ještě musíte přičíst daně, z čehož máme 12,69 <em>(nice)</em>. Použil jsem jejich <a href="https://www.theregister.com/2020/03/06/nordvpn_no_auth_needed_view_user_payments/">(ne)</a>bezpečnou bránu a vzdal se svých těžce vydělaných peněz.
|
||||||
|
Jejich stránka, ze které jsem měl stáhnout klienta, se chvástala „online zabezpečením pro všechny velké linuxové distribuce“, takže je super, že nabízejí stažení pouze pro distribuce založené na Debianu a RHEL, když jsem na Archu. Samozřejmě nic, co by Arch komunita nevyřešila.</p>
|
||||||
|
|
||||||
|
<p>Nemůžu hodnotit jednoduchost prostředí, protože <em>to na linuxu ani není</em>. Nicméně se podíváme na rychlost.</p>
|
||||||
|
<h2 id="rychlosti-velmi-stručně">Rychlosti (velmi stručně)</h2>
|
||||||
|
<p><img src="/assets/images/vpn/13.png" alt="Výchozí rychlost (bez VPN, WiFi)" /></p>
|
||||||
|
|
||||||
|
<p>Výchozí rychlost (bez VPN, WiFi)</p>
|
||||||
|
|
||||||
|
<p><img src="/assets/images/vpn/12.png" alt="NordVPN Germany #1078" /></p>
|
||||||
|
|
||||||
|
<p>NordVPN Germany #1078</p>
|
||||||
|
|
||||||
|
<p><img src="/assets/images/vpn/11.png" alt="Rychlost stahování torrentů na serverech v Německu" /></p>
|
||||||
|
|
||||||
|
<p>Pokles rychlosti, úplně normální, protože pakety urazí větší vzdálenost. Streamování YouTube ve Full HD má pocititelné zpomalení/zasekávání. Rychlosti stahování torrentů se držely v průměru mezi 600 a 700 KB/s.</p>
|
||||||
|
|
||||||
|
<p><img src="/assets/images/vpn/10.png" alt="NordVPN USA #9363" /></p>
|
||||||
|
|
||||||
|
<p>NordVPN USA #9363</p>
|
||||||
|
|
||||||
|
<p><img src="/assets/images/vpn/9.png" alt="Rychlost stahování torrentů na serverech v USA" /></p>
|
||||||
|
|
||||||
|
<p>Tady už změnu pocítíte víc. Zajímavé však je, že se videa z YouTube ve Full HD načítají rychleji. Nicméně rychlosti stahování torrentů skákaly nahorů a dolů.</p>
|
||||||
|
|
||||||
|
<h2 id="threat-protection-lite">Threat Protection Lite</h2>
|
||||||
|
<p>Další funkce dostupná pro linux je <a href="https://support.nordvpn.com/General-info/Features/1047407402/What-are-Threat-Protection-and-Threat-Protection-Lite.htm">TPL</a>, který má blokovat reklamy, nebezpečné stránky a pochybná připojení během připojení na VPN.</p>
|
||||||
|
|
||||||
|
<p>Na webu NordVPN zablokoval sledovací prvky Twitteru, Bingu a Googlu, nicméně vynechal Google Analytics (což je asi pochopitelné, když o blokování sledujících prvků není ani zmínka).</p>
|
||||||
|
|
||||||
|
<p><img src="/assets/images/vpn/8.png" alt="Zablokované sledovací prvky na NordVPN.com" /></p>
|
||||||
|
|
||||||
|
<p>Na YouTube neblokuje reklamy vůbec,
|
||||||
|
<img src="/assets/images/vpn/7.png" alt="Blokování reklam s TPL na YouTube" /></p>
|
||||||
|
|
||||||
|
<p>ale na jiných webech ano.
|
||||||
|
<img src="/assets/images/vpn/6.png" alt="Blokování reklam s TPL na jiných webech" /></p>
|
||||||
|
|
||||||
|
<p>Takže nahradí blokovače jako <a href="https://github.com/gorhill/uBlock#readme">uBlock Origin</a>? Řekl bych, že ne.</p>
|
||||||
|
<h1 id="část-iii-opouštíme-králičí-noru">Část III: Opouštíme králičí noru</h1>
|
||||||
|
<p>Dobře, mám trochu NordVPN na vlastní kůži, ale teď se ho chci zbavit. Takže jdeme žádat zpět peníze.
|
||||||
|
Zrušení obnovení předplatného bylo relativně snadné, v nastavení účtu stačilo kliknout na „Zrušit“.</p>
|
||||||
|
|
||||||
|
<p><img src="/assets/images/vpn/5.png" alt="Zrušení obnovení předplatného" /></p>
|
||||||
|
|
||||||
|
<p>Teď přijde ta bolestivější část, a to žádání o vrácení peněz. Dle podmínek máte 30 dní od prvního nákupu nárok na vrácení peněz.
|
||||||
|
NordVPN říká, že podpora funguje 24/7. Na začátku jste spojeni s robotem, který vás postupně přepojí na živého člověka.</p>
|
||||||
|
|
||||||
|
<p><img src="/assets/images/vpn/4.png" alt="Robot na podpoře" /></p>
|
||||||
|
|
||||||
|
<p>Člověk se skutečně objevil.</p>
|
||||||
|
|
||||||
|
<p><img src="/assets/images/vpn/3.png" alt="Chat s podporu část 1" /></p>
|
||||||
|
|
||||||
|
<p>Chvilku mu to trvalo, takže jsem ho popostrčil.</p>
|
||||||
|
|
||||||
|
<p><img src="/assets/images/vpn/2.png" alt="Chat s podporu část 2" /></p>
|
||||||
|
|
||||||
|
<p>Řekl jsem mu slušně „Ne, díky“, po čemž mi nastavil vrácení peněz.</p>
|
||||||
|
|
||||||
|
<p><img src="/assets/images/vpn/1.png" alt="Chat s podporu část 3" /></p>
|
||||||
|
|
||||||
|
<p>Celkem rychle vyřízeno, dobrá práce. Zvláštní mi přišlo jen, že si mě nijak neověřil, pouze jsem na začátku poskytl e-mail, z čehož (doufám) vydedukoval, že to patří k mému účtu.
|
||||||
|
Další den mi skutečně odebrali přístup k jejich službě, nicméně peníze jsou stále zablokované, tak snad si banka pohne.</p>
|
||||||
|
|
||||||
|
<h1 id="část-v-závěr">Část V: Závěr</h1>
|
||||||
|
<p>Takže na závěr:
|
||||||
|
<strong>Je VPN úplně zbytečný nástroj?</strong> Určitě ne.</p>
|
||||||
|
|
||||||
|
<p><strong>Můžou youtubeři za to, že někdy neříkají pravdivé věci?</strong> Spíš ne, nemůžete čekat každého youtubera, že je expert přes sítě, jenom se snaží se uživit a vyloženě lži říkají opravdu málokdy.</p>
|
||||||
|
|
||||||
|
<p><strong>Snaží se NordVPN prodat hadí olej a moje děti na darknetu?</strong> Nejspíš ne, ale měli by víc sjednotit prezentování co se týče sponzorování youtuberů.</p>
|
||||||
|
|
||||||
|
<p><strong>Můžu důvěřovat NordVPN?</strong> S jejich velikostí nejspíš ano.</p>
|
||||||
|
|
||||||
|
<p><strong>Doporučil bych NordVPN?</strong> Ne. Pokud chcete opravdu 100% anonymitu a hlavně no-bullshit produkt, použijte něco jako Mullvad <em>(toto není sponzorováno, sám ho používám a je fajn)</em>, který nenabízí žádné posrané slevy kvůli všemu možnému a kde dokonce můžete platit v hotovosti, ale nezapomeňte, že VPNkem to nekončí. Podívejte se na <a href="https://ssd.eff.org/">Surveillance Self-Defense</a> od EFF pro více tipů na ochranu vašeho soukromí.</p>]]></content><author><name>hernikplays</name></author><category term="bezpečí" /><category term="vpn" /><category term="youtube" /><category term="reklamy" /><summary type="html"><![CDATA[Pokud sledujete YouTube, určite jste už narazili na nespočet videí, které sponzoruje nějaký poskytovatel tzv. VPN. Většinou se dozvíte něco jako „vaše data jsou v nebezpečí“ a/nebo „použijte naše služby pro zabezpečení vašich dat před hackery“. Toto se samozřejmě netýká jen NordVPN, ale myslím, že ti mají tu nejagresivnější marketingovou strategii snad ze všech. ČÁST I: Kecy Kdo stojí za NordVPN NordVPN vzniklo v roce 2012 jako produkt Toma Okmana, Eimantase Sabaliauskase a Jonase Karklyse. Služba má sloužit jako tzv. Virtual Private Network neboli virtuální soukromá síť. Můžete se tak skrze NordVPN servery připojovat na internet třeba z Německa. Dle zvoleného protokolu je síťový provoz šifrován. NordVPN vlastní společnost Nord Security, která zastřešuje i ostatní produkty značky Nord. Sídlo má ve Velké Británii. Nord Security kromě VPN nabízí i vlastního správce hesel a šifrovaný cloud.]]></summary></entry><entry><title type="html">GitHub Codespaces aneb VS Code na VPS</title><link href="https://caras.cafe/vychyt%C3%A1vky/2022/05/31/codespaces.html" rel="alternate" type="text/html" title="GitHub Codespaces aneb VS Code na VPS" /><published>2022-05-31T00:00:00+00:00</published><updated>2022-05-31T00:00:00+00:00</updated><id>https://caras.cafe/vychyt%C3%A1vky/2022/05/31/codespaces</id><content type="html" xml:base="https://caras.cafe/vychyt%C3%A1vky/2022/05/31/codespaces.html"><![CDATA[<p>Nedávno mi přišel e-mail, že jsem byl přidán do beta testování funkce Codespaces na GitHubu. Stručně, Codespaces má být systém ve kterém si vytvoříte vlastní prostředí pro váš repozitář, do kterého si nainstalujete všechny potřebné knihovny, SDK a balíky. Server, na kterém to všechno běží, si platíte u GitHubu a můžete na něj kdekoliv a kdykoliv přejít přes web do webové, narozdíl od výchozího webového VS Code plně vybavené, verzi VS Code nebo nainstalovaný VS Code a upravovat nebo testovat kód.</p>
|
||||||
|
|
||||||
|
<p>Hodí se pro lidi, kteří nechtějí tahat např. do školy nebo do práce, kde nesmí instalovat externí aplikace, svůj vlastní notebook.
|
||||||
|
Parametry</p>
|
||||||
|
|
||||||
|
<p>V betě je možné testovat pouze výchozí možnost 4 jádra + 8GB RAM + 32GB úložiště, což definitivně stačí pro osobní a malé projekty. Do konce bety neplatíte nic, ale 4 jádra vyjdou na $0.36 (asi 8,3 kč) za hodinu, tj za hodinu aktivního používání. Codespace se vám automaticky vypne, pokud není po stanovenou dobu nepoužíván, takže můžete předejít placení katastrofických částek.
|
||||||
|
<img src="/assets/images/codespaces/1.jpg" alt="Ceny Codespaces" /></p>
|
||||||
|
|
||||||
|
<p>Je to určitě výhodnější, než si platit např. hotové VPS, pokud ho tedy nepoužíváte i na něco smysluplnějšího.
|
||||||
|
Moje zkušenost</p>
|
||||||
|
|
||||||
|
<p>Samozřejmě jsem nemohl odolat a na OpenCanteen jsem si jeden nechal vytvořit, aniž bych věděl do čeho se vrhám.</p>
|
||||||
|
|
||||||
|
<p>Codespace se vytváří jednoduše kliknutím na tlačítko “Code” ve vašem repozitáří, kde se vám nově zobrazí možnost si Codespace vytvořit.</p>
|
||||||
|
|
||||||
|
<p>Ve výchozím stavu běží server na Ubuntu. Pokud nenajdete docker obraz nebo devcontainer konfigurační soubor, musíte si samozřejmě vše nainstalovat sami, což zas tolik nevadí, protože to nejspíš budete dělat jen jednou, pokud si nebudete s obrazem stroje nějak zahrávat.</p>
|
||||||
|
|
||||||
|
<p>Instalace všeho však probíhá svižně, jelikož asi v Microsoftu mají na rychlejší internet, než já. Samozřejmě vše musíte instalovat skrze terminál (což mě celkem ranilo, jelikož instalovat Android SDK pro flutter byla celkem fuška).</p>
|
||||||
|
|
||||||
|
<p>Pokud používáte Settings Sync ve VS Code, automaticky se vám synchronizují nastavení a rozšíření. Pro pokročilé upravení prostředí slouží konfigurační soubor devcontainer.json
|
||||||
|
<img src="/assets/images/codespaces/2.jpg" alt="Ceny Codespaces" /></p>
|
||||||
|
|
||||||
|
<p>Jakmile máte všechno nastavené, už stačí jen využít starého známého Visual Studio Code, které funguje úplně stejně jako na lokálním zařízení. Na Codespace se můžete kdykoli připojit přes webovou adresu.</p>
|
||||||
|
|
||||||
|
<p>Za mě velice praktické pro dříve uvedené typy lidí, už jen záleží, jestli se to zrovna vám za ty peníze vyplatí. Dokumentace je možná trochu chaotická, alespoň pro uživatele co se nevyznají v technologiích jako kontejnery či docker a většiny funkcí využije jen skutečný poweruser (což já určitě nejsem).</p>]]></content><author><name>hernikplays</name></author><category term="vychytávky" /><category term="github" /><category term="vps" /><summary type="html"><![CDATA[Nedávno mi přišel e-mail, že jsem byl přidán do beta testování funkce Codespaces na GitHubu. Stručně, Codespaces má být systém ve kterém si vytvoříte vlastní prostředí pro váš repozitář, do kterého si nainstalujete všechny potřebné knihovny, SDK a balíky. Server, na kterém to všechno běží, si platíte u GitHubu a můžete na něj kdekoliv a kdykoliv přejít přes web do webové, narozdíl od výchozího webového VS Code plně vybavené, verzi VS Code nebo nainstalovaný VS Code a upravovat nebo testovat kód.]]></summary></entry><entry><title type="html">Automatizace, automatizace, automatizace</title><link href="https://caras.cafe/programov%C3%A1n%C3%AD/2022/05/22/automatizace.html" rel="alternate" type="text/html" title="Automatizace, automatizace, automatizace" /><published>2022-05-22T00:00:00+00:00</published><updated>2022-05-22T00:00:00+00:00</updated><id>https://caras.cafe/programov%C3%A1n%C3%AD/2022/05/22/automatizace</id><content type="html" xml:base="https://caras.cafe/programov%C3%A1n%C3%AD/2022/05/22/automatizace.html"><![CDATA[<p>Roboti nám brzo vezmou práci, ale mně to (prozatím) nevadí. Já nechávám robůtky pracovat za mě a ulehčovat mi práci. A vy byste měli taky! Pokud teda programujete, jinak nevím.</p>
|
||||||
|
|
||||||
|
<p>Nedávno jsem objevil krásy zvané GitHub Actions a musím říct, že je to opravdu radost. Nikdy předtím jsem nedokázal pochopit jejich praktičnost, než jsem pracoval na <a href="https://github.com/hernikplays/opencanteen">OpenCanteen</a>. Sestavovat, podepisovat a nahrávat mě opravdu nebavilo a ještě s mým pomalým PC v kombinaci s pomalým internetem to nešlo zrovna rychle. Pak jsem si vzpomněl na GitHub Actions. Místo toho, abych dělal cokoliv produktivního, jsem strávil celé odpoledne nastavováním Actions, aby mi při novém tagu automaticky sestavil a publikoval vydání aplikace do Google Play.</p>
|
||||||
|
|
||||||
|
<p>Ta první část šla skvěle, avšak nahrávání do Google Play bylo o něco složitější, dokud jsem neobjevil hotové a, prozatím bezplatné, řešení <a href="https://codemagic.io/start/">CodeMagic</a>.</p>
|
||||||
|
|
||||||
|
<p>Jednoduše jsem napojil repozitář, nastavil podepisovací a nahrávací údaje a všechno hned jelo! Byla to radost pro někoho tak líného jako jsem já. I přesto, že jsem sám reálně nic neudělal, cítil jsem, že jsem dosáhl něčeho úžasného.</p>
|
||||||
|
|
||||||
|
<p>A určitě to lze dotáhnout ještě dál, už teď používám Actions pro automatickou analýzu kódu, a kdybych si vytvořil testy tak by mi to určitě i otestovalo celou aplikaci.</p>
|
||||||
|
|
||||||
|
<p>Pak jsem si řekl, že by možná mohl někdo chtít do mé aplikace přispět svým kódem. Protože chci v tom mít pořádek, hned jsem začal projíždět GitHub Marketplace pro nějaké akce na pull requesty. Hned jsem jich několik objevil.</p>
|
||||||
|
|
||||||
|
<p>Velice jsem ocenil akci, která mi automaticky přidala labely podle souboru, který byl v PR upraven.</p>
|
||||||
|
|
||||||
|
<p>Určitě nepotřebujete nutně automatizovat všechno, pokud máte např. soukromý či malý projekt. Nicméně si to můžete aspoň otestovat a případně využít v budoucnu tak se do toho pusťte! Automatizovat můžete všechno možné. Určitě budete mít dobrý pocit, když se vaše akce spustí a úspěšně se dokončí.</p>]]></content><author><name>hernikplays</name></author><category term="programování" /><category term="automatizace" /><category term="technologie" /><summary type="html"><![CDATA[Roboti nám brzo vezmou práci, ale mně to (prozatím) nevadí. Já nechávám robůtky pracovat za mě a ulehčovat mi práci. A vy byste měli taky! Pokud teda programujete, jinak nevím.]]></summary></entry></feed>
|
1067
index.html
Normal file
28
jekyll-theme-yat.gemspec
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
Gem::Specification.new do |spec|
|
||||||
|
spec.name = "jekyll-theme-yat"
|
||||||
|
spec.version = "1.8.0"
|
||||||
|
spec.authors = ["jeffreytse"]
|
||||||
|
spec.email = ["jeffreytse.mail@gmail.com"]
|
||||||
|
|
||||||
|
spec.summary = "Yet another theme for elegant writers with modern flat style and beautiful night/dark mode."
|
||||||
|
spec.homepage = "https://github.com/jeffreytse/jekyll-theme-yat"
|
||||||
|
spec.license = "MIT"
|
||||||
|
|
||||||
|
spec.metadata["plugin_type"] = "theme"
|
||||||
|
|
||||||
|
spec.files = `git ls-files -z`.split("\x0").select do |f|
|
||||||
|
f.match(%r!^(assets|_data|_layouts|_includes|_sass|LICENSE|README)!i)
|
||||||
|
end
|
||||||
|
|
||||||
|
spec.add_development_dependency "bundler", ">= 1.6", "< 3.0"
|
||||||
|
spec.add_development_dependency "rake", ">= 12.0", "< 13.0"
|
||||||
|
|
||||||
|
spec.add_runtime_dependency "jekyll", "> 3.5", "< 5.0"
|
||||||
|
spec.add_runtime_dependency "jekyll-feed", "~> 0.9"
|
||||||
|
spec.add_runtime_dependency "jekyll-seo-tag", "~> 2.1"
|
||||||
|
spec.add_runtime_dependency "jekyll-sitemap", "~> 1.3"
|
||||||
|
spec.add_runtime_dependency "jekyll-paginate", "~> 1.1"
|
||||||
|
spec.add_runtime_dependency "jekyll-spaceship", "~> 0.2"
|
||||||
|
end
|
750
programování/2022/05/22/automatizace.html
Normal file
|
@ -0,0 +1,750 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
|
<meta name="google-translate-customization" content="108d9124921d80c3-80e20d618ff053c8-g4f02ec6f3dba68b7-c">
|
||||||
|
<!-- Begin Jekyll SEO tag v2.8.0 -->
|
||||||
|
<title>Automatizace, automatizace, automatizace | Matyáš Caras</title>
|
||||||
|
<meta name="generator" content="Jekyll v4.3.1">
|
||||||
|
<meta property="og:title" content="Automatizace, automatizace, automatizace">
|
||||||
|
<meta name="author" content="hernikplays">
|
||||||
|
<meta property="og:locale" content="en_US">
|
||||||
|
<meta name="description" content="Roboti nám brzo vezmou práci, ale mně to (prozatím) nevadí. Já nechávám robůtky pracovat za mě a ulehčovat mi práci. A vy byste měli taky! Pokud teda programujete, jinak nevím.">
|
||||||
|
<meta property="og:description" content="Roboti nám brzo vezmou práci, ale mně to (prozatím) nevadí. Já nechávám robůtky pracovat za mě a ulehčovat mi práci. A vy byste měli taky! Pokud teda programujete, jinak nevím.">
|
||||||
|
<link rel="canonical" href="https://caras.cafe/programov%C3%A1n%C3%AD/2022/05/22/automatizace.html">
|
||||||
|
<meta property="og:url" content="https://caras.cafe/programov%C3%A1n%C3%AD/2022/05/22/automatizace.html">
|
||||||
|
<meta property="og:site_name" content="Matyáš Caras">
|
||||||
|
<meta property="og:type" content="article">
|
||||||
|
<meta property="article:published_time" content="2022-05-22T00:00:00+00:00">
|
||||||
|
<meta name="twitter:card" content="summary">
|
||||||
|
<meta property="twitter:title" content="Automatizace, automatizace, automatizace">
|
||||||
|
<script type="application/ld+json">
|
||||||
|
{"@context":"https://schema.org","@type":"BlogPosting","author":{"@type":"Person","name":"hernikplays"},"dateModified":"2022-05-22T00:00:00+00:00","datePublished":"2022-05-22T00:00:00+00:00","description":"Roboti nám brzo vezmou práci, ale mně to (prozatím) nevadí. Já nechávám robůtky pracovat za mě a ulehčovat mi práci. A vy byste měli taky! Pokud teda programujete, jinak nevím.","headline":"Automatizace, automatizace, automatizace","mainEntityOfPage":{"@type":"WebPage","@id":"https://caras.cafe/programov%C3%A1n%C3%AD/2022/05/22/automatizace.html"},"url":"https://caras.cafe/programov%C3%A1n%C3%AD/2022/05/22/automatizace.html"}</script>
|
||||||
|
<!-- End Jekyll SEO tag -->
|
||||||
|
<link rel="shortcut icon" href="">
|
||||||
|
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
|
||||||
|
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/typeface-noto-sans@0.0.72/index.min.css">
|
||||||
|
<link rel="stylesheet" href="/assets/css/main.css">
|
||||||
|
<script src="/assets/js/main.js"></script><link type="application/atom+xml" rel="alternate" href="https://caras.cafe/feed.xml" title="Matyáš Caras">
|
||||||
|
<link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/highlight.js/10.1.1/styles/default.min.css">
|
||||||
|
<script src="//cdnjs.cloudflare.com/ajax/libs/highlight.js/10.1.1/highlight.min.js"></script>
|
||||||
|
<!-- and it's easy to individually load additional languages -->
|
||||||
|
<script charset="UTF-8" src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.1.1/languages/go.min.js"></script>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<script>
|
||||||
|
// Init highlight js
|
||||||
|
document.addEventListener('DOMContentLoaded', function(event) {
|
||||||
|
var els = document.querySelectorAll('pre code')
|
||||||
|
|
||||||
|
function addLangData(block) {
|
||||||
|
var outer = block.parentElement.parentElement.parentElement;
|
||||||
|
var lang = block.getAttribute('data-lang');
|
||||||
|
for (var i = 0; i < outer.classList.length; i++) {
|
||||||
|
var cls = outer.classList[i];
|
||||||
|
if (cls.startsWith('language-')) {
|
||||||
|
lang = cls;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!lang) {
|
||||||
|
cls = block.getAttribute('class');
|
||||||
|
lang = cls ? cls.replace('hljs ', '') : '';
|
||||||
|
}
|
||||||
|
if (lang.startsWith('language-')) {
|
||||||
|
lang = lang.substr(9);
|
||||||
|
}
|
||||||
|
block.setAttribute('class', 'hljs ' + lang);
|
||||||
|
block.parentNode.setAttribute('data-lang', lang);
|
||||||
|
}
|
||||||
|
|
||||||
|
function addBadge(block) {
|
||||||
|
var enabled = ('true' || 'true').toLowerCase();
|
||||||
|
if (enabled == 'true') {
|
||||||
|
var pre = block.parentElement;
|
||||||
|
pre.classList.add('badge');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function handle(block) {
|
||||||
|
addLangData(block);
|
||||||
|
addBadge(block)
|
||||||
|
hljs.highlightBlock(block);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (var i = 0; i < els.length; i++) {
|
||||||
|
var el = els[i];
|
||||||
|
handle(el);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
/* code language badge */
|
||||||
|
pre.badge::before {
|
||||||
|
content: attr(data-lang);
|
||||||
|
color: #fff;
|
||||||
|
background-color: #ff4e00;
|
||||||
|
padding: 0 .5em;
|
||||||
|
border-radius: 0 2px;
|
||||||
|
text-transform: uppercase;
|
||||||
|
text-align: center;
|
||||||
|
min-width: 32px;
|
||||||
|
display: inline-block;
|
||||||
|
position: absolute;
|
||||||
|
right: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* fix wrong badge display for firefox browser */
|
||||||
|
code > table pre::before {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<header class="site-header " role="banner">
|
||||||
|
|
||||||
|
<div class="wrapper">
|
||||||
|
<div class="site-header-inner">
|
||||||
|
<span class="site-brand"><a class="site-brand-inner" rel="author" href="/">
|
||||||
|
<img class="site-favicon" title="Matyáš Caras" src="" onerror="this.style.display='none'">
|
||||||
|
Matyáš Caras
|
||||||
|
</a>
|
||||||
|
</span><nav class="site-nav">
|
||||||
|
<input type="checkbox" id="nav-trigger" class="nav-trigger">
|
||||||
|
<label for="nav-trigger">
|
||||||
|
<span class="menu-icon">
|
||||||
|
<svg viewbox="0 0 18 15" width="18px" height="15px">
|
||||||
|
<path d="M18,1.484c0,0.82-0.665,1.484-1.484,1.484H1.484C0.665,2.969,0,2.304,0,1.484l0,0C0,0.665,0.665,0,1.484,0 h15.032C17.335,0,18,0.665,18,1.484L18,1.484z M18,7.516C18,8.335,17.335,9,16.516,9H1.484C0.665,9,0,8.335,0,7.516l0,0 c0-0.82,0.665-1.484,1.484-1.484h15.032C17.335,6.031,18,6.696,18,7.516L18,7.516z M18,13.516C18,14.335,17.335,15,16.516,15H1.484 C0.665,15,0,14.335,0,13.516l0,0c0-0.82,0.665-1.483,1.484-1.483h15.032C17.335,12.031,18,12.695,18,13.516L18,13.516z"></path>
|
||||||
|
</svg>
|
||||||
|
</span>
|
||||||
|
</label>
|
||||||
|
|
||||||
|
<div class="trigger">
|
||||||
|
<a class="page-link" href="/about.html">ABOUT</a><a class="page-link" href="/archives.html">ARCHIVES</a><a class="page-link" href="/categories.html">CATEGORIES</a><a class="page-link" href="/">HOME</a><a class="page-link" href="/tags.html">TAGS</a>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</nav>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</header>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
function initHeader() {
|
||||||
|
var lastScrollY = getScrollPos().y;
|
||||||
|
var documentElement = document.documentElement;
|
||||||
|
|
||||||
|
function storeScrollData() {
|
||||||
|
var y = getScrollPos().y;var scrollStatus = "";
|
||||||
|
|
||||||
|
if (y <= 0) {
|
||||||
|
scrollStatus = "top";
|
||||||
|
} else if ((window.innerHeight + y) >= document.body.offsetHeight) {
|
||||||
|
scrollStatus = "bottom";
|
||||||
|
} else {
|
||||||
|
var isScrollDown = (y - lastScrollY > 0) ? true : false;
|
||||||
|
scrollStatus = isScrollDown ? "down" : "up";
|
||||||
|
}
|
||||||
|
|
||||||
|
lastScrollY = y;
|
||||||
|
documentElement.setAttribute("data-scroll-status", scrollStatus);
|
||||||
|
}
|
||||||
|
|
||||||
|
window.addEventListener('scroll', function(e) {
|
||||||
|
storeScrollData();
|
||||||
|
});
|
||||||
|
|
||||||
|
storeScrollData();
|
||||||
|
}
|
||||||
|
document.addEventListener('DOMContentLoaded', initHeader);
|
||||||
|
</script>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<script>
|
||||||
|
function hashLocate(hashValue) {
|
||||||
|
hashValue = hashValue.replace(/^.*#h-/, '');
|
||||||
|
hashValue = decodeURIComponent(hashValue);
|
||||||
|
var element = document.getElementById(hashValue);
|
||||||
|
|
||||||
|
if (!element) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var header = document.querySelector('header.site-header');
|
||||||
|
var headerRect = header.getBoundingClientRect();
|
||||||
|
var headerTop = Math.floor(headerRect.top);
|
||||||
|
var headerHeight = Math.floor(headerRect.height);
|
||||||
|
var scrollPos = getScrollPos();
|
||||||
|
var offsetY = element.offsetTop - (headerTop + headerHeight + 20);
|
||||||
|
|
||||||
|
if (offsetY == scrollPos.y) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (headerTop == 0 && offsetY > scrollPos.y) {
|
||||||
|
offsetY += headerHeight + 2;
|
||||||
|
} else if (headerTop < 0 && offsetY < scrollPos.y) {
|
||||||
|
offsetY -= headerHeight - 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
smoothScrollTo(offsetY);
|
||||||
|
}
|
||||||
|
|
||||||
|
// The first event occurred
|
||||||
|
window.addEventListener('load', function(event) {
|
||||||
|
if (window.location.hash) {
|
||||||
|
hashLocate(window.location.hash);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// The first event occurred
|
||||||
|
window.addEventListener('click', function(event) {
|
||||||
|
if (event.target.tagName.toLowerCase() == 'a') {
|
||||||
|
hashLocate(event.target.getAttribute('href'));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
<div class="theme-toggle">
|
||||||
|
<input type="checkbox" id="theme-switch">
|
||||||
|
<label for="theme-switch">
|
||||||
|
<div class="toggle"></div>
|
||||||
|
<div class="names">
|
||||||
|
<p class="light">Light</p>
|
||||||
|
<p class="dark">Dark</p>
|
||||||
|
</div>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<script>
|
||||||
|
(function() {
|
||||||
|
var sw = document.getElementById('theme-switch');
|
||||||
|
var html = document.getElementsByTagName('html')[0];
|
||||||
|
var nightModeOption = ('auto' || 'auto').toLowerCase();
|
||||||
|
var storage = nightModeOption === 'manual'
|
||||||
|
? localStorage
|
||||||
|
: sessionStorage;
|
||||||
|
var themeData = loadThemeData();
|
||||||
|
|
||||||
|
function saveThemeData(data) {
|
||||||
|
storage.setItem('theme', JSON.stringify(data));
|
||||||
|
}
|
||||||
|
|
||||||
|
function loadThemeData() {
|
||||||
|
var data = storage.getItem('theme');
|
||||||
|
try {
|
||||||
|
data = JSON.parse(data ? data : '');
|
||||||
|
} catch(e) {
|
||||||
|
data = { nightShift: undefined, autoToggleAt: 0 };
|
||||||
|
saveThemeData(data);
|
||||||
|
}
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleThemeToggle(nightShift) {
|
||||||
|
themeData.nightShift = nightShift;
|
||||||
|
saveThemeData(themeData);
|
||||||
|
html.dataset.theme = nightShift ? 'dark' : 'light';
|
||||||
|
setTimeout(function() {
|
||||||
|
sw.checked = nightShift ? true : false;
|
||||||
|
}, 50);
|
||||||
|
}
|
||||||
|
|
||||||
|
function autoThemeToggle() {
|
||||||
|
// Next time point of theme toggle
|
||||||
|
var now = new Date();
|
||||||
|
var toggleAt = new Date();
|
||||||
|
var hours = now.getHours();
|
||||||
|
var nightShift = hours >= 19 || hours <=7;
|
||||||
|
|
||||||
|
if (nightShift) {
|
||||||
|
if (hours > 7) {
|
||||||
|
toggleAt.setDate(toggleAt.getDate() + 1);
|
||||||
|
}
|
||||||
|
toggleAt.setHours(7);
|
||||||
|
} else {
|
||||||
|
toggleAt.setHours(19);
|
||||||
|
}
|
||||||
|
|
||||||
|
toggleAt.setMinutes(0);
|
||||||
|
toggleAt.setSeconds(0);
|
||||||
|
toggleAt.setMilliseconds(0)
|
||||||
|
|
||||||
|
var delay = toggleAt.getTime() - now.getTime();
|
||||||
|
|
||||||
|
// auto toggle theme mode
|
||||||
|
setTimeout(function() {
|
||||||
|
handleThemeToggle(!nightShift);
|
||||||
|
}, delay);
|
||||||
|
|
||||||
|
return {
|
||||||
|
nightShift: nightShift,
|
||||||
|
toggleAt: toggleAt.getTime()
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// Listen the theme toggle event
|
||||||
|
sw.addEventListener('change', function(event) {
|
||||||
|
handleThemeToggle(event.target.checked);
|
||||||
|
});
|
||||||
|
|
||||||
|
if (nightModeOption == 'auto') {
|
||||||
|
var data = autoThemeToggle();
|
||||||
|
|
||||||
|
// Toggle theme by local setting
|
||||||
|
if (data.toggleAt > themeData.autoToggleAt) {
|
||||||
|
themeData.autoToggleAt = data.toggleAt;
|
||||||
|
handleThemeToggle(data.nightShift);
|
||||||
|
} else {
|
||||||
|
handleThemeToggle(themeData.nightShift);
|
||||||
|
}
|
||||||
|
} else if (nightModeOption == 'manual') {
|
||||||
|
handleThemeToggle(themeData.nightShift);
|
||||||
|
} else {
|
||||||
|
var nightShift = themeData.nightShift;
|
||||||
|
if (nightShift === undefined) {
|
||||||
|
nightShift = nightModeOption === 'on';
|
||||||
|
}
|
||||||
|
handleThemeToggle(nightShift);
|
||||||
|
}
|
||||||
|
})();
|
||||||
|
</script>
|
||||||
|
<div id="click-to-top" class="click-to-top">
|
||||||
|
<i class="fa fa-arrow-up"></i>
|
||||||
|
</div>
|
||||||
|
<script>
|
||||||
|
(function () {
|
||||||
|
const clickToTop = document.getElementById('click-to-top');
|
||||||
|
window.addEventListener('scroll', () => {
|
||||||
|
if (window.scrollY > 100) {
|
||||||
|
clickToTop.classList.add('show')
|
||||||
|
}else {
|
||||||
|
clickToTop.classList.remove('show')
|
||||||
|
}
|
||||||
|
});
|
||||||
|
clickToTop.addEventListener('click', () => {
|
||||||
|
window.smoothScrollTo(0);
|
||||||
|
});
|
||||||
|
})();
|
||||||
|
</script>
|
||||||
|
<main class="page-content" aria-label="Content">
|
||||||
|
<div class="wrapper">
|
||||||
|
<div class="framework">
|
||||||
|
<section class="main">
|
||||||
|
|
||||||
|
<div class="post">
|
||||||
|
<section>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<header class="post-header">
|
||||||
|
<h1 class="post-title p-name" itemprop="name headline">Automatizace, automatizace, automatizace</h1>
|
||||||
|
<h2 class="post-subtitle">Ulehčujeme si život</h2>
|
||||||
|
|
||||||
|
<p class="post-meta">
|
||||||
|
<time class="dt-published" datetime="2022-05-22T00:00:00+00:00" itemprop="datePublished"><i class="fa fa-calendar"></i> May 22, 2022
|
||||||
|
</time>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<span class="post-reading-time left-vsplit"><i class="fa fa-clock-o"></i> About 1 min</span>
|
||||||
|
</p>
|
||||||
|
<div class="post-tags">
|
||||||
|
<a class="post-tag" href="/tags.html#automatizace">#automatizace</a><a class="post-tag" href="/tags.html#technologie">#technologie</a>
|
||||||
|
</div></header>
|
||||||
|
<article class="post h-entry" itemscope itemtype="http://schema.org/BlogPosting">
|
||||||
|
|
||||||
|
<div class="post-content e-content" itemprop="articleBody">
|
||||||
|
|
||||||
|
<p>Roboti nám brzo vezmou práci, ale mně to (prozatím) nevadí. Já nechávám robůtky pracovat za mě a ulehčovat mi práci. A vy byste měli taky! Pokud teda programujete, jinak nevím.</p>
|
||||||
|
|
||||||
|
<p>Nedávno jsem objevil krásy zvané GitHub Actions a musím říct, že je to opravdu radost. Nikdy předtím jsem nedokázal pochopit jejich praktičnost, než jsem pracoval na <a href="https://github.com/hernikplays/opencanteen">OpenCanteen</a>. Sestavovat, podepisovat a nahrávat mě opravdu nebavilo a ještě s mým pomalým PC v kombinaci s pomalým internetem to nešlo zrovna rychle. Pak jsem si vzpomněl na GitHub Actions. Místo toho, abych dělal cokoliv produktivního, jsem strávil celé odpoledne nastavováním Actions, aby mi při novém tagu automaticky sestavil a publikoval vydání aplikace do Google Play.</p>
|
||||||
|
|
||||||
|
<p>Ta první část šla skvěle, avšak nahrávání do Google Play bylo o něco složitější, dokud jsem neobjevil hotové a, prozatím bezplatné, řešení <a href="https://codemagic.io/start/">CodeMagic</a>.</p>
|
||||||
|
|
||||||
|
<p>Jednoduše jsem napojil repozitář, nastavil podepisovací a nahrávací údaje a všechno hned jelo! Byla to radost pro někoho tak líného jako jsem já. I přesto, že jsem sám reálně nic neudělal, cítil jsem, že jsem dosáhl něčeho úžasného.</p>
|
||||||
|
|
||||||
|
<p>A určitě to lze dotáhnout ještě dál, už teď používám Actions pro automatickou analýzu kódu, a kdybych si vytvořil testy tak by mi to určitě i otestovalo celou aplikaci.</p>
|
||||||
|
|
||||||
|
<p>Pak jsem si řekl, že by možná mohl někdo chtít do mé aplikace přispět svým kódem. Protože chci v tom mít pořádek, hned jsem začal projíždět GitHub Marketplace pro nějaké akce na pull requesty. Hned jsem jich několik objevil.</p>
|
||||||
|
|
||||||
|
<p>Velice jsem ocenil akci, která mi automaticky přidala labely podle souboru, který byl v PR upraven.</p>
|
||||||
|
|
||||||
|
<p>Určitě nepotřebujete nutně automatizovat všechno, pokud máte např. soukromý či malý projekt. Nicméně si to můžete aspoň otestovat a případně využít v budoucnu tak se do toho pusťte! Automatizovat můžete všechno možné. Určitě budete mít dobrý pocit, když se vaše akce spustí a úspěšně se dokončí.</p>
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</article>
|
||||||
|
<div class="post-nav">
|
||||||
|
<span></span><a class="next" href="/vychyt%C3%A1vky/2022/05/31/codespaces.html" title="GitHub Codespaces aneb VS Code na VPS">GitHub Codespaces aneb VS Code na...</a>
|
||||||
|
</div>
|
||||||
|
<div class="post-related">
|
||||||
|
<div>Related Articles</div>
|
||||||
|
<ul>
|
||||||
|
<li><a class="post-link" href="/programov%C3%A1n%C3%AD/2022/05/22/automatizace.html" title="GitHub Codespaces aneb VS Code na VPS">Automatizace, automatizace, automatizace</a></li>
|
||||||
|
<li><a class="post-link" href="/tutori%C3%A1l/2022/10/22/rpi-arch.html" title="GitHub Codespaces aneb VS Code na VPS">Instalujeme Arch Linux ARM na Raspberry Pi 3</a></li>
|
||||||
|
<li><a class="post-link" href="/vychyt%C3%A1vky/2022/05/31/codespaces.html" title="GitHub Codespaces aneb VS Code na VPS">GitHub Codespaces aneb VS Code na VPS</a></li>
|
||||||
|
<li><a class="post-link" href="/bezpe%C4%8D%C3%AD/2022/07/19/nordvpn.html" title="GitHub Codespaces aneb VS Code na VPS">NordVPN - Jste opravdu v takovém nebezpečí?</a></li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
<div class="post-comments"> <div id="gitment_thread" class="giscus"></div>
|
||||||
|
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/theme-next/theme-next-gitment@1/default.css">
|
||||||
|
<script src="https://cdn.jsdelivr.net/gh/theme-next/theme-next-gitment@1/gitment.browser.js"></script>
|
||||||
|
<script src="https://giscus.app/client.js" data-repo="hernikplays/blog" data-repo-id="R_kgDOHr2B6w" data-category="General" data-category-id="DIC_kwDOHr2B684CSIhA" data-mapping="pathname" data-strict="0" data-reactions-enabled="1" data-emit-metadata="0" data-input-position="top" data-theme="transparent_dark" data-lang="en" data-loading="lazy" crossorigin="anonymous" async>
|
||||||
|
</script>
|
||||||
|
</div></section>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
</section>
|
||||||
|
<section class="sidebar" style="margin-left: 15px;">
|
||||||
|
<!-- Get sidebar items --></section>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</main><footer class="site-footer h-card">
|
||||||
|
<data class="u-url" href="/"></data>
|
||||||
|
|
||||||
|
<div class="wrapper">
|
||||||
|
<div class="site-footer-inner">
|
||||||
|
<div>Copyright © 2021-2022 hernikplays</div>
|
||||||
|
<div>Powered by <a title="Jekyll is a simple, blog-aware, static site
|
||||||
|
generator." href="https://jekyllrb.com/">Jekyll</a> & <a title="Yat, yet
|
||||||
|
another theme." href="https://github.com/jeffreytse/jekyll-theme-yat">Yat Theme</a>.</div>
|
||||||
|
<div><a rel="me" href="https://social.linux.pizza/@hernik">Mastodon</a></div>
|
||||||
|
<div class="footer-col rss-subscribe">Subscribe <a href="/feed.xml">via RSS</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</footer>
|
||||||
|
</body>
|
||||||
|
</html>
|
1
robots.txt
Normal file
|
@ -0,0 +1 @@
|
||||||
|
Sitemap: https://caras.cafe/sitemap.xml
|
34
sitemap.xml
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<urlset xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.sitemaps.org/schemas/sitemap/0.9 http://www.sitemaps.org/schemas/sitemap/0.9/sitemap.xsd" xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
|
||||||
|
<url>
|
||||||
|
<loc>https://caras.cafe/programov%C3%A1n%C3%AD/2022/05/22/automatizace.html</loc>
|
||||||
|
<lastmod>2022-05-22T00:00:00+00:00</lastmod>
|
||||||
|
</url>
|
||||||
|
<url>
|
||||||
|
<loc>https://caras.cafe/vychyt%C3%A1vky/2022/05/31/codespaces.html</loc>
|
||||||
|
<lastmod>2022-05-31T00:00:00+00:00</lastmod>
|
||||||
|
</url>
|
||||||
|
<url>
|
||||||
|
<loc>https://caras.cafe/bezpe%C4%8D%C3%AD/2022/07/19/nordvpn.html</loc>
|
||||||
|
<lastmod>2022-07-19T00:00:00+00:00</lastmod>
|
||||||
|
</url>
|
||||||
|
<url>
|
||||||
|
<loc>https://caras.cafe/tutori%C3%A1l/2022/10/22/rpi-arch.html</loc>
|
||||||
|
<lastmod>2022-10-22T00:00:00+00:00</lastmod>
|
||||||
|
</url>
|
||||||
|
<url>
|
||||||
|
<loc>https://caras.cafe/about.html</loc>
|
||||||
|
</url>
|
||||||
|
<url>
|
||||||
|
<loc>https://caras.cafe/archives.html</loc>
|
||||||
|
</url>
|
||||||
|
<url>
|
||||||
|
<loc>https://caras.cafe/categories.html</loc>
|
||||||
|
</url>
|
||||||
|
<url>
|
||||||
|
<loc>https://caras.cafe/</loc>
|
||||||
|
</url>
|
||||||
|
<url>
|
||||||
|
<loc>https://caras.cafe/tags.html</loc>
|
||||||
|
</url>
|
||||||
|
</urlset>
|
913
tags.html
Normal file
|
@ -0,0 +1,913 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
|
<meta name="google-translate-customization" content="108d9124921d80c3-80e20d618ff053c8-g4f02ec6f3dba68b7-c">
|
||||||
|
<!-- Begin Jekyll SEO tag v2.8.0 -->
|
||||||
|
<title>Tags | Matyáš Caras</title>
|
||||||
|
<meta name="generator" content="Jekyll v4.3.1">
|
||||||
|
<meta property="og:title" content="Tags">
|
||||||
|
<meta name="author" content="hernikplays">
|
||||||
|
<meta property="og:locale" content="en_US">
|
||||||
|
<meta name="description" content="Welcome to my website/blog, full of weird stuff written by yours truly.">
|
||||||
|
<meta property="og:description" content="Welcome to my website/blog, full of weird stuff written by yours truly.">
|
||||||
|
<link rel="canonical" href="https://caras.cafe/tags.html">
|
||||||
|
<meta property="og:url" content="https://caras.cafe/tags.html">
|
||||||
|
<meta property="og:site_name" content="Matyáš Caras">
|
||||||
|
<meta property="og:type" content="website">
|
||||||
|
<meta name="twitter:card" content="summary">
|
||||||
|
<meta property="twitter:title" content="Tags">
|
||||||
|
<script type="application/ld+json">
|
||||||
|
{"@context":"https://schema.org","@type":"WebPage","author":{"@type":"Person","name":"hernikplays"},"description":"Welcome to my website/blog, full of weird stuff written by yours truly.","headline":"Tags","url":"https://caras.cafe/tags.html"}</script>
|
||||||
|
<!-- End Jekyll SEO tag -->
|
||||||
|
<link rel="shortcut icon" href="">
|
||||||
|
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
|
||||||
|
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/typeface-noto-sans@0.0.72/index.min.css">
|
||||||
|
<link rel="stylesheet" href="/assets/css/main.css">
|
||||||
|
<script src="/assets/js/main.js"></script><link type="application/atom+xml" rel="alternate" href="https://caras.cafe/feed.xml" title="Matyáš Caras">
|
||||||
|
<link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/highlight.js/10.1.1/styles/default.min.css">
|
||||||
|
<script src="//cdnjs.cloudflare.com/ajax/libs/highlight.js/10.1.1/highlight.min.js"></script>
|
||||||
|
<!-- and it's easy to individually load additional languages -->
|
||||||
|
<script charset="UTF-8" src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.1.1/languages/go.min.js"></script>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<script>
|
||||||
|
// Init highlight js
|
||||||
|
document.addEventListener('DOMContentLoaded', function(event) {
|
||||||
|
var els = document.querySelectorAll('pre code')
|
||||||
|
|
||||||
|
function addLangData(block) {
|
||||||
|
var outer = block.parentElement.parentElement.parentElement;
|
||||||
|
var lang = block.getAttribute('data-lang');
|
||||||
|
for (var i = 0; i < outer.classList.length; i++) {
|
||||||
|
var cls = outer.classList[i];
|
||||||
|
if (cls.startsWith('language-')) {
|
||||||
|
lang = cls;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!lang) {
|
||||||
|
cls = block.getAttribute('class');
|
||||||
|
lang = cls ? cls.replace('hljs ', '') : '';
|
||||||
|
}
|
||||||
|
if (lang.startsWith('language-')) {
|
||||||
|
lang = lang.substr(9);
|
||||||
|
}
|
||||||
|
block.setAttribute('class', 'hljs ' + lang);
|
||||||
|
block.parentNode.setAttribute('data-lang', lang);
|
||||||
|
}
|
||||||
|
|
||||||
|
function addBadge(block) {
|
||||||
|
var enabled = ('true' || 'true').toLowerCase();
|
||||||
|
if (enabled == 'true') {
|
||||||
|
var pre = block.parentElement;
|
||||||
|
pre.classList.add('badge');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function handle(block) {
|
||||||
|
addLangData(block);
|
||||||
|
addBadge(block)
|
||||||
|
hljs.highlightBlock(block);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (var i = 0; i < els.length; i++) {
|
||||||
|
var el = els[i];
|
||||||
|
handle(el);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
/* code language badge */
|
||||||
|
pre.badge::before {
|
||||||
|
content: attr(data-lang);
|
||||||
|
color: #fff;
|
||||||
|
background-color: #ff4e00;
|
||||||
|
padding: 0 .5em;
|
||||||
|
border-radius: 0 2px;
|
||||||
|
text-transform: uppercase;
|
||||||
|
text-align: center;
|
||||||
|
min-width: 32px;
|
||||||
|
display: inline-block;
|
||||||
|
position: absolute;
|
||||||
|
right: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* fix wrong badge display for firefox browser */
|
||||||
|
code > table pre::before {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<header class="site-header " role="banner">
|
||||||
|
|
||||||
|
<div class="wrapper">
|
||||||
|
<div class="site-header-inner">
|
||||||
|
<span class="site-brand"><a class="site-brand-inner" rel="author" href="/">
|
||||||
|
<img class="site-favicon" title="Matyáš Caras" src="" onerror="this.style.display='none'">
|
||||||
|
Matyáš Caras
|
||||||
|
</a>
|
||||||
|
</span><nav class="site-nav">
|
||||||
|
<input type="checkbox" id="nav-trigger" class="nav-trigger">
|
||||||
|
<label for="nav-trigger">
|
||||||
|
<span class="menu-icon">
|
||||||
|
<svg viewbox="0 0 18 15" width="18px" height="15px">
|
||||||
|
<path d="M18,1.484c0,0.82-0.665,1.484-1.484,1.484H1.484C0.665,2.969,0,2.304,0,1.484l0,0C0,0.665,0.665,0,1.484,0 h15.032C17.335,0,18,0.665,18,1.484L18,1.484z M18,7.516C18,8.335,17.335,9,16.516,9H1.484C0.665,9,0,8.335,0,7.516l0,0 c0-0.82,0.665-1.484,1.484-1.484h15.032C17.335,6.031,18,6.696,18,7.516L18,7.516z M18,13.516C18,14.335,17.335,15,16.516,15H1.484 C0.665,15,0,14.335,0,13.516l0,0c0-0.82,0.665-1.483,1.484-1.483h15.032C17.335,12.031,18,12.695,18,13.516L18,13.516z"></path>
|
||||||
|
</svg>
|
||||||
|
</span>
|
||||||
|
</label>
|
||||||
|
|
||||||
|
<div class="trigger">
|
||||||
|
<a class="page-link" href="/about.html">ABOUT</a><a class="page-link" href="/archives.html">ARCHIVES</a><a class="page-link" href="/categories.html">CATEGORIES</a><a class="page-link" href="/">HOME</a><a class="page-link" href="/tags.html">TAGS</a>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</nav>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</header>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
function initHeader() {
|
||||||
|
var lastScrollY = getScrollPos().y;
|
||||||
|
var documentElement = document.documentElement;
|
||||||
|
|
||||||
|
function storeScrollData() {
|
||||||
|
var y = getScrollPos().y;var scrollStatus = "";
|
||||||
|
|
||||||
|
if (y <= 0) {
|
||||||
|
scrollStatus = "top";
|
||||||
|
} else if ((window.innerHeight + y) >= document.body.offsetHeight) {
|
||||||
|
scrollStatus = "bottom";
|
||||||
|
} else {
|
||||||
|
var isScrollDown = (y - lastScrollY > 0) ? true : false;
|
||||||
|
scrollStatus = isScrollDown ? "down" : "up";
|
||||||
|
}
|
||||||
|
|
||||||
|
lastScrollY = y;
|
||||||
|
documentElement.setAttribute("data-scroll-status", scrollStatus);
|
||||||
|
}
|
||||||
|
|
||||||
|
window.addEventListener('scroll', function(e) {
|
||||||
|
storeScrollData();
|
||||||
|
});
|
||||||
|
|
||||||
|
storeScrollData();
|
||||||
|
}
|
||||||
|
document.addEventListener('DOMContentLoaded', initHeader);
|
||||||
|
</script>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<script>
|
||||||
|
function hashLocate(hashValue) {
|
||||||
|
hashValue = hashValue.replace(/^.*#h-/, '');
|
||||||
|
hashValue = decodeURIComponent(hashValue);
|
||||||
|
var element = document.getElementById(hashValue);
|
||||||
|
|
||||||
|
if (!element) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var header = document.querySelector('header.site-header');
|
||||||
|
var headerRect = header.getBoundingClientRect();
|
||||||
|
var headerTop = Math.floor(headerRect.top);
|
||||||
|
var headerHeight = Math.floor(headerRect.height);
|
||||||
|
var scrollPos = getScrollPos();
|
||||||
|
var offsetY = element.offsetTop - (headerTop + headerHeight + 20);
|
||||||
|
|
||||||
|
if (offsetY == scrollPos.y) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (headerTop == 0 && offsetY > scrollPos.y) {
|
||||||
|
offsetY += headerHeight + 2;
|
||||||
|
} else if (headerTop < 0 && offsetY < scrollPos.y) {
|
||||||
|
offsetY -= headerHeight - 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
smoothScrollTo(offsetY);
|
||||||
|
}
|
||||||
|
|
||||||
|
// The first event occurred
|
||||||
|
window.addEventListener('load', function(event) {
|
||||||
|
if (window.location.hash) {
|
||||||
|
hashLocate(window.location.hash);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// The first event occurred
|
||||||
|
window.addEventListener('click', function(event) {
|
||||||
|
if (event.target.tagName.toLowerCase() == 'a') {
|
||||||
|
hashLocate(event.target.getAttribute('href'));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
<div class="theme-toggle">
|
||||||
|
<input type="checkbox" id="theme-switch">
|
||||||
|
<label for="theme-switch">
|
||||||
|
<div class="toggle"></div>
|
||||||
|
<div class="names">
|
||||||
|
<p class="light">Light</p>
|
||||||
|
<p class="dark">Dark</p>
|
||||||
|
</div>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<script>
|
||||||
|
(function() {
|
||||||
|
var sw = document.getElementById('theme-switch');
|
||||||
|
var html = document.getElementsByTagName('html')[0];
|
||||||
|
var nightModeOption = ('auto' || 'auto').toLowerCase();
|
||||||
|
var storage = nightModeOption === 'manual'
|
||||||
|
? localStorage
|
||||||
|
: sessionStorage;
|
||||||
|
var themeData = loadThemeData();
|
||||||
|
|
||||||
|
function saveThemeData(data) {
|
||||||
|
storage.setItem('theme', JSON.stringify(data));
|
||||||
|
}
|
||||||
|
|
||||||
|
function loadThemeData() {
|
||||||
|
var data = storage.getItem('theme');
|
||||||
|
try {
|
||||||
|
data = JSON.parse(data ? data : '');
|
||||||
|
} catch(e) {
|
||||||
|
data = { nightShift: undefined, autoToggleAt: 0 };
|
||||||
|
saveThemeData(data);
|
||||||
|
}
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleThemeToggle(nightShift) {
|
||||||
|
themeData.nightShift = nightShift;
|
||||||
|
saveThemeData(themeData);
|
||||||
|
html.dataset.theme = nightShift ? 'dark' : 'light';
|
||||||
|
setTimeout(function() {
|
||||||
|
sw.checked = nightShift ? true : false;
|
||||||
|
}, 50);
|
||||||
|
}
|
||||||
|
|
||||||
|
function autoThemeToggle() {
|
||||||
|
// Next time point of theme toggle
|
||||||
|
var now = new Date();
|
||||||
|
var toggleAt = new Date();
|
||||||
|
var hours = now.getHours();
|
||||||
|
var nightShift = hours >= 19 || hours <=7;
|
||||||
|
|
||||||
|
if (nightShift) {
|
||||||
|
if (hours > 7) {
|
||||||
|
toggleAt.setDate(toggleAt.getDate() + 1);
|
||||||
|
}
|
||||||
|
toggleAt.setHours(7);
|
||||||
|
} else {
|
||||||
|
toggleAt.setHours(19);
|
||||||
|
}
|
||||||
|
|
||||||
|
toggleAt.setMinutes(0);
|
||||||
|
toggleAt.setSeconds(0);
|
||||||
|
toggleAt.setMilliseconds(0)
|
||||||
|
|
||||||
|
var delay = toggleAt.getTime() - now.getTime();
|
||||||
|
|
||||||
|
// auto toggle theme mode
|
||||||
|
setTimeout(function() {
|
||||||
|
handleThemeToggle(!nightShift);
|
||||||
|
}, delay);
|
||||||
|
|
||||||
|
return {
|
||||||
|
nightShift: nightShift,
|
||||||
|
toggleAt: toggleAt.getTime()
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// Listen the theme toggle event
|
||||||
|
sw.addEventListener('change', function(event) {
|
||||||
|
handleThemeToggle(event.target.checked);
|
||||||
|
});
|
||||||
|
|
||||||
|
if (nightModeOption == 'auto') {
|
||||||
|
var data = autoThemeToggle();
|
||||||
|
|
||||||
|
// Toggle theme by local setting
|
||||||
|
if (data.toggleAt > themeData.autoToggleAt) {
|
||||||
|
themeData.autoToggleAt = data.toggleAt;
|
||||||
|
handleThemeToggle(data.nightShift);
|
||||||
|
} else {
|
||||||
|
handleThemeToggle(themeData.nightShift);
|
||||||
|
}
|
||||||
|
} else if (nightModeOption == 'manual') {
|
||||||
|
handleThemeToggle(themeData.nightShift);
|
||||||
|
} else {
|
||||||
|
var nightShift = themeData.nightShift;
|
||||||
|
if (nightShift === undefined) {
|
||||||
|
nightShift = nightModeOption === 'on';
|
||||||
|
}
|
||||||
|
handleThemeToggle(nightShift);
|
||||||
|
}
|
||||||
|
})();
|
||||||
|
</script>
|
||||||
|
<div id="click-to-top" class="click-to-top">
|
||||||
|
<i class="fa fa-arrow-up"></i>
|
||||||
|
</div>
|
||||||
|
<script>
|
||||||
|
(function () {
|
||||||
|
const clickToTop = document.getElementById('click-to-top');
|
||||||
|
window.addEventListener('scroll', () => {
|
||||||
|
if (window.scrollY > 100) {
|
||||||
|
clickToTop.classList.add('show')
|
||||||
|
}else {
|
||||||
|
clickToTop.classList.remove('show')
|
||||||
|
}
|
||||||
|
});
|
||||||
|
clickToTop.addEventListener('click', () => {
|
||||||
|
window.smoothScrollTo(0);
|
||||||
|
});
|
||||||
|
})();
|
||||||
|
</script>
|
||||||
|
<main class="page-content" aria-label="Content">
|
||||||
|
<div class="wrapper">
|
||||||
|
<div class="framework">
|
||||||
|
<section class="main">
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<div class="page-segments">
|
||||||
|
<ul class="page-segments-list">
|
||||||
|
|
||||||
|
<h2 id="arch" class="segment-name">arch</h2>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<li>
|
||||||
|
<span class="post-meta">Oct 22, 2022</span>
|
||||||
|
<span>
|
||||||
|
<a class="post-link" href="/tutori%C3%A1l/2022/10/22/rpi-arch.html">
|
||||||
|
Instalujeme Arch Linux ARM na Raspberry Pi 3
|
||||||
|
</a>
|
||||||
|
</span>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<h2 id="automatizace" class="segment-name">automatizace</h2>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<li>
|
||||||
|
<span class="post-meta">May 22, 2022</span>
|
||||||
|
<span>
|
||||||
|
<a class="post-link" href="/programov%C3%A1n%C3%AD/2022/05/22/automatizace.html">
|
||||||
|
Automatizace, automatizace, automatizace
|
||||||
|
</a>
|
||||||
|
</span>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<h2 id="github" class="segment-name">github</h2>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<li>
|
||||||
|
<span class="post-meta">May 31, 2022</span>
|
||||||
|
<span>
|
||||||
|
<a class="post-link" href="/vychyt%C3%A1vky/2022/05/31/codespaces.html">
|
||||||
|
GitHub Codespaces aneb VS Code na VPS
|
||||||
|
</a>
|
||||||
|
</span>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<h2 id="návod" class="segment-name">návod</h2>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<li>
|
||||||
|
<span class="post-meta">Oct 22, 2022</span>
|
||||||
|
<span>
|
||||||
|
<a class="post-link" href="/tutori%C3%A1l/2022/10/22/rpi-arch.html">
|
||||||
|
Instalujeme Arch Linux ARM na Raspberry Pi 3
|
||||||
|
</a>
|
||||||
|
</span>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<h2 id="reklamy" class="segment-name">reklamy</h2>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<li>
|
||||||
|
<span class="post-meta">Jul 19, 2022</span>
|
||||||
|
<span>
|
||||||
|
<a class="post-link" href="/bezpe%C4%8D%C3%AD/2022/07/19/nordvpn.html">
|
||||||
|
NordVPN - Jste opravdu v takovém nebezpečí?
|
||||||
|
</a>
|
||||||
|
</span>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<h2 id="rpi" class="segment-name">rpi</h2>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<li>
|
||||||
|
<span class="post-meta">Oct 22, 2022</span>
|
||||||
|
<span>
|
||||||
|
<a class="post-link" href="/tutori%C3%A1l/2022/10/22/rpi-arch.html">
|
||||||
|
Instalujeme Arch Linux ARM na Raspberry Pi 3
|
||||||
|
</a>
|
||||||
|
</span>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<h2 id="technologie" class="segment-name">technologie</h2>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<li>
|
||||||
|
<span class="post-meta">May 22, 2022</span>
|
||||||
|
<span>
|
||||||
|
<a class="post-link" href="/programov%C3%A1n%C3%AD/2022/05/22/automatizace.html">
|
||||||
|
Automatizace, automatizace, automatizace
|
||||||
|
</a>
|
||||||
|
</span>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<h2 id="vpn" class="segment-name">vpn</h2>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<li>
|
||||||
|
<span class="post-meta">Jul 19, 2022</span>
|
||||||
|
<span>
|
||||||
|
<a class="post-link" href="/bezpe%C4%8D%C3%AD/2022/07/19/nordvpn.html">
|
||||||
|
NordVPN - Jste opravdu v takovém nebezpečí?
|
||||||
|
</a>
|
||||||
|
</span>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<h2 id="vps" class="segment-name">vps</h2>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<li>
|
||||||
|
<span class="post-meta">May 31, 2022</span>
|
||||||
|
<span>
|
||||||
|
<a class="post-link" href="/vychyt%C3%A1vky/2022/05/31/codespaces.html">
|
||||||
|
GitHub Codespaces aneb VS Code na VPS
|
||||||
|
</a>
|
||||||
|
</span>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<h2 id="youtube" class="segment-name">youtube</h2>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<li>
|
||||||
|
<span class="post-meta">Jul 19, 2022</span>
|
||||||
|
<span>
|
||||||
|
<a class="post-link" href="/bezpe%C4%8D%C3%AD/2022/07/19/nordvpn.html">
|
||||||
|
NordVPN - Jste opravdu v takovém nebezpečí?
|
||||||
|
</a>
|
||||||
|
</span>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
</section>
|
||||||
|
<section class="sidebar" style="margin-left: 15px;">
|
||||||
|
<!-- Get sidebar items -->
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<div class="common-list">
|
||||||
|
<ul>
|
||||||
|
<li>
|
||||||
|
<a href="/index.html">
|
||||||
|
All<span>4</span>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
|
||||||
|
<li>
|
||||||
|
<a href="/tags.html#h-arch">
|
||||||
|
arch <span>1</span>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<li>
|
||||||
|
<a href="/tags.html#h-automatizace">
|
||||||
|
automatizace <span>1</span>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<li>
|
||||||
|
<a href="/tags.html#h-github">
|
||||||
|
github <span>1</span>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<li>
|
||||||
|
<a href="/tags.html#h-n%C3%A1vod">
|
||||||
|
návod <span>1</span>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<li>
|
||||||
|
<a href="/tags.html#h-reklamy">
|
||||||
|
reklamy <span>1</span>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<li>
|
||||||
|
<a href="/tags.html#h-rpi">
|
||||||
|
rpi <span>1</span>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<li>
|
||||||
|
<a href="/tags.html#h-technologie">
|
||||||
|
technologie <span>1</span>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<li>
|
||||||
|
<a href="/tags.html#h-vpn">
|
||||||
|
vpn <span>1</span>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<li>
|
||||||
|
<a href="/tags.html#h-vps">
|
||||||
|
vps <span>1</span>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<li>
|
||||||
|
<a href="/tags.html#h-youtube">
|
||||||
|
youtube <span>1</span>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</main><footer class="site-footer h-card">
|
||||||
|
<data class="u-url" href="/"></data>
|
||||||
|
|
||||||
|
<div class="wrapper">
|
||||||
|
<div class="site-footer-inner">
|
||||||
|
<div>Copyright © 2021-2022 hernikplays</div>
|
||||||
|
<div>Powered by <a title="Jekyll is a simple, blog-aware, static site
|
||||||
|
generator." href="https://jekyllrb.com/">Jekyll</a> & <a title="Yat, yet
|
||||||
|
another theme." href="https://github.com/jeffreytse/jekyll-theme-yat">Yat Theme</a>.</div>
|
||||||
|
<div><a rel="me" href="https://social.linux.pizza/@hernik">Mastodon</a></div>
|
||||||
|
<div class="footer-col rss-subscribe">Subscribe <a href="/feed.xml">via RSS</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</footer>
|
||||||
|
</body>
|
||||||
|
</html>
|
827
tutoriál/2022/10/22/rpi-arch.html
Normal file
|
@ -0,0 +1,827 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
|
<meta name="google-translate-customization" content="108d9124921d80c3-80e20d618ff053c8-g4f02ec6f3dba68b7-c">
|
||||||
|
<!-- Begin Jekyll SEO tag v2.8.0 -->
|
||||||
|
<title>Instalujeme Arch Linux ARM na Raspberry Pi 3 | Matyáš Caras</title>
|
||||||
|
<meta name="generator" content="Jekyll v4.3.1">
|
||||||
|
<meta property="og:title" content="Instalujeme Arch Linux ARM na Raspberry Pi 3">
|
||||||
|
<meta name="author" content="hernikplays">
|
||||||
|
<meta property="og:locale" content="en_US">
|
||||||
|
<meta name="description" content="Welcome to my website/blog, full of weird stuff written by yours truly.">
|
||||||
|
<meta property="og:description" content="Welcome to my website/blog, full of weird stuff written by yours truly.">
|
||||||
|
<link rel="canonical" href="https://caras.cafe/tutori%C3%A1l/2022/10/22/rpi-arch.html">
|
||||||
|
<meta property="og:url" content="https://caras.cafe/tutori%C3%A1l/2022/10/22/rpi-arch.html">
|
||||||
|
<meta property="og:site_name" content="Matyáš Caras">
|
||||||
|
<meta property="og:type" content="article">
|
||||||
|
<meta property="article:published_time" content="2022-10-22T00:00:00+00:00">
|
||||||
|
<meta name="twitter:card" content="summary">
|
||||||
|
<meta property="twitter:title" content="Instalujeme Arch Linux ARM na Raspberry Pi 3">
|
||||||
|
<script type="application/ld+json">
|
||||||
|
{"@context":"https://schema.org","@type":"BlogPosting","author":{"@type":"Person","name":"hernikplays"},"dateModified":"2022-10-22T00:00:00+00:00","datePublished":"2022-10-22T00:00:00+00:00","description":"Welcome to my website/blog, full of weird stuff written by yours truly.","headline":"Instalujeme Arch Linux ARM na Raspberry Pi 3","mainEntityOfPage":{"@type":"WebPage","@id":"https://caras.cafe/tutori%C3%A1l/2022/10/22/rpi-arch.html"},"url":"https://caras.cafe/tutori%C3%A1l/2022/10/22/rpi-arch.html"}</script>
|
||||||
|
<!-- End Jekyll SEO tag -->
|
||||||
|
<link rel="shortcut icon" href="">
|
||||||
|
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
|
||||||
|
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/typeface-noto-sans@0.0.72/index.min.css">
|
||||||
|
<link rel="stylesheet" href="/assets/css/main.css">
|
||||||
|
<script src="/assets/js/main.js"></script><link type="application/atom+xml" rel="alternate" href="https://caras.cafe/feed.xml" title="Matyáš Caras">
|
||||||
|
<link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/highlight.js/10.1.1/styles/default.min.css">
|
||||||
|
<script src="//cdnjs.cloudflare.com/ajax/libs/highlight.js/10.1.1/highlight.min.js"></script>
|
||||||
|
<!-- and it's easy to individually load additional languages -->
|
||||||
|
<script charset="UTF-8" src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.1.1/languages/go.min.js"></script>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<script>
|
||||||
|
// Init highlight js
|
||||||
|
document.addEventListener('DOMContentLoaded', function(event) {
|
||||||
|
var els = document.querySelectorAll('pre code')
|
||||||
|
|
||||||
|
function addLangData(block) {
|
||||||
|
var outer = block.parentElement.parentElement.parentElement;
|
||||||
|
var lang = block.getAttribute('data-lang');
|
||||||
|
for (var i = 0; i < outer.classList.length; i++) {
|
||||||
|
var cls = outer.classList[i];
|
||||||
|
if (cls.startsWith('language-')) {
|
||||||
|
lang = cls;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!lang) {
|
||||||
|
cls = block.getAttribute('class');
|
||||||
|
lang = cls ? cls.replace('hljs ', '') : '';
|
||||||
|
}
|
||||||
|
if (lang.startsWith('language-')) {
|
||||||
|
lang = lang.substr(9);
|
||||||
|
}
|
||||||
|
block.setAttribute('class', 'hljs ' + lang);
|
||||||
|
block.parentNode.setAttribute('data-lang', lang);
|
||||||
|
}
|
||||||
|
|
||||||
|
function addBadge(block) {
|
||||||
|
var enabled = ('true' || 'true').toLowerCase();
|
||||||
|
if (enabled == 'true') {
|
||||||
|
var pre = block.parentElement;
|
||||||
|
pre.classList.add('badge');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function handle(block) {
|
||||||
|
addLangData(block);
|
||||||
|
addBadge(block)
|
||||||
|
hljs.highlightBlock(block);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (var i = 0; i < els.length; i++) {
|
||||||
|
var el = els[i];
|
||||||
|
handle(el);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
/* code language badge */
|
||||||
|
pre.badge::before {
|
||||||
|
content: attr(data-lang);
|
||||||
|
color: #fff;
|
||||||
|
background-color: #ff4e00;
|
||||||
|
padding: 0 .5em;
|
||||||
|
border-radius: 0 2px;
|
||||||
|
text-transform: uppercase;
|
||||||
|
text-align: center;
|
||||||
|
min-width: 32px;
|
||||||
|
display: inline-block;
|
||||||
|
position: absolute;
|
||||||
|
right: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* fix wrong badge display for firefox browser */
|
||||||
|
code > table pre::before {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<header class="site-header " role="banner">
|
||||||
|
|
||||||
|
<div class="wrapper">
|
||||||
|
<div class="site-header-inner">
|
||||||
|
<span class="site-brand"><a class="site-brand-inner" rel="author" href="/">
|
||||||
|
<img class="site-favicon" title="Matyáš Caras" src="" onerror="this.style.display='none'">
|
||||||
|
Matyáš Caras
|
||||||
|
</a>
|
||||||
|
</span><nav class="site-nav">
|
||||||
|
<input type="checkbox" id="nav-trigger" class="nav-trigger">
|
||||||
|
<label for="nav-trigger">
|
||||||
|
<span class="menu-icon">
|
||||||
|
<svg viewbox="0 0 18 15" width="18px" height="15px">
|
||||||
|
<path d="M18,1.484c0,0.82-0.665,1.484-1.484,1.484H1.484C0.665,2.969,0,2.304,0,1.484l0,0C0,0.665,0.665,0,1.484,0 h15.032C17.335,0,18,0.665,18,1.484L18,1.484z M18,7.516C18,8.335,17.335,9,16.516,9H1.484C0.665,9,0,8.335,0,7.516l0,0 c0-0.82,0.665-1.484,1.484-1.484h15.032C17.335,6.031,18,6.696,18,7.516L18,7.516z M18,13.516C18,14.335,17.335,15,16.516,15H1.484 C0.665,15,0,14.335,0,13.516l0,0c0-0.82,0.665-1.483,1.484-1.483h15.032C17.335,12.031,18,12.695,18,13.516L18,13.516z"></path>
|
||||||
|
</svg>
|
||||||
|
</span>
|
||||||
|
</label>
|
||||||
|
|
||||||
|
<div class="trigger">
|
||||||
|
<a class="page-link" href="/about.html">ABOUT</a><a class="page-link" href="/archives.html">ARCHIVES</a><a class="page-link" href="/categories.html">CATEGORIES</a><a class="page-link" href="/">HOME</a><a class="page-link" href="/tags.html">TAGS</a>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</nav>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</header>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
function initHeader() {
|
||||||
|
var lastScrollY = getScrollPos().y;
|
||||||
|
var documentElement = document.documentElement;
|
||||||
|
|
||||||
|
function storeScrollData() {
|
||||||
|
var y = getScrollPos().y;var scrollStatus = "";
|
||||||
|
|
||||||
|
if (y <= 0) {
|
||||||
|
scrollStatus = "top";
|
||||||
|
} else if ((window.innerHeight + y) >= document.body.offsetHeight) {
|
||||||
|
scrollStatus = "bottom";
|
||||||
|
} else {
|
||||||
|
var isScrollDown = (y - lastScrollY > 0) ? true : false;
|
||||||
|
scrollStatus = isScrollDown ? "down" : "up";
|
||||||
|
}
|
||||||
|
|
||||||
|
lastScrollY = y;
|
||||||
|
documentElement.setAttribute("data-scroll-status", scrollStatus);
|
||||||
|
}
|
||||||
|
|
||||||
|
window.addEventListener('scroll', function(e) {
|
||||||
|
storeScrollData();
|
||||||
|
});
|
||||||
|
|
||||||
|
storeScrollData();
|
||||||
|
}
|
||||||
|
document.addEventListener('DOMContentLoaded', initHeader);
|
||||||
|
</script>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<script>
|
||||||
|
function hashLocate(hashValue) {
|
||||||
|
hashValue = hashValue.replace(/^.*#h-/, '');
|
||||||
|
hashValue = decodeURIComponent(hashValue);
|
||||||
|
var element = document.getElementById(hashValue);
|
||||||
|
|
||||||
|
if (!element) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var header = document.querySelector('header.site-header');
|
||||||
|
var headerRect = header.getBoundingClientRect();
|
||||||
|
var headerTop = Math.floor(headerRect.top);
|
||||||
|
var headerHeight = Math.floor(headerRect.height);
|
||||||
|
var scrollPos = getScrollPos();
|
||||||
|
var offsetY = element.offsetTop - (headerTop + headerHeight + 20);
|
||||||
|
|
||||||
|
if (offsetY == scrollPos.y) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (headerTop == 0 && offsetY > scrollPos.y) {
|
||||||
|
offsetY += headerHeight + 2;
|
||||||
|
} else if (headerTop < 0 && offsetY < scrollPos.y) {
|
||||||
|
offsetY -= headerHeight - 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
smoothScrollTo(offsetY);
|
||||||
|
}
|
||||||
|
|
||||||
|
// The first event occurred
|
||||||
|
window.addEventListener('load', function(event) {
|
||||||
|
if (window.location.hash) {
|
||||||
|
hashLocate(window.location.hash);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// The first event occurred
|
||||||
|
window.addEventListener('click', function(event) {
|
||||||
|
if (event.target.tagName.toLowerCase() == 'a') {
|
||||||
|
hashLocate(event.target.getAttribute('href'));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
<div class="theme-toggle">
|
||||||
|
<input type="checkbox" id="theme-switch">
|
||||||
|
<label for="theme-switch">
|
||||||
|
<div class="toggle"></div>
|
||||||
|
<div class="names">
|
||||||
|
<p class="light">Light</p>
|
||||||
|
<p class="dark">Dark</p>
|
||||||
|
</div>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<script>
|
||||||
|
(function() {
|
||||||
|
var sw = document.getElementById('theme-switch');
|
||||||
|
var html = document.getElementsByTagName('html')[0];
|
||||||
|
var nightModeOption = ('auto' || 'auto').toLowerCase();
|
||||||
|
var storage = nightModeOption === 'manual'
|
||||||
|
? localStorage
|
||||||
|
: sessionStorage;
|
||||||
|
var themeData = loadThemeData();
|
||||||
|
|
||||||
|
function saveThemeData(data) {
|
||||||
|
storage.setItem('theme', JSON.stringify(data));
|
||||||
|
}
|
||||||
|
|
||||||
|
function loadThemeData() {
|
||||||
|
var data = storage.getItem('theme');
|
||||||
|
try {
|
||||||
|
data = JSON.parse(data ? data : '');
|
||||||
|
} catch(e) {
|
||||||
|
data = { nightShift: undefined, autoToggleAt: 0 };
|
||||||
|
saveThemeData(data);
|
||||||
|
}
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleThemeToggle(nightShift) {
|
||||||
|
themeData.nightShift = nightShift;
|
||||||
|
saveThemeData(themeData);
|
||||||
|
html.dataset.theme = nightShift ? 'dark' : 'light';
|
||||||
|
setTimeout(function() {
|
||||||
|
sw.checked = nightShift ? true : false;
|
||||||
|
}, 50);
|
||||||
|
}
|
||||||
|
|
||||||
|
function autoThemeToggle() {
|
||||||
|
// Next time point of theme toggle
|
||||||
|
var now = new Date();
|
||||||
|
var toggleAt = new Date();
|
||||||
|
var hours = now.getHours();
|
||||||
|
var nightShift = hours >= 19 || hours <=7;
|
||||||
|
|
||||||
|
if (nightShift) {
|
||||||
|
if (hours > 7) {
|
||||||
|
toggleAt.setDate(toggleAt.getDate() + 1);
|
||||||
|
}
|
||||||
|
toggleAt.setHours(7);
|
||||||
|
} else {
|
||||||
|
toggleAt.setHours(19);
|
||||||
|
}
|
||||||
|
|
||||||
|
toggleAt.setMinutes(0);
|
||||||
|
toggleAt.setSeconds(0);
|
||||||
|
toggleAt.setMilliseconds(0)
|
||||||
|
|
||||||
|
var delay = toggleAt.getTime() - now.getTime();
|
||||||
|
|
||||||
|
// auto toggle theme mode
|
||||||
|
setTimeout(function() {
|
||||||
|
handleThemeToggle(!nightShift);
|
||||||
|
}, delay);
|
||||||
|
|
||||||
|
return {
|
||||||
|
nightShift: nightShift,
|
||||||
|
toggleAt: toggleAt.getTime()
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// Listen the theme toggle event
|
||||||
|
sw.addEventListener('change', function(event) {
|
||||||
|
handleThemeToggle(event.target.checked);
|
||||||
|
});
|
||||||
|
|
||||||
|
if (nightModeOption == 'auto') {
|
||||||
|
var data = autoThemeToggle();
|
||||||
|
|
||||||
|
// Toggle theme by local setting
|
||||||
|
if (data.toggleAt > themeData.autoToggleAt) {
|
||||||
|
themeData.autoToggleAt = data.toggleAt;
|
||||||
|
handleThemeToggle(data.nightShift);
|
||||||
|
} else {
|
||||||
|
handleThemeToggle(themeData.nightShift);
|
||||||
|
}
|
||||||
|
} else if (nightModeOption == 'manual') {
|
||||||
|
handleThemeToggle(themeData.nightShift);
|
||||||
|
} else {
|
||||||
|
var nightShift = themeData.nightShift;
|
||||||
|
if (nightShift === undefined) {
|
||||||
|
nightShift = nightModeOption === 'on';
|
||||||
|
}
|
||||||
|
handleThemeToggle(nightShift);
|
||||||
|
}
|
||||||
|
})();
|
||||||
|
</script>
|
||||||
|
<div id="click-to-top" class="click-to-top">
|
||||||
|
<i class="fa fa-arrow-up"></i>
|
||||||
|
</div>
|
||||||
|
<script>
|
||||||
|
(function () {
|
||||||
|
const clickToTop = document.getElementById('click-to-top');
|
||||||
|
window.addEventListener('scroll', () => {
|
||||||
|
if (window.scrollY > 100) {
|
||||||
|
clickToTop.classList.add('show')
|
||||||
|
}else {
|
||||||
|
clickToTop.classList.remove('show')
|
||||||
|
}
|
||||||
|
});
|
||||||
|
clickToTop.addEventListener('click', () => {
|
||||||
|
window.smoothScrollTo(0);
|
||||||
|
});
|
||||||
|
})();
|
||||||
|
</script>
|
||||||
|
<main class="page-content" aria-label="Content">
|
||||||
|
<div class="wrapper">
|
||||||
|
<div class="framework">
|
||||||
|
<section class="main">
|
||||||
|
|
||||||
|
<div class="post">
|
||||||
|
<section>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<header class="post-header">
|
||||||
|
<h1 class="post-title p-name" itemprop="name headline">Instalujeme Arch Linux ARM na Raspberry Pi 3</h1>
|
||||||
|
<h2 class="post-subtitle">Protože proč ne</h2>
|
||||||
|
|
||||||
|
<p class="post-meta">
|
||||||
|
<time class="dt-published" datetime="2022-10-22T00:00:00+00:00" itemprop="datePublished"><i class="fa fa-calendar"></i> Oct 22, 2022
|
||||||
|
</time>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<span class="post-reading-time left-vsplit"><i class="fa fa-clock-o"></i> About 6 mins</span>
|
||||||
|
</p>
|
||||||
|
<div class="post-tags">
|
||||||
|
<a class="post-tag" href="/tags.html#n%C3%A1vod">#návod</a><a class="post-tag" href="/tags.html#rpi">#rpi</a><a class="post-tag" href="/tags.html#arch">#arch</a>
|
||||||
|
</div></header>
|
||||||
|
<article class="post h-entry" itemscope itemtype="http://schema.org/BlogPosting">
|
||||||
|
|
||||||
|
<div class="post-content e-content" itemprop="articleBody">
|
||||||
|
|
||||||
|
<p><img src="https://archlinuxarm.org/public/images/alarm.png" alt="Arch Linux ARM logo"></p>
|
||||||
|
|
||||||
|
<p>Raspbian OS už je ohraný. Pojďme si nainstalovat <a href="https://archlinuxarm.org/platforms/armv8/broadcom/raspberry-pi-3">ARM verzi Arch Linuxu</a> na Raspberry Pi 3. Proces je relativně prostý.</p>
|
||||||
|
|
||||||
|
<h1 id="připravujeme-sd-kartu">Připravujeme SD kartu</h1>
|
||||||
|
<p>Nejdřív je nutné SD kartu naformátovat a rozdělit oddíly. Můžete to udělat svým oblíbeným způsobem, já použiji GUI nástroj GParted.</p>
|
||||||
|
|
||||||
|
<p>Odstraníme všechny oddíly skrz kontextové menu pravého kliknutí a potvrzení fajfkou.</p>
|
||||||
|
|
||||||
|
<p><img src="/assets/images/rpi-arch/01.png" alt="Odstraněné oddíly v GParted"></p>
|
||||||
|
|
||||||
|
<p>Následně vytvoříme jeden FAT32 oddíl, který bude sloužit jako bootovací. Bude stačit 128 MiB.</p>
|
||||||
|
|
||||||
|
<p><img src="/assets/images/rpi-arch/02.png" alt="Vytváření FAT32 oddílu v GParted"></p>
|
||||||
|
|
||||||
|
<p>Druhý oddíl bude náš systémový, který bude ext4.</p>
|
||||||
|
|
||||||
|
<p><img src="/assets/images/rpi-arch/03.png" alt="Vytváření ext4 oddílu v GParted"></p>
|
||||||
|
|
||||||
|
<p>Jakmile fajfkou potvrdíme a necháme oddíly vytvořit, můžete je ještě zformátovat, nicméně je nejdůležitější nastavit <code class="language-plaintext highlighter-rouge">boot</code> příznak na našem boot oddílu skrz kontextové menu.</p>
|
||||||
|
|
||||||
|
<p><img src="/assets/images/rpi-arch/04.png" alt="Výběr příznaků v GParted"></p>
|
||||||
|
|
||||||
|
<p>Tak je všechno hotovo v GParted.</p>
|
||||||
|
|
||||||
|
<h1 id="přesouváme-systém">Přesouváme systém</h1>
|
||||||
|
<p>Dále připojíme naše oddíly podle jejich identifikátoru a čísla připojíme.</p>
|
||||||
|
|
||||||
|
<p>Nejdřív si vytvoříme složky, <code class="language-plaintext highlighter-rouge">sudo mkdir -p /mnt/archpi/{root,boot}</code> nám vytvoří složky <code class="language-plaintext highlighter-rouge">root</code> a <code class="language-plaintext highlighter-rouge">boot</code> pro naše oddíly.</p>
|
||||||
|
|
||||||
|
<p>Dále příkazem <code class="language-plaintext highlighter-rouge">sudo mount /dev/sdc1 /mnt/archpi/root</code> připojíme náš FAT32 bootovácí oddíl (<strong>Označení <code class="language-plaintext highlighter-rouge">sdc1</code> se u vás může lišit, podívejte se do GPartedu nebo skrz příkaz <code class="language-plaintext highlighter-rouge">lsblk</code> na označení jednotlivých oddílů</strong>) a příkazem <code class="language-plaintext highlighter-rouge">sudo mount /dev/sdc2 /mnt/archpi/boot</code> připojíme systémový oddíl.</p>
|
||||||
|
|
||||||
|
<p>Dle oficiální <a href="https://archlinuxarm.org/platforms/armv8/broadcom/raspberry-pi-3">dokumentace</a> se další proces má dělat skrz root uživatele, takže se přepneme příkazem <code class="language-plaintext highlighter-rouge">sudo su</code>.</p>
|
||||||
|
|
||||||
|
<p>Příkazem <code class="language-plaintext highlighter-rouge">wget http://os.archlinuxarm.org/os/ArchLinuxARM-rpi-armv7-latest.tar.gz</code> stáhneme archiv a příkazem <code class="language-plaintext highlighter-rouge">tar -xf ArchLinuxARM-rpi-armv7-latest.tar.gz -C /mnt/archpi/root</code> ho rozbalíme.</p>
|
||||||
|
|
||||||
|
<p>Pak musíme přesunout bootovací soubory do bootovacího oddílu: <code class="language-plaintext highlighter-rouge">mv /mnt/archpi/root/boot/* boot</code> a tím jsme hotovi, stačí oddíly odpojit příkazem <code class="language-plaintext highlighter-rouge">umount /mnt/archpi/root</code> a <code class="language-plaintext highlighter-rouge">umount /mnt/archpi/boot</code>. Jakmile se příkazy dokončí, můžete SD kartu vložit do RPi a zapnout.</p>
|
||||||
|
|
||||||
|
<p>Výchozí jméno a zároveň heslo uživatele je <code class="language-plaintext highlighter-rouge">alarm</code> a roota <code class="language-plaintext highlighter-rouge">root</code>. Než bude systém nastavený, doporučuji použít <code class="language-plaintext highlighter-rouge">root</code> účet.</p>
|
||||||
|
|
||||||
|
<h1 id="připojení-k-wi-fi-síti">Připojení k Wi-Fi síti</h1>
|
||||||
|
<p><em>Pokud používáte kabelové připojení, tak můžete přeskočit</em>
|
||||||
|
Nyní se připojíme skrz terminál k Wi-Fi síti. Předpokládám, že název (SSID) sítě a heslo znáte a že zabezpečení je WPA2 Personal. Jinak si můžete prohlédnout <a href="https://wiki.archlinux.org/title/Network_configuration/Wireless">Arch Wiki</a> pro více návodů.</p>
|
||||||
|
|
||||||
|
<p>Příkazem <code class="language-plaintext highlighter-rouge">iw dev</code> zjistíte název vašeho interfacu (např. já mám <code class="language-plaintext highlighter-rouge">wlan0</code>). Zapneme ho pomocí <code class="language-plaintext highlighter-rouge">ip link wlan0 up</code> (místo <code class="language-plaintext highlighter-rouge">wlan0</code> tedy použijte váš název interfacu).</p>
|
||||||
|
|
||||||
|
<p>Dále se tedy připojíme k nějaké Wi-Fi síti. Nejdřív musíme vytvořit konfigurační soubor pro <code class="language-plaintext highlighter-rouge">wpa_supplicant</code>, který slouží jako <a href="https://cs.wikipedia.org/wiki/Suplikant">suplikant</a> s podporou WPA, WPA2 a WPA3.</p>
|
||||||
|
|
||||||
|
<p>Pomocí příkazu <code class="language-plaintext highlighter-rouge">nano /etc/wpa_supplicant/wpa_supplicant.conf</code> vstoupíme do editace konfiguračního souboru. Do něj vložíme následující dva řádky:</p>
|
||||||
|
|
||||||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>ctrl_interface=/run/wpa_supplicant
|
||||||
|
update_config=1
|
||||||
|
</code></pre></div></div>
|
||||||
|
|
||||||
|
<p>Klávesovou zkratkou <code class="language-plaintext highlighter-rouge">Ctrl+X</code>, zadáním <code class="language-plaintext highlighter-rouge">y</code> a potvrzením enterem uložíme soubor a opustíme editaci. wpa_supplicant teď můžeme spustit příkazem <code class="language-plaintext highlighter-rouge">wpa_supplicant -B -i wlan0 -c /etc/wpa_supplicant/wpa_supplicant.conf</code>.</p>
|
||||||
|
|
||||||
|
<p>S běžícím wpa_supplicant můžeme použít příkaz <code class="language-plaintext highlighter-rouge">wpa_cli</code>, kde můžeme konfigurovat síť.</p>
|
||||||
|
|
||||||
|
<p>Sítě zde můžete hledat příkazem <a href="https://wiki.archlinux.org/title/Wpa_supplicant#Connecting_with_wpa_cli"><code class="language-plaintext highlighter-rouge">scan</code></a>, následováný <code class="language-plaintext highlighter-rouge">scan_results</code>.</p>
|
||||||
|
|
||||||
|
<p>Pro přidání sítě použijeme příkaz <code class="language-plaintext highlighter-rouge">add_network</code>. Terminál vrátí <code class="language-plaintext highlighter-rouge">0</code>, což je ID sítě, které můžeme konfigurovat. Příkazem <code class="language-plaintext highlighter-rouge">set_network 0 ssid "MYSSID"</code> nastavíme SSID (název) sítě na <code class="language-plaintext highlighter-rouge">MYSSID</code>. Příkazem <code class="language-plaintext highlighter-rouge">set_network 0 psk "passphrase"</code> nastavíme heslo na <code class="language-plaintext highlighter-rouge">passphrase</code>. Jakmile je nastaveno, můžeme povolit síť pomocí <code class="language-plaintext highlighter-rouge">enable_network 0</code>. Konfiguraci uložíme příkazem <code class="language-plaintext highlighter-rouge">save_config</code> a opustíme pomocí <code class="language-plaintext highlighter-rouge">quit</code>.</p>
|
||||||
|
|
||||||
|
<p>Jelikož ale právě teď nemáme IP adresu, musíme nastavit službu DHCP (pokud ji samozřejmě váš router má). Stačí zapnout službu <code class="language-plaintext highlighter-rouge">dhcpcd</code> pomocí příkazu <code class="language-plaintext highlighter-rouge">systemctl enable dhcpcd</code>. Abychom při každém zapnutí nemuseli síť manuálně zapínat, můžeme do <code class="language-plaintext highlighter-rouge">dhcpcd</code> přidat <a href="https://wiki.archlinux.org/title/Dhcpcd#10-wpa_supplicant">hook</a>, který ji automaticky zapne, stačí použít <code class="language-plaintext highlighter-rouge">ln -s /usr/share/dhcpcd/hooks/10-wpa_supplicant /usr/lib/dhcpcd/dhcpcd-hooks/</code>.</p>
|
||||||
|
|
||||||
|
<p>V tomto stádiu doporučuji restartovat příkazem <code class="language-plaintext highlighter-rouge">reboot</code>.</p>
|
||||||
|
|
||||||
|
<h1 id="nastavujeme-správce-balíků">Nastavujeme správce balíků</h1>
|
||||||
|
<p>Aktuálně bychom měli mít funkční síť, nicméně je potřeba pár dalších příkazů pokud chceme používat <code class="language-plaintext highlighter-rouge">pacman</code> správce balíků.</p>
|
||||||
|
|
||||||
|
<p>Nejdřív musíme vytvořit klíčenku příkazem <code class="language-plaintext highlighter-rouge">pacman-key --init</code>, poté přidáme klíče Arch ARM repozitářů příkazem <code class="language-plaintext highlighter-rouge">pacman-key --populate archlinuxarm</code>. Teď můžete příkazem <code class="language-plaintext highlighter-rouge">pacman -Sy</code> repozitáře synchronizovat.</p>
|
||||||
|
|
||||||
|
<p>Jako první balík bychom měli stáhnout <a href="https://wiki.archlinux.org/title/sudo"><code class="language-plaintext highlighter-rouge">sudo</code></a>, abychom nemuseli používat <code class="language-plaintext highlighter-rouge">root</code> uživatele pro všechno nastavování. Nainstalujeme ho příkazem <code class="language-plaintext highlighter-rouge">pacman -S sudo</code>. Dále příkazem <code class="language-plaintext highlighter-rouge">nano /etc/sudoers</code> upravíme konfiguraci. Najdeme následující řádky (<code class="language-plaintext highlighter-rouge">Ctrl+W</code> pro hledání):</p>
|
||||||
|
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>## Uncomment to allow members of group wheel to execute any command
|
||||||
|
#%wheel ALL=(ALL:ALL) ALL
|
||||||
|
</code></pre></div></div>
|
||||||
|
<p>a odstraníme mřížku před <code class="language-plaintext highlighter-rouge">%</code> pro odstranění komentáře. Tím umožníme uživatelům v uživatelské skupině <code class="language-plaintext highlighter-rouge">wheel</code> používat příkaz <code class="language-plaintext highlighter-rouge">sudo</code>.</p>
|
||||||
|
|
||||||
|
<p>Nyní přidáme uživatele <code class="language-plaintext highlighter-rouge">alarm</code> do skupiny <code class="language-plaintext highlighter-rouge">wheel</code> příkazem <code class="language-plaintext highlighter-rouge">gpasswd -a alarm wheel</code>. A teď už můžeme používat uživatele <code class="language-plaintext highlighter-rouge">alarm</code> pro různé administrativní operace místo roota.</p>
|
||||||
|
|
||||||
|
<h1 id="nastavení-ssh-přístupu">Nastavení SSH přístupu</h1>
|
||||||
|
<p>Možná vás nebaví zapojovat RPi do monitoru nebo u něj klapat věci do klávesnice v terminálu nebo jen chcete vzdálený přístup. SSH lze povolit skrz OpenSSH, které je na Archu předinstalované. Stačí povolit službu pomocí <code class="language-plaintext highlighter-rouge">systemctl enable sshd</code>. Pro nějakou pokročilou konfiguraci si prohlédněte <a href="https://wiki.archlinux.org/title/OpenSSH#Server_usage">Arch Wiki</a>.</p>
|
||||||
|
|
||||||
|
<p>Nyní se stačí připojit skrz nějaký SSH klient na vaše zařízení (pokud neznáte IP, podívejte se skrz příkaz <code class="language-plaintext highlighter-rouge">ip a</code>), třeba skrz <code class="language-plaintext highlighter-rouge">ssh alarm@vase.ip.adresa</code>.</p>
|
||||||
|
|
||||||
|
<h1 id="https-problémy">HTTPS problémy</h1>
|
||||||
|
<p>Pokud máte problémy s SSL nebo komunikací se zabezpečenými servery, zkuste nainstalovat balík <code class="language-plaintext highlighter-rouge">ca-certificates</code> a nastavit systémový čas skrz <code class="language-plaintext highlighter-rouge">timedatectl set-time "2022-10-29 15:00:00</code> (samozřejmě vaše datum).</p>
|
||||||
|
|
||||||
|
<h1 id="závěr">Závěr</h1>
|
||||||
|
|
||||||
|
<p><img src="/assets/images/rpi-arch/05.png" alt="Arch neofetch"></p>
|
||||||
|
|
||||||
|
<p>Instalace je opravdu prostý a snadný proces (i když jsem ho sám dělal asi 5x než mi to nabootovalo), takže určitě zkoušejte a zkoušejte.</p>
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</article>
|
||||||
|
<div class="post-nav">
|
||||||
|
<a class="previous" href="/bezpe%C4%8D%C3%AD/2022/07/19/nordvpn.html" title="NordVPN - Jste opravdu v takovém nebezpečí?">NordVPN - Jste opravdu v takovém...</a><span></span>
|
||||||
|
</div>
|
||||||
|
<div class="post-related">
|
||||||
|
<div>Related Articles</div>
|
||||||
|
<ul>
|
||||||
|
<li><a class="post-link" href="/programov%C3%A1n%C3%AD/2022/05/22/automatizace.html" title="">Automatizace, automatizace, automatizace</a></li>
|
||||||
|
<li><a class="post-link" href="/tutori%C3%A1l/2022/10/22/rpi-arch.html" title="">Instalujeme Arch Linux ARM na Raspberry Pi 3</a></li>
|
||||||
|
<li><a class="post-link" href="/bezpe%C4%8D%C3%AD/2022/07/19/nordvpn.html" title="">NordVPN - Jste opravdu v takovém nebezpečí?</a></li>
|
||||||
|
<li><a class="post-link" href="/vychyt%C3%A1vky/2022/05/31/codespaces.html" title="">GitHub Codespaces aneb VS Code na VPS</a></li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
<div class="post-comments"> <div id="gitment_thread" class="giscus"></div>
|
||||||
|
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/theme-next/theme-next-gitment@1/default.css">
|
||||||
|
<script src="https://cdn.jsdelivr.net/gh/theme-next/theme-next-gitment@1/gitment.browser.js"></script>
|
||||||
|
<script src="https://giscus.app/client.js" data-repo="hernikplays/blog" data-repo-id="R_kgDOHr2B6w" data-category="General" data-category-id="DIC_kwDOHr2B684CSIhA" data-mapping="pathname" data-strict="0" data-reactions-enabled="1" data-emit-metadata="0" data-input-position="top" data-theme="transparent_dark" data-lang="en" data-loading="lazy" crossorigin="anonymous" async>
|
||||||
|
</script>
|
||||||
|
</div></section>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
</section>
|
||||||
|
<section class="sidebar" style="margin-left: 15px;">
|
||||||
|
<!-- Get sidebar items --></section>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</main><footer class="site-footer h-card">
|
||||||
|
<data class="u-url" href="/"></data>
|
||||||
|
|
||||||
|
<div class="wrapper">
|
||||||
|
<div class="site-footer-inner">
|
||||||
|
<div>Copyright © 2021-2022 hernikplays</div>
|
||||||
|
<div>Powered by <a title="Jekyll is a simple, blog-aware, static site
|
||||||
|
generator." href="https://jekyllrb.com/">Jekyll</a> & <a title="Yat, yet
|
||||||
|
another theme." href="https://github.com/jeffreytse/jekyll-theme-yat">Yat Theme</a>.</div>
|
||||||
|
<div><a rel="me" href="https://social.linux.pizza/@hernik">Mastodon</a></div>
|
||||||
|
<div class="footer-col rss-subscribe">Subscribe <a href="/feed.xml">via RSS</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</footer>
|
||||||
|
</body>
|
||||||
|
</html>
|
760
vychytávky/2022/05/31/codespaces.html
Normal file
|
@ -0,0 +1,760 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
|
<meta name="google-translate-customization" content="108d9124921d80c3-80e20d618ff053c8-g4f02ec6f3dba68b7-c">
|
||||||
|
<!-- Begin Jekyll SEO tag v2.8.0 -->
|
||||||
|
<title>GitHub Codespaces aneb VS Code na VPS | Matyáš Caras</title>
|
||||||
|
<meta name="generator" content="Jekyll v4.3.1">
|
||||||
|
<meta property="og:title" content="GitHub Codespaces aneb VS Code na VPS">
|
||||||
|
<meta name="author" content="hernikplays">
|
||||||
|
<meta property="og:locale" content="en_US">
|
||||||
|
<meta name="description" content="Nedávno mi přišel e-mail, že jsem byl přidán do beta testování funkce Codespaces na GitHubu. Stručně, Codespaces má být systém ve kterém si vytvoříte vlastní prostředí pro váš repozitář, do kterého si nainstalujete všechny potřebné knihovny, SDK a balíky. Server, na kterém to všechno běží, si platíte u GitHubu a můžete na něj kdekoliv a kdykoliv přejít přes web do webové, narozdíl od výchozího webového VS Code plně vybavené, verzi VS Code nebo nainstalovaný VS Code a upravovat nebo testovat kód.">
|
||||||
|
<meta property="og:description" content="Nedávno mi přišel e-mail, že jsem byl přidán do beta testování funkce Codespaces na GitHubu. Stručně, Codespaces má být systém ve kterém si vytvoříte vlastní prostředí pro váš repozitář, do kterého si nainstalujete všechny potřebné knihovny, SDK a balíky. Server, na kterém to všechno běží, si platíte u GitHubu a můžete na něj kdekoliv a kdykoliv přejít přes web do webové, narozdíl od výchozího webového VS Code plně vybavené, verzi VS Code nebo nainstalovaný VS Code a upravovat nebo testovat kód.">
|
||||||
|
<link rel="canonical" href="https://caras.cafe/vychyt%C3%A1vky/2022/05/31/codespaces.html">
|
||||||
|
<meta property="og:url" content="https://caras.cafe/vychyt%C3%A1vky/2022/05/31/codespaces.html">
|
||||||
|
<meta property="og:site_name" content="Matyáš Caras">
|
||||||
|
<meta property="og:type" content="article">
|
||||||
|
<meta property="article:published_time" content="2022-05-31T00:00:00+00:00">
|
||||||
|
<meta name="twitter:card" content="summary">
|
||||||
|
<meta property="twitter:title" content="GitHub Codespaces aneb VS Code na VPS">
|
||||||
|
<script type="application/ld+json">
|
||||||
|
{"@context":"https://schema.org","@type":"BlogPosting","author":{"@type":"Person","name":"hernikplays"},"dateModified":"2022-05-31T00:00:00+00:00","datePublished":"2022-05-31T00:00:00+00:00","description":"Nedávno mi přišel e-mail, že jsem byl přidán do beta testování funkce Codespaces na GitHubu. Stručně, Codespaces má být systém ve kterém si vytvoříte vlastní prostředí pro váš repozitář, do kterého si nainstalujete všechny potřebné knihovny, SDK a balíky. Server, na kterém to všechno běží, si platíte u GitHubu a můžete na něj kdekoliv a kdykoliv přejít přes web do webové, narozdíl od výchozího webového VS Code plně vybavené, verzi VS Code nebo nainstalovaný VS Code a upravovat nebo testovat kód.","headline":"GitHub Codespaces aneb VS Code na VPS","mainEntityOfPage":{"@type":"WebPage","@id":"https://caras.cafe/vychyt%C3%A1vky/2022/05/31/codespaces.html"},"url":"https://caras.cafe/vychyt%C3%A1vky/2022/05/31/codespaces.html"}</script>
|
||||||
|
<!-- End Jekyll SEO tag -->
|
||||||
|
<link rel="shortcut icon" href="">
|
||||||
|
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
|
||||||
|
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/typeface-noto-sans@0.0.72/index.min.css">
|
||||||
|
<link rel="stylesheet" href="/assets/css/main.css">
|
||||||
|
<script src="/assets/js/main.js"></script><link type="application/atom+xml" rel="alternate" href="https://caras.cafe/feed.xml" title="Matyáš Caras">
|
||||||
|
<link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/highlight.js/10.1.1/styles/default.min.css">
|
||||||
|
<script src="//cdnjs.cloudflare.com/ajax/libs/highlight.js/10.1.1/highlight.min.js"></script>
|
||||||
|
<!-- and it's easy to individually load additional languages -->
|
||||||
|
<script charset="UTF-8" src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.1.1/languages/go.min.js"></script>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<script>
|
||||||
|
// Init highlight js
|
||||||
|
document.addEventListener('DOMContentLoaded', function(event) {
|
||||||
|
var els = document.querySelectorAll('pre code')
|
||||||
|
|
||||||
|
function addLangData(block) {
|
||||||
|
var outer = block.parentElement.parentElement.parentElement;
|
||||||
|
var lang = block.getAttribute('data-lang');
|
||||||
|
for (var i = 0; i < outer.classList.length; i++) {
|
||||||
|
var cls = outer.classList[i];
|
||||||
|
if (cls.startsWith('language-')) {
|
||||||
|
lang = cls;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!lang) {
|
||||||
|
cls = block.getAttribute('class');
|
||||||
|
lang = cls ? cls.replace('hljs ', '') : '';
|
||||||
|
}
|
||||||
|
if (lang.startsWith('language-')) {
|
||||||
|
lang = lang.substr(9);
|
||||||
|
}
|
||||||
|
block.setAttribute('class', 'hljs ' + lang);
|
||||||
|
block.parentNode.setAttribute('data-lang', lang);
|
||||||
|
}
|
||||||
|
|
||||||
|
function addBadge(block) {
|
||||||
|
var enabled = ('true' || 'true').toLowerCase();
|
||||||
|
if (enabled == 'true') {
|
||||||
|
var pre = block.parentElement;
|
||||||
|
pre.classList.add('badge');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function handle(block) {
|
||||||
|
addLangData(block);
|
||||||
|
addBadge(block)
|
||||||
|
hljs.highlightBlock(block);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (var i = 0; i < els.length; i++) {
|
||||||
|
var el = els[i];
|
||||||
|
handle(el);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
/* code language badge */
|
||||||
|
pre.badge::before {
|
||||||
|
content: attr(data-lang);
|
||||||
|
color: #fff;
|
||||||
|
background-color: #ff4e00;
|
||||||
|
padding: 0 .5em;
|
||||||
|
border-radius: 0 2px;
|
||||||
|
text-transform: uppercase;
|
||||||
|
text-align: center;
|
||||||
|
min-width: 32px;
|
||||||
|
display: inline-block;
|
||||||
|
position: absolute;
|
||||||
|
right: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* fix wrong badge display for firefox browser */
|
||||||
|
code > table pre::before {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<header class="site-header " role="banner">
|
||||||
|
|
||||||
|
<div class="wrapper">
|
||||||
|
<div class="site-header-inner">
|
||||||
|
<span class="site-brand"><a class="site-brand-inner" rel="author" href="/">
|
||||||
|
<img class="site-favicon" title="Matyáš Caras" src="" onerror="this.style.display='none'">
|
||||||
|
Matyáš Caras
|
||||||
|
</a>
|
||||||
|
</span><nav class="site-nav">
|
||||||
|
<input type="checkbox" id="nav-trigger" class="nav-trigger">
|
||||||
|
<label for="nav-trigger">
|
||||||
|
<span class="menu-icon">
|
||||||
|
<svg viewbox="0 0 18 15" width="18px" height="15px">
|
||||||
|
<path d="M18,1.484c0,0.82-0.665,1.484-1.484,1.484H1.484C0.665,2.969,0,2.304,0,1.484l0,0C0,0.665,0.665,0,1.484,0 h15.032C17.335,0,18,0.665,18,1.484L18,1.484z M18,7.516C18,8.335,17.335,9,16.516,9H1.484C0.665,9,0,8.335,0,7.516l0,0 c0-0.82,0.665-1.484,1.484-1.484h15.032C17.335,6.031,18,6.696,18,7.516L18,7.516z M18,13.516C18,14.335,17.335,15,16.516,15H1.484 C0.665,15,0,14.335,0,13.516l0,0c0-0.82,0.665-1.483,1.484-1.483h15.032C17.335,12.031,18,12.695,18,13.516L18,13.516z"></path>
|
||||||
|
</svg>
|
||||||
|
</span>
|
||||||
|
</label>
|
||||||
|
|
||||||
|
<div class="trigger">
|
||||||
|
<a class="page-link" href="/about.html">ABOUT</a><a class="page-link" href="/archives.html">ARCHIVES</a><a class="page-link" href="/categories.html">CATEGORIES</a><a class="page-link" href="/">HOME</a><a class="page-link" href="/tags.html">TAGS</a>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</nav>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</header>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
function initHeader() {
|
||||||
|
var lastScrollY = getScrollPos().y;
|
||||||
|
var documentElement = document.documentElement;
|
||||||
|
|
||||||
|
function storeScrollData() {
|
||||||
|
var y = getScrollPos().y;var scrollStatus = "";
|
||||||
|
|
||||||
|
if (y <= 0) {
|
||||||
|
scrollStatus = "top";
|
||||||
|
} else if ((window.innerHeight + y) >= document.body.offsetHeight) {
|
||||||
|
scrollStatus = "bottom";
|
||||||
|
} else {
|
||||||
|
var isScrollDown = (y - lastScrollY > 0) ? true : false;
|
||||||
|
scrollStatus = isScrollDown ? "down" : "up";
|
||||||
|
}
|
||||||
|
|
||||||
|
lastScrollY = y;
|
||||||
|
documentElement.setAttribute("data-scroll-status", scrollStatus);
|
||||||
|
}
|
||||||
|
|
||||||
|
window.addEventListener('scroll', function(e) {
|
||||||
|
storeScrollData();
|
||||||
|
});
|
||||||
|
|
||||||
|
storeScrollData();
|
||||||
|
}
|
||||||
|
document.addEventListener('DOMContentLoaded', initHeader);
|
||||||
|
</script>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<script>
|
||||||
|
function hashLocate(hashValue) {
|
||||||
|
hashValue = hashValue.replace(/^.*#h-/, '');
|
||||||
|
hashValue = decodeURIComponent(hashValue);
|
||||||
|
var element = document.getElementById(hashValue);
|
||||||
|
|
||||||
|
if (!element) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var header = document.querySelector('header.site-header');
|
||||||
|
var headerRect = header.getBoundingClientRect();
|
||||||
|
var headerTop = Math.floor(headerRect.top);
|
||||||
|
var headerHeight = Math.floor(headerRect.height);
|
||||||
|
var scrollPos = getScrollPos();
|
||||||
|
var offsetY = element.offsetTop - (headerTop + headerHeight + 20);
|
||||||
|
|
||||||
|
if (offsetY == scrollPos.y) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (headerTop == 0 && offsetY > scrollPos.y) {
|
||||||
|
offsetY += headerHeight + 2;
|
||||||
|
} else if (headerTop < 0 && offsetY < scrollPos.y) {
|
||||||
|
offsetY -= headerHeight - 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
smoothScrollTo(offsetY);
|
||||||
|
}
|
||||||
|
|
||||||
|
// The first event occurred
|
||||||
|
window.addEventListener('load', function(event) {
|
||||||
|
if (window.location.hash) {
|
||||||
|
hashLocate(window.location.hash);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// The first event occurred
|
||||||
|
window.addEventListener('click', function(event) {
|
||||||
|
if (event.target.tagName.toLowerCase() == 'a') {
|
||||||
|
hashLocate(event.target.getAttribute('href'));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
<div class="theme-toggle">
|
||||||
|
<input type="checkbox" id="theme-switch">
|
||||||
|
<label for="theme-switch">
|
||||||
|
<div class="toggle"></div>
|
||||||
|
<div class="names">
|
||||||
|
<p class="light">Light</p>
|
||||||
|
<p class="dark">Dark</p>
|
||||||
|
</div>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<script>
|
||||||
|
(function() {
|
||||||
|
var sw = document.getElementById('theme-switch');
|
||||||
|
var html = document.getElementsByTagName('html')[0];
|
||||||
|
var nightModeOption = ('auto' || 'auto').toLowerCase();
|
||||||
|
var storage = nightModeOption === 'manual'
|
||||||
|
? localStorage
|
||||||
|
: sessionStorage;
|
||||||
|
var themeData = loadThemeData();
|
||||||
|
|
||||||
|
function saveThemeData(data) {
|
||||||
|
storage.setItem('theme', JSON.stringify(data));
|
||||||
|
}
|
||||||
|
|
||||||
|
function loadThemeData() {
|
||||||
|
var data = storage.getItem('theme');
|
||||||
|
try {
|
||||||
|
data = JSON.parse(data ? data : '');
|
||||||
|
} catch(e) {
|
||||||
|
data = { nightShift: undefined, autoToggleAt: 0 };
|
||||||
|
saveThemeData(data);
|
||||||
|
}
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleThemeToggle(nightShift) {
|
||||||
|
themeData.nightShift = nightShift;
|
||||||
|
saveThemeData(themeData);
|
||||||
|
html.dataset.theme = nightShift ? 'dark' : 'light';
|
||||||
|
setTimeout(function() {
|
||||||
|
sw.checked = nightShift ? true : false;
|
||||||
|
}, 50);
|
||||||
|
}
|
||||||
|
|
||||||
|
function autoThemeToggle() {
|
||||||
|
// Next time point of theme toggle
|
||||||
|
var now = new Date();
|
||||||
|
var toggleAt = new Date();
|
||||||
|
var hours = now.getHours();
|
||||||
|
var nightShift = hours >= 19 || hours <=7;
|
||||||
|
|
||||||
|
if (nightShift) {
|
||||||
|
if (hours > 7) {
|
||||||
|
toggleAt.setDate(toggleAt.getDate() + 1);
|
||||||
|
}
|
||||||
|
toggleAt.setHours(7);
|
||||||
|
} else {
|
||||||
|
toggleAt.setHours(19);
|
||||||
|
}
|
||||||
|
|
||||||
|
toggleAt.setMinutes(0);
|
||||||
|
toggleAt.setSeconds(0);
|
||||||
|
toggleAt.setMilliseconds(0)
|
||||||
|
|
||||||
|
var delay = toggleAt.getTime() - now.getTime();
|
||||||
|
|
||||||
|
// auto toggle theme mode
|
||||||
|
setTimeout(function() {
|
||||||
|
handleThemeToggle(!nightShift);
|
||||||
|
}, delay);
|
||||||
|
|
||||||
|
return {
|
||||||
|
nightShift: nightShift,
|
||||||
|
toggleAt: toggleAt.getTime()
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// Listen the theme toggle event
|
||||||
|
sw.addEventListener('change', function(event) {
|
||||||
|
handleThemeToggle(event.target.checked);
|
||||||
|
});
|
||||||
|
|
||||||
|
if (nightModeOption == 'auto') {
|
||||||
|
var data = autoThemeToggle();
|
||||||
|
|
||||||
|
// Toggle theme by local setting
|
||||||
|
if (data.toggleAt > themeData.autoToggleAt) {
|
||||||
|
themeData.autoToggleAt = data.toggleAt;
|
||||||
|
handleThemeToggle(data.nightShift);
|
||||||
|
} else {
|
||||||
|
handleThemeToggle(themeData.nightShift);
|
||||||
|
}
|
||||||
|
} else if (nightModeOption == 'manual') {
|
||||||
|
handleThemeToggle(themeData.nightShift);
|
||||||
|
} else {
|
||||||
|
var nightShift = themeData.nightShift;
|
||||||
|
if (nightShift === undefined) {
|
||||||
|
nightShift = nightModeOption === 'on';
|
||||||
|
}
|
||||||
|
handleThemeToggle(nightShift);
|
||||||
|
}
|
||||||
|
})();
|
||||||
|
</script>
|
||||||
|
<div id="click-to-top" class="click-to-top">
|
||||||
|
<i class="fa fa-arrow-up"></i>
|
||||||
|
</div>
|
||||||
|
<script>
|
||||||
|
(function () {
|
||||||
|
const clickToTop = document.getElementById('click-to-top');
|
||||||
|
window.addEventListener('scroll', () => {
|
||||||
|
if (window.scrollY > 100) {
|
||||||
|
clickToTop.classList.add('show')
|
||||||
|
}else {
|
||||||
|
clickToTop.classList.remove('show')
|
||||||
|
}
|
||||||
|
});
|
||||||
|
clickToTop.addEventListener('click', () => {
|
||||||
|
window.smoothScrollTo(0);
|
||||||
|
});
|
||||||
|
})();
|
||||||
|
</script>
|
||||||
|
<main class="page-content" aria-label="Content">
|
||||||
|
<div class="wrapper">
|
||||||
|
<div class="framework">
|
||||||
|
<section class="main">
|
||||||
|
|
||||||
|
<div class="post">
|
||||||
|
<section>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<header class="post-header">
|
||||||
|
<h1 class="post-title p-name" itemprop="name headline">GitHub Codespaces aneb VS Code na VPS</h1>
|
||||||
|
<h2 class="post-subtitle">Dopřejte si trochu luxusu</h2>
|
||||||
|
|
||||||
|
<p class="post-meta">
|
||||||
|
<time class="dt-published" datetime="2022-05-31T00:00:00+00:00" itemprop="datePublished"><i class="fa fa-calendar"></i> May 31, 2022
|
||||||
|
</time>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<span class="post-reading-time left-vsplit"><i class="fa fa-clock-o"></i> About 2 mins</span>
|
||||||
|
</p>
|
||||||
|
<div class="post-tags">
|
||||||
|
<a class="post-tag" href="/tags.html#github">#github</a><a class="post-tag" href="/tags.html#vps">#vps</a>
|
||||||
|
</div></header>
|
||||||
|
<article class="post h-entry" itemscope itemtype="http://schema.org/BlogPosting">
|
||||||
|
|
||||||
|
<div class="post-content e-content" itemprop="articleBody">
|
||||||
|
|
||||||
|
<p>Nedávno mi přišel e-mail, že jsem byl přidán do beta testování funkce Codespaces na GitHubu. Stručně, Codespaces má být systém ve kterém si vytvoříte vlastní prostředí pro váš repozitář, do kterého si nainstalujete všechny potřebné knihovny, SDK a balíky. Server, na kterém to všechno běží, si platíte u GitHubu a můžete na něj kdekoliv a kdykoliv přejít přes web do webové, narozdíl od výchozího webového VS Code plně vybavené, verzi VS Code nebo nainstalovaný VS Code a upravovat nebo testovat kód.</p>
|
||||||
|
|
||||||
|
<p>Hodí se pro lidi, kteří nechtějí tahat např. do školy nebo do práce, kde nesmí instalovat externí aplikace, svůj vlastní notebook.
|
||||||
|
Parametry</p>
|
||||||
|
|
||||||
|
<p>V betě je možné testovat pouze výchozí možnost 4 jádra + 8GB RAM + 32GB úložiště, což definitivně stačí pro osobní a malé projekty. Do konce bety neplatíte nic, ale 4 jádra vyjdou na $0.36 (asi 8,3 kč) za hodinu, tj za hodinu aktivního používání. Codespace se vám automaticky vypne, pokud není po stanovenou dobu nepoužíván, takže můžete předejít placení katastrofických částek.
|
||||||
|
<img src="/assets/images/codespaces/1.jpg" alt="Ceny Codespaces"></p>
|
||||||
|
|
||||||
|
<p>Je to určitě výhodnější, než si platit např. hotové VPS, pokud ho tedy nepoužíváte i na něco smysluplnějšího.
|
||||||
|
Moje zkušenost</p>
|
||||||
|
|
||||||
|
<p>Samozřejmě jsem nemohl odolat a na OpenCanteen jsem si jeden nechal vytvořit, aniž bych věděl do čeho se vrhám.</p>
|
||||||
|
|
||||||
|
<p>Codespace se vytváří jednoduše kliknutím na tlačítko “Code” ve vašem repozitáří, kde se vám nově zobrazí možnost si Codespace vytvořit.</p>
|
||||||
|
|
||||||
|
<p>Ve výchozím stavu běží server na Ubuntu. Pokud nenajdete docker obraz nebo devcontainer konfigurační soubor, musíte si samozřejmě vše nainstalovat sami, což zas tolik nevadí, protože to nejspíš budete dělat jen jednou, pokud si nebudete s obrazem stroje nějak zahrávat.</p>
|
||||||
|
|
||||||
|
<p>Instalace všeho však probíhá svižně, jelikož asi v Microsoftu mají na rychlejší internet, než já. Samozřejmě vše musíte instalovat skrze terminál (což mě celkem ranilo, jelikož instalovat Android SDK pro flutter byla celkem fuška).</p>
|
||||||
|
|
||||||
|
<p>Pokud používáte Settings Sync ve VS Code, automaticky se vám synchronizují nastavení a rozšíření. Pro pokročilé upravení prostředí slouží konfigurační soubor devcontainer.json
|
||||||
|
<img src="/assets/images/codespaces/2.jpg" alt="Ceny Codespaces"></p>
|
||||||
|
|
||||||
|
<p>Jakmile máte všechno nastavené, už stačí jen využít starého známého Visual Studio Code, které funguje úplně stejně jako na lokálním zařízení. Na Codespace se můžete kdykoli připojit přes webovou adresu.</p>
|
||||||
|
|
||||||
|
<p>Za mě velice praktické pro dříve uvedené typy lidí, už jen záleží, jestli se to zrovna vám za ty peníze vyplatí. Dokumentace je možná trochu chaotická, alespoň pro uživatele co se nevyznají v technologiích jako kontejnery či docker a většiny funkcí využije jen skutečný poweruser (což já určitě nejsem).</p>
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</article>
|
||||||
|
<div class="post-nav">
|
||||||
|
<a class="previous" href="/programov%C3%A1n%C3%AD/2022/05/22/automatizace.html" title="Automatizace, automatizace, automatizace">Automatizace, automatizace, automatizace</a><a class="next" href="/bezpe%C4%8D%C3%AD/2022/07/19/nordvpn.html" title="NordVPN - Jste opravdu v takovém nebezpečí?">NordVPN - Jste opravdu v takovém...</a>
|
||||||
|
</div>
|
||||||
|
<div class="post-related">
|
||||||
|
<div>Related Articles</div>
|
||||||
|
<ul>
|
||||||
|
<li><a class="post-link" href="/vychyt%C3%A1vky/2022/05/31/codespaces.html" title="NordVPN - Jste opravdu v takovém nebezpečí?">GitHub Codespaces aneb VS Code na VPS</a></li>
|
||||||
|
<li><a class="post-link" href="/bezpe%C4%8D%C3%AD/2022/07/19/nordvpn.html" title="NordVPN - Jste opravdu v takovém nebezpečí?">NordVPN - Jste opravdu v takovém nebezpečí?</a></li>
|
||||||
|
<li><a class="post-link" href="/programov%C3%A1n%C3%AD/2022/05/22/automatizace.html" title="NordVPN - Jste opravdu v takovém nebezpečí?">Automatizace, automatizace, automatizace</a></li>
|
||||||
|
<li><a class="post-link" href="/tutori%C3%A1l/2022/10/22/rpi-arch.html" title="NordVPN - Jste opravdu v takovém nebezpečí?">Instalujeme Arch Linux ARM na Raspberry Pi 3</a></li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
<div class="post-comments"> <div id="gitment_thread" class="giscus"></div>
|
||||||
|
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/theme-next/theme-next-gitment@1/default.css">
|
||||||
|
<script src="https://cdn.jsdelivr.net/gh/theme-next/theme-next-gitment@1/gitment.browser.js"></script>
|
||||||
|
<script src="https://giscus.app/client.js" data-repo="hernikplays/blog" data-repo-id="R_kgDOHr2B6w" data-category="General" data-category-id="DIC_kwDOHr2B684CSIhA" data-mapping="pathname" data-strict="0" data-reactions-enabled="1" data-emit-metadata="0" data-input-position="top" data-theme="transparent_dark" data-lang="en" data-loading="lazy" crossorigin="anonymous" async>
|
||||||
|
</script>
|
||||||
|
</div></section>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
</section>
|
||||||
|
<section class="sidebar" style="margin-left: 15px;">
|
||||||
|
<!-- Get sidebar items --></section>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</main><footer class="site-footer h-card">
|
||||||
|
<data class="u-url" href="/"></data>
|
||||||
|
|
||||||
|
<div class="wrapper">
|
||||||
|
<div class="site-footer-inner">
|
||||||
|
<div>Copyright © 2021-2022 hernikplays</div>
|
||||||
|
<div>Powered by <a title="Jekyll is a simple, blog-aware, static site
|
||||||
|
generator." href="https://jekyllrb.com/">Jekyll</a> & <a title="Yat, yet
|
||||||
|
another theme." href="https://github.com/jeffreytse/jekyll-theme-yat">Yat Theme</a>.</div>
|
||||||
|
<div><a rel="me" href="https://social.linux.pizza/@hernik">Mastodon</a></div>
|
||||||
|
<div class="footer-col rss-subscribe">Subscribe <a href="/feed.xml">via RSS</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</footer>
|
||||||
|
</body>
|
||||||
|
</html>
|