Remove static ghub pages and use automatic build instead.
33
.github/workflows/build.yml
vendored
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
name: Build Eleventy
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-20.04
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
node-version: [12.x]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
|
||||
- name: Use Node.js ${{ matrix.node-version }}
|
||||
uses: actions/setup-node@v1
|
||||
with:
|
||||
node-version: ${{ matrix.node-version }}
|
||||
|
||||
- name: Install dependencies & build
|
||||
run: |
|
||||
npm ci
|
||||
npm run build
|
||||
|
||||
- name: Deploy
|
||||
uses: peaceiris/actions-gh-pages@v3
|
||||
with:
|
||||
publish_dir: ./_site
|
||||
github_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
43
.github/workflows/static.yml
vendored
|
|
@ -1,43 +0,0 @@
|
|||
# Simple workflow for deploying static content to GitHub Pages
|
||||
name: Deploy static content to Pages
|
||||
|
||||
on:
|
||||
# Runs on pushes targeting the default branch
|
||||
push:
|
||||
branches: ["main"]
|
||||
|
||||
# Allows you to run this workflow manually from the Actions tab
|
||||
workflow_dispatch:
|
||||
|
||||
# Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages
|
||||
permissions:
|
||||
contents: read
|
||||
pages: write
|
||||
id-token: write
|
||||
|
||||
# Allow only one concurrent deployment, skipping runs queued between the run in-progress and latest queued.
|
||||
# However, do NOT cancel in-progress runs as we want to allow these production deployments to complete.
|
||||
concurrency:
|
||||
group: "pages"
|
||||
cancel-in-progress: false
|
||||
|
||||
jobs:
|
||||
# Single deploy job since we're just deploying
|
||||
deploy:
|
||||
environment:
|
||||
name: github-pages
|
||||
url: ${{ steps.deployment.outputs.page_url }}
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
- name: Setup Pages
|
||||
uses: actions/configure-pages@v5
|
||||
- name: Upload artifact
|
||||
uses: actions/upload-pages-artifact@v3
|
||||
with:
|
||||
# Upload entire repository
|
||||
path: 'docs'
|
||||
- name: Deploy to GitHub Pages
|
||||
id: deployment
|
||||
uses: actions/deploy-pages@v4
|
||||
3
.gitignore
vendored
|
|
@ -1,2 +1,3 @@
|
|||
_site/
|
||||
node_modules/
|
||||
node_modules/
|
||||
docs/
|
||||
|
|
@ -1,80 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Adrian Victor</title>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<link rel="stylesheet" href="/static/main.css?fixcache=1">
|
||||
<script src="/static/scripts/ccd.js"></script>
|
||||
<script src="/static/scripts/main.js" defer></script>
|
||||
<link rel="apple-touch-icon" sizes="180x180" href="/static/apple-touch-icon.png">
|
||||
<link rel="icon" type="image/png" sizes="32x32" href="/static/favicon-32x32.png">
|
||||
<link rel="icon" type="image/png" sizes="16x16" href="/static/favicon-16x16.png">
|
||||
<link rel="manifest" href="/static/site.webmanifest">
|
||||
<script src="https://keepandroidopen.org/banner.js" defer></script>
|
||||
</head>
|
||||
<body>
|
||||
<style>
|
||||
.bg {
|
||||
opacity: .4!important;
|
||||
}
|
||||
</style>
|
||||
<div id="everythingHelper">
|
||||
<img src="/static/images/bear.jpg" class="bg">
|
||||
<header>
|
||||
<div>
|
||||
<h1>Adrian Victor:Blog</h1>
|
||||
<a id="headerSubtitle"><i>Fanasy is not a crime, find your castle in the sky.</i></a>
|
||||
<script>
|
||||
const headeri18n =
|
||||
{
|
||||
by: "by",
|
||||
options: "Options",
|
||||
hideBackground: "Hide background",
|
||||
back: "back"
|
||||
}
|
||||
</script>
|
||||
</div>
|
||||
<div id="linksHelper">
|
||||
<div id="music">
|
||||
</div>
|
||||
<ul id="headerLinks">
|
||||
<a href="/en/">home</a>
|
||||
<a href="/en/blog/">blog</a>
|
||||
</ul>
|
||||
</div>
|
||||
</header>
|
||||
<div id="mainHelper">
|
||||
|
||||
<main>
|
||||
<p><b>Listing Blog Posts:</b></p>
|
||||
<ul>
|
||||
|
||||
|
||||
<li>
|
||||
<p>
|
||||
<a href="/posts/android-developer-verification/">On the Recent Changes to App Distribution Requirements in the Android System by Google.</a><br>
|
||||
Fri Aug 29 2025 21:00:00 GMT-0300 (Brasilia Standard Time)
|
||||
</p>
|
||||
</li>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<li>
|
||||
<p>
|
||||
<a href="/posts/telnet-en/">Telnet</a><br>
|
||||
Tue Aug 26 2025 21:00:00 GMT-0300 (Brasilia Standard Time)
|
||||
</p>
|
||||
</li>
|
||||
|
||||
|
||||
|
||||
|
||||
</ul>
|
||||
</main>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -1,149 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Adrian Victor</title>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<link rel="stylesheet" href="/static/main.css?fixcache=1">
|
||||
<script src="/static/scripts/ccd.js"></script>
|
||||
<script src="/static/scripts/main.js" defer></script>
|
||||
<link rel="apple-touch-icon" sizes="180x180" href="/static/apple-touch-icon.png">
|
||||
<link rel="icon" type="image/png" sizes="32x32" href="/static/favicon-32x32.png">
|
||||
<link rel="icon" type="image/png" sizes="16x16" href="/static/favicon-16x16.png">
|
||||
<link rel="manifest" href="/static/site.webmanifest">
|
||||
<script src="https://keepandroidopen.org/banner.js" defer></script>
|
||||
</head>
|
||||
<body>
|
||||
<style>
|
||||
.bg {
|
||||
opacity: .4!important;
|
||||
}
|
||||
</style>
|
||||
<div id="everythingHelper">
|
||||
<img src="/static/images/bear.jpg" class="bg">
|
||||
<header>
|
||||
<div>
|
||||
<h1>Adrian Victor</h1>
|
||||
<a id="headerSubtitle"><i>Fanasy is not a crime, find your castle in the sky.</i></a>
|
||||
<script>
|
||||
const headeri18n =
|
||||
{
|
||||
by: "by",
|
||||
options: "Options",
|
||||
hideBackground: "Hide background",
|
||||
back: "back"
|
||||
}
|
||||
</script>
|
||||
</div>
|
||||
<div id="linksHelper">
|
||||
<div id="music">
|
||||
</div>
|
||||
<ul id="headerLinks">
|
||||
<a href="/en/">home</a>
|
||||
<a href="/en/blog/">blog</a>
|
||||
</ul>
|
||||
</div>
|
||||
</header>
|
||||
<div id="mainHelper">
|
||||
|
||||
<div id="homeSquares">
|
||||
</div>
|
||||
<main>
|
||||
<script src="/static/scripts/home.js" defer></script>
|
||||
<noscript><style>
|
||||
.hs {
|
||||
display: unset!important;
|
||||
}
|
||||
#homeSquares {
|
||||
display: none;
|
||||
}
|
||||
</style></noscript>
|
||||
<div class="hs" id="hsDefault">
|
||||
<h1 id="homeTitle">Welcome</h1>
|
||||
<p>It seems that you have found my website! Hi, I am <b>Adrian Victor</b> (or <b>tenkuma</b>), a Brazilian guy who likes to mess around with computers, computer programs and <i>enimatpyrtlyhtemids</i>.</p>
|
||||
<h2>Socials and Contact</h2>
|
||||
<p>
|
||||
I'm publicly available at Mastodon <a href='https://mstdn.social/@tenkuma'>(@tenkuma@mstdn.social)</a>,
|
||||
GitHub <a href='https://github.com/adrianvic'>(adrianvic)</a>,
|
||||
Disroot Git <a href='https://git.disroot.org/adrianvictor'>(adrianvictor)</a>,
|
||||
Discord <a href='https://discord.com/users/681643259764015116'>(@adrianvic)</a>,
|
||||
YouTube <a href='https://www.youtube.com/@adrianvictor8'>(@adrianvictor8)</a>,
|
||||
BitView <a href='https://www.bitview.net/user/tenkuma'>(tenkuma)</a>,
|
||||
Modrinth <a href='https://modrinth.com/user/tenkumabear'>(tenkumabear)</a>
|
||||
and XMPP <a href='xmpp:adrianvictor@disroot.org'>(adrianvictor@disroot.org)</a>.
|
||||
</p>
|
||||
<p>You can message me on my E-mail <a href="mailto:adrianvictor@disroot.org">(adrianvictor@disroot.org)</a> or feel free to get in touch through any of the other places mentioned above. For project-specific subjects, check for the project's contact field or if there's no such field add <i>+projectname</i> to my E-mail address (example: adrianvictor+coolproject@disroot.org).</p>
|
||||
<p><i><b>Please, avoid reaching me through ways not mentioned above :)</b></i></p>
|
||||
</div>
|
||||
<div class="hs" id="hsMusic">
|
||||
<h1>My Music</h1>
|
||||
<p>Me and my friends have an amateur record label called <span class="margarinaColor">Margarina Records</span>, things usually move slowly with my musical works, usually because of college and the lack of proper music production knowledge, but I'm working my way through it.</p>
|
||||
<p>You can follow my latest songs at the <a href="https://margarina-records.rf.gd">label website</a> and on <a href="https://genius.com/tenkuma">Genius</a>. You'd probably also like the other member's works as well, so take a look at all songs from MGR.</p>
|
||||
</div>
|
||||
<div class="hs" id="hsVideo">
|
||||
<h1>My Videos</h1>
|
||||
<p>I have a YouTube channel where I post mostly Minecraft videos, but I want to have other types of content in the future. There's no scedule for my videos because it takes a lot of editing time to put a video together, and I have little time to work on my own projects, you should subscribe if you want to know when I post something!</p>
|
||||
<p>Here's a random video I'm proud of:</p>
|
||||
<a href="https://youtu.be/tZLoSxzsfpM" id="youtubeVideo">
|
||||
<img src="/static/images/youtube_video.jpg" alt="" id="youtubeVideoImage">
|
||||
<p>How to use MCA Selector to merge worlds in Minecraft Java!</p>
|
||||
</a>
|
||||
</div>
|
||||
<div class="hs" id="hsCode">
|
||||
<h1>My Software</h1>
|
||||
<p>I am studying computing at IFC (SC, Brazil) but in my free time I have some projects like computer applications, Minecraft plugins, Minecraft servers, etc... Anything that is public should be in my <a href="https://github.com/adrianvic">GitHub profile</a>.</p>
|
||||
|
||||
<div class="hsProjects">
|
||||
<div class="hsProject">
|
||||
<div class="hsProjectHeader">
|
||||
<div class="hsProjectImage"><img src="/static/images/jamfish-wide.png" alt="A digital drawing of the top of a fork with a black outline, in the right a text in white says 'Pesto Wiki'"></div>
|
||||
<a href="https://github.com/adrianvic/jamfish" class="hsProjectHeaderIcon">
|
||||
<img src="/static/visual/github.svg" class="invertedc">
|
||||
</a>
|
||||
</div>
|
||||
<div class="hsProjectContent">
|
||||
<p>Native music player for Android devices that connects to Jellyfin media servers. The code is based on Gelli's archived repository, which is based on an old version of Phonograph.</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="hsProject">
|
||||
<div class="hsProjectHeader">
|
||||
<div class="hsProjectImage"><img src="/static/images/eye_of_nemesis.png" alt=""></div>
|
||||
<a href="https://github.com/adrianvic/NemesisEye" class="hsProjectHeaderIcon">
|
||||
<img src="/static/visual/github.svg" class="invertedc">
|
||||
</a>
|
||||
</div>
|
||||
<div class="hsProjectContent">
|
||||
<p>Eye of Nemesis is a plugin that allows server admins to write policies that will deny or allow (black/whitelist) players to do specific things based on the value of nodes.</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="hsProject">
|
||||
<div class="hsProjectHeader">
|
||||
<div class="hsProjectImage"><img src="/static/images/itemeconomy2-wide.png" alt=""></div>
|
||||
<a href="https://github.com/adrianvic/ItemEconomy" class="hsProjectHeaderIcon">
|
||||
<img src="/static/visual/github.svg" class="invertedc">
|
||||
</a>
|
||||
</div>
|
||||
<div class="hsProjectContent">
|
||||
<p>This PaperMC plugin integrates with VaultUnlocked to provide a unique, item-based economy system for your Minecraft server. Instead of relying solely on virtual balances, players use in-game items as physical currency, adding a layer of immersion and realism to your economy.</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="hsProject">
|
||||
<div class="hsProjectHeader">
|
||||
<div class="hsProjectImage"><img src="/static/images/pestowikifullwhite.png" alt=""></div>
|
||||
<a href="https://github.com/Margarina-not-butter/PestoWiki" class="hsProjectHeaderIcon">
|
||||
<img src="/static/visual/github.svg" class="invertedc">
|
||||
</a>
|
||||
</div>
|
||||
<div class="hsProjectContent">
|
||||
<p>Multi-platform customizable client for wikis written in Python using PySide6 (QT).</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -1,64 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Adrian Victor</title>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<link rel="stylesheet" href="/static/main.css?fixcache=1">
|
||||
<script src="/static/scripts/ccd.js"></script>
|
||||
<script src="/static/scripts/main.js" defer></script>
|
||||
<link rel="apple-touch-icon" sizes="180x180" href="/static/apple-touch-icon.png">
|
||||
<link rel="icon" type="image/png" sizes="32x32" href="/static/favicon-32x32.png">
|
||||
<link rel="icon" type="image/png" sizes="16x16" href="/static/favicon-16x16.png">
|
||||
<link rel="manifest" href="/static/site.webmanifest">
|
||||
<script src="https://keepandroidopen.org/banner.js" defer></script>
|
||||
</head>
|
||||
<body>
|
||||
<style>
|
||||
.bg {
|
||||
opacity: .4!important;
|
||||
}
|
||||
</style>
|
||||
<div id="everythingHelper">
|
||||
<img src="/static/images/bear.jpg" class="bg">
|
||||
<header>
|
||||
<div>
|
||||
<h1>Adrian Victor</h1>
|
||||
<a id="headerSubtitle"><i>Fanasy is not a crime, find your castle in the sky.</i></a>
|
||||
<script>
|
||||
const headeri18n =
|
||||
{
|
||||
by: "by",
|
||||
options: "Options",
|
||||
hideBackground: "Hide background",
|
||||
back: "back"
|
||||
}
|
||||
</script>
|
||||
</div>
|
||||
<div id="linksHelper">
|
||||
<div id="music">
|
||||
</div>
|
||||
<ul id="headerLinks">
|
||||
<a href="/en/">home</a>
|
||||
<a href="/en/blog/">blog</a>
|
||||
</ul>
|
||||
</div>
|
||||
</header>
|
||||
<div id="mainHelper">
|
||||
<script src="/static/scripts/language.js" defer></script>
|
||||
<style>
|
||||
#headerLinks {
|
||||
display: none!important;
|
||||
}
|
||||
</style>
|
||||
<main>
|
||||
<h1 id="languageTitle">Pick a language</h1>
|
||||
<ul id="languageList">
|
||||
<li><a href="/en/">English</a></li>
|
||||
<li><a href="/pt/">Português Brasileiro</a></li>
|
||||
</ul>
|
||||
</main>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -1,101 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Adrian Victor - On the Recent Changes to App Distribution Requirements in the Android System by Google.</title>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<link rel="stylesheet" href="/static/main.css?fixcache=1">
|
||||
<script src="/static/scripts/ccd.js"></script>
|
||||
<script src="/static/scripts/main.js" defer></script>
|
||||
<link rel="apple-touch-icon" sizes="180x180" href="/static/apple-touch-icon.png">
|
||||
<link rel="icon" type="image/png" sizes="32x32" href="/static/favicon-32x32.png">
|
||||
<link rel="icon" type="image/png" sizes="16x16" href="/static/favicon-16x16.png">
|
||||
<link rel="manifest" href="/static/site.webmanifest">
|
||||
<script src="https://keepandroidopen.org/banner.js" defer></script>
|
||||
</head>
|
||||
<body>
|
||||
<style>
|
||||
.bg {
|
||||
opacity: 0.35!important;
|
||||
}
|
||||
</style>
|
||||
<div id="everythingHelper">
|
||||
<img src="/static/images/android-jellybean.jpg" class="bg">
|
||||
<header>
|
||||
<div>
|
||||
<h1>Adrian Victor:Blog</h1>
|
||||
<a id="headerSubtitle"><i>Fanasy is not a crime, find your castle in the sky.</i></a>
|
||||
<script>
|
||||
const headeri18n =
|
||||
{
|
||||
by: "by",
|
||||
options: "Options",
|
||||
hideBackground: "Hide background",
|
||||
back: "back"
|
||||
}
|
||||
</script>
|
||||
</div>
|
||||
<div id="linksHelper">
|
||||
<div id="music">
|
||||
</div>
|
||||
<ul id="headerLinks">
|
||||
<a href="/en/">home</a>
|
||||
<a href="/en/blog/">blog</a>
|
||||
</ul>
|
||||
</div>
|
||||
</header>
|
||||
<div id="mainHelper">
|
||||
<main>
|
||||
<article>
|
||||
<div id="postHeader">
|
||||
<h1>On the Recent Changes to App Distribution Requirements in the Android System by Google.</h1>
|
||||
<p>Adrian Victor - Fri Aug 29 2025 21:00:00 GMT-0300 (Brasilia Standard Time)</p>
|
||||
</div>
|
||||
<h2>Recap</h2>
|
||||
|
||||
<p>Android is that open-source operating system that works well for users and is loved by developers. Always known for breaking barriers and being open, expandable, versatile, and even friendly to power users-something not every system dares to be (iOS, Windows Phone). For a long time, Android was seen this way compared to its competitors: a breath of fresh air against the abusive practices of companies like Apple. But it seems the Android we've nurtured for two decades no longer fits in the pockets of Google executives; it is too free, creating ethical and technical barriers to the profitable exploitation path adopted by its developer.</p>
|
||||
|
||||
<h2>What happened with Android?</h2>
|
||||
|
||||
<p>At the end of this month (August 2025), Google announced that starting September 2026, all apps installed on certified devices (those with Google Android and locked bootloader) will need to undergo a developer verification process. This process involves collecting personal data from the individual distributing the app, so they can be identified and held accountable for potential malicious activities related to their software. The same applies to companies, which must also pay a $25 USD fee. This process is mandatory even if the app is distributed outside Google's official stores, raising obvious concerns about user privacy and freedom.</p>
|
||||
|
||||
<h2>Implications, Justifications, and Motivations of the New Policy</h2>
|
||||
|
||||
<p>It is important to examine Google's justification and try to understand its true motivation behind this distribution policy. Let's start by analyzing Google's statement:</p>
|
||||
|
||||
<blockquote cite="https://developer.android.com/developer-verification">"By making Android safer, we're protecting the open environment that allows developers and users to confidently create and connect. Android's new developer verification is an extra layer of security that deters bad actors and makes it harder for them to spread harm."</blockquote>
|
||||
|
||||
<p>They argue that the new rules are intended to improve user security, preventing malicious software from being installed on certified Android devices. Again, we see "security" used to justify controversial practices that limit the end user's control over their device. This was also the justification given for the proven abusive sideloading restrictions that led Google to lose a lawsuit against Epic Games-a more sophisticated version of the same issue is happening here.</p>
|
||||
|
||||
<p>It is easy to sympathize with the company when the words are well-phrased, but as a user who loves alternative software outside the big tech ecosystem, I have seen enough examples of authority abuse to conclude that Google's recent actions are simply an attempt to regain part, if not all, of the control it had over Android devices before the previously mentioned case.</p>
|
||||
|
||||
<p>One example is the kio-gdrive software, widely used to integrate Google Drive with the KDE file manager on Linux systems. The software was blocked from asking users if they authorized access to their Google Drive account. Instead of the permission popup, Google displayed a warning implying that the legitimate software could be malicious. Developers reported:</p>
|
||||
|
||||
<blockquote cite="https://bugs.kde.org/show_bug.cgi?id=480779#c54">"Google blocked us from using this back in June because we weren't able
|
||||
justify our API usage to their satisfaction. As such, the permission is now blocked [...] mamaking 25% of the KAccounts KCM non-functional. Remove the gdrive permissions [...] for now so at least other Google things can work (at least in theory)."</blockquote>
|
||||
|
||||
<blockquote cite="https://bugs.kde.org/show_bug.cgi?id=480779#c54">"It's beyond stupid (IMHO) if individual users can't indicate that they're fine with a particular piece of software accessing their supposedly sensitive data!"</blockquote>
|
||||
|
||||
<p>Although I couldn't find the exact internal conversations between developers-and I'm giving Google the benefit of the doubt-it is at least suspicious that Google did not agree that software performing its primary functions within Google Drive should have a valid reason to access it. This was not an isolated case; Google operates behind the scenes to control what happens on Android. For example, apps compiled for older system versions would show alarming security warnings because recent changes introduced more permission barriers, even though old apps didn't support them. A reasonable warning would emphasize that permissions must be granted to support optional features, but the actual messages were vague, conveniently scaring users attempting sideloading and helping maintain the Play Store monopoly.</p>
|
||||
|
||||
<p>Speaking of alarming warnings, let's discuss Play Protect, software embedded in the Google Play Store that scans installed sideloaded apps and reports the results back to Google. At first glance, this is a good idea, assuming the user opts in. The problem arises when the difference between malware detection messages and warnings triggered by outdated software is unclear, causing two serious effects: it renders Google's protection service almost useless while maintaining the Play Store monopoly.</p>
|
||||
|
||||
<p>Imagine sideloading for the first time: you try to install an old version of a favored software. You receive exaggerated warnings about the supposed dangers, abandon the installation, and install the latest version from the Play Store. Google thus indirectly forces more users to use its store, ensuring the lucrative 30% transaction fee.</p>
|
||||
|
||||
<p>Now consider a second scenario: you're an advanced Android user who understands sideloading and loves installing open-source apps outside the Play Store. You click a suspicious link and download a malicious APK. Play Protect warns you during installation, but the warnings are so frequent and exaggerated-even when no malware is detected-that you ignore them out of habit. The result: malware on your device, and Play Protect was ineffective.</p>
|
||||
|
||||
<p>Sometimes, downloading software outside the Play Store is the only option, because developers may not want to publish apps there-either for privacy reasons (developers must disclose personal data when publishing) or because of publishing fees, which may discourage donation-supported developers. Users must have the freedom to choose what runs on their devices.</p>
|
||||
|
||||
<p>According to current information, developers don't have to make their data public if they avoid distributing apps via the Play Store. This is the least Google could do to make the new distribution policies fairer. Google also claims the verification isn't meant to inspect app content or purpose; it is supposedly only to block malware distribution. Whether this holds up remains to be seen, given it could also serve as a convenient tool for abuse of power.</p>
|
||||
|
||||
<h2>Next Steps</h2>
|
||||
|
||||
<p>We must watch how these policies are applied and how they affect the Android ecosystem. An inevitable consequence is that countless abandoned apps, perfectly functional without the new requirements, will disappear overnight. Not all old software connects to the internet, and not all represents a constant threat. Google is taking away the option for experienced users to take responsibility and say: "I know what I'm doing!", treating us like children, as if they know what's best for everyone.</p>
|
||||
|
||||
<p>The commercial Android on phones is based on the <abbr title="Android Open Source Project">AOSP</abbr>, meaning Android's core remains open, and Google hasn't taken that from users yet. I plan to write another post explaining how to regain control of your device through system modifications, from the simplest, safest, most stable methods to advanced approaches, if you feel confident.</p>
|
||||
</article>
|
||||
</main>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -1,112 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Adrian Victor - Telnet</title>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<link rel="stylesheet" href="/static/main.css?fixcache=1">
|
||||
<script src="/static/scripts/ccd.js"></script>
|
||||
<script src="/static/scripts/main.js" defer></script>
|
||||
<link rel="apple-touch-icon" sizes="180x180" href="/static/apple-touch-icon.png">
|
||||
<link rel="icon" type="image/png" sizes="32x32" href="/static/favicon-32x32.png">
|
||||
<link rel="icon" type="image/png" sizes="16x16" href="/static/favicon-16x16.png">
|
||||
<link rel="manifest" href="/static/site.webmanifest">
|
||||
<script src="https://keepandroidopen.org/banner.js" defer></script>
|
||||
</head>
|
||||
<body>
|
||||
<style>
|
||||
.bg {
|
||||
opacity: .4!important;
|
||||
}
|
||||
</style>
|
||||
<div id="everythingHelper">
|
||||
<img src="/static/images/redes.jpg" class="bg">
|
||||
<header>
|
||||
<div>
|
||||
<h1>Adrian Victor:Blog</h1>
|
||||
<a id="headerSubtitle"><i>Fanasy is not a crime, find your castle in the sky.</i></a>
|
||||
<script>
|
||||
const headeri18n =
|
||||
{
|
||||
by: "by",
|
||||
options: "Options",
|
||||
hideBackground: "Hide background",
|
||||
back: "back"
|
||||
}
|
||||
</script>
|
||||
</div>
|
||||
<div id="linksHelper">
|
||||
<div id="music">
|
||||
</div>
|
||||
<ul id="headerLinks">
|
||||
<a href="/en/">home</a>
|
||||
<a href="/en/blog/">blog</a>
|
||||
</ul>
|
||||
</div>
|
||||
</header>
|
||||
<div id="mainHelper">
|
||||
<main>
|
||||
<article>
|
||||
<div id="postHeader">
|
||||
<h1>Telnet</h1>
|
||||
<p>Adrian Victor & Arthur Borges - Tue Aug 26 2025 21:00:00 GMT-0300 (Brasilia Standard Time)</p>
|
||||
</div>
|
||||
<script src="/static/scripts/telnetSimulator.js" defer></script>
|
||||
<h2>What the protocol is, its function and history</h2>
|
||||
<p>Telnet (from <b>TEL</b>ecommunication <b>NET</b>work) is a TCP/IP stack network protocol that allows remote text-mode communication between computers. Its main function is to provide an interactive session where a user can access and control another device as if they were on a local terminal.</p>
|
||||
<p>Created in 1969, Telnet was one of the first protocols developed for ARPANET (the network that gave rise to the Internet) and became fundamental for system and device administration in the 1970s, 1980s, and 1990s. Over time, it fell out of use due to lack of security, being replaced by more modern alternatives such as SSH (Secure Shell).</p>
|
||||
<h2>Implementation</h2>
|
||||
<p><b>Default port:</b> 23/TCP.<br>
|
||||
Works at the application layer of the OSI model.<br>
|
||||
<b>Format:</b> Based on ASCII character exchange, without encryption.<br>
|
||||
<b>RFC:</b> Defined by RFC 854 (1983).<br>
|
||||
<b>Architecture:</b> Follows the client-server model</p>
|
||||
<h2>How it works</h2>
|
||||
<p>In practice, Telnet works relatively simply. The process starts when the client establishes a TCP connection to the server via port 23. Then a remote terminal session is initiated and the user must provide credentials such as username and password. After authentication, commands typed on the client are transmitted in plain text to the server, which processes them and returns the corresponding output. The session remains active as long as the user wants, normally ending with commands like <i>exit</i> or <i>logout</i></p>
|
||||
<h2>Use cases</h2>
|
||||
<p>For many years, Telnet was widely used for remote access to Unix, Linux, and Windows servers, especially older versions of these systems. It also became common in network device administration, such as routers and switches, until SSH became the standard. Additionally, mainframes and some legacy devices still use Telnet today. Another practical application is in educational environments and network diagnostics, where it is used to test open ports and check service connectivity, such as running “telnet server.com 80” to see if a web server port is operational.</p>
|
||||
<h2>Encryption: the inherent problem</h2>
|
||||
<p>Telnet has no native encryption, which makes it extremely vulnerable. To solve this problem, more secure alternatives were developed. The main one is SSH (Secure Shell), created in the 1990s as a direct Telnet replacement. SSH offers the same functionality while ensuring data protection through strong authentication and full traffic encryption. Another, less common approach is using SSL/TLS to tunnel Telnet sessions, but in practice this is rarely used.</p>
|
||||
<h2>Advantages and disadvantages</h2>
|
||||
<p>Telnet’s advantages include simplicity, low resource usage, and compatibility with various older systems, which facilitated its adoption over the years. However, these benefits are outweighed by its disadvantages. The main one is the lack of encryption, exposing all transmitted data—including passwords—in plain text. This makes it vulnerable to attacks such as sniffing, which captures network packets, and hijacking, which takes over active sessions. For this reason, Telnet is considered obsolete and unsafe for use on open networks like the Internet.</p>
|
||||
<h2>Relation to other protocols</h2>
|
||||
<p>Telnet is part of the TCP/IP protocol family and uses TCP to ensure reliable communication. Like other protocols in this stack, such as HTTP, FTP, and SMTP, it relies on stable connections to perform its functions, but its distinguishing feature has always been terminal-mode interactivity. Due to security flaws, it was replaced by its natural successor, SSH, which retained Telnet’s conceptual base but added robust protection layers.</p>
|
||||
<h2>Functional example</h2>
|
||||
<p>Below is a Telnet connection simulator written in JavaScript.</p>
|
||||
<div id="telnetSimulationLoadingHolder">
|
||||
<p id="telnetSimulationLoadingText">Loading...</p>
|
||||
<div class="ellipsis-loader" aria-role="alert" aria-label="Loading. Please wait">
|
||||
<div class="ellipsis-loader__dot"></div>
|
||||
<div class="ellipsis-loader__dot"></div>
|
||||
<div class="ellipsis-loader__dot"></div>
|
||||
<div class="ellipsis-loader__dot"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="telnetSimulation">
|
||||
<div id="telnetSimulationServer">
|
||||
<h3>Server</h3>
|
||||
<textarea name="" id="telnetSimulationServerScreen" readonly>Welcome to Zubuntu 30.1!
|
||||
Running startup script: start_telnet_server.sh
|
||||
Telnet Server started on localhost:23
|
||||
Ready to receive commands.
|
||||
----
|
||||
</textarea>
|
||||
<button id="telnetSimulationServerClean">Clear</button>
|
||||
</div>
|
||||
<div id="telnetSimulationClient">
|
||||
<h3>Client</h3>
|
||||
<textarea name="" id="telnetSimulationClientScreen" readonly>Send help to see the list of commands supported by the server!
|
||||
----
|
||||
</textarea>
|
||||
<div id="telnetSimulationInput">
|
||||
<input type="text" id="telnetSimulationInputBox">
|
||||
<button id="telnetSimulationClientSend">Send</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</article>
|
||||
</main>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -1,154 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="pt">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Adrian Victor - Telnet</title>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<link rel="stylesheet" href="/static/main.css?fixcache=1">
|
||||
<script src="/static/scripts/ccd.js"></script>
|
||||
<script src="/static/scripts/main.js" defer></script>
|
||||
<link rel="apple-touch-icon" sizes="180x180" href="/static/apple-touch-icon.png">
|
||||
<link rel="icon" type="image/png" sizes="32x32" href="/static/favicon-32x32.png">
|
||||
<link rel="icon" type="image/png" sizes="16x16" href="/static/favicon-16x16.png">
|
||||
<link rel="manifest" href="/static/site.webmanifest">
|
||||
<script src="https://keepandroidopen.org/banner.js" defer></script>
|
||||
</head>
|
||||
<body>
|
||||
<style>
|
||||
.bg {
|
||||
opacity: .4!important;
|
||||
}
|
||||
</style>
|
||||
<div id="everythingHelper">
|
||||
<img src="/static/images/redes.jpg" class="bg">
|
||||
<header>
|
||||
<div>
|
||||
<h1>Adrian Victor:Blog</h1>
|
||||
<a id="headerSubtitle"><i>Fanasy is not a crime, find your castle in the sky.</i></a>
|
||||
<script>
|
||||
const headeri18n =
|
||||
{
|
||||
by: "por",
|
||||
options: "Options",
|
||||
hideBackground: "Esconder imagem de fundo",
|
||||
back: "voltar"
|
||||
}
|
||||
</script>
|
||||
</div>
|
||||
<div id="linksHelper">
|
||||
<div id="music">
|
||||
</div>
|
||||
<ul id="headerLinks">
|
||||
<a href="/pt/">início</a>
|
||||
<a href="/pt/blog/">blog</a>
|
||||
</ul>
|
||||
</div>
|
||||
</header>
|
||||
<div id="mainHelper">
|
||||
<main>
|
||||
<article>
|
||||
<div id="postHeader">
|
||||
<h1>Telnet</h1>
|
||||
<p>Adrian Victor & Arthur Borges - Tue Aug 26 2025 21:00:00 GMT-0300 (Brasilia Standard Time)</p>
|
||||
</div>
|
||||
<script src="/static/scripts/telnetSimulator.js" defer></script>
|
||||
<h2>O que é o protocolo, sua função e histórico</h2>
|
||||
<p>O Telnet (do inglês <b>TEL</b>ecommunication <b>NET</b>work) é um protocolo de rede da pilha
|
||||
TCP/IP que permite a comunicação remota entre computadores em modo texto. Sua
|
||||
função principal é proporcionar uma sessão interativa, em que um usuário pode
|
||||
acessar e controlar outro dispositivo como se estivesse em um terminal local.</p>
|
||||
<p>Criado em 1969, o Telnet foi um dos primeiros protocolos desenvolvidos para a
|
||||
ARPANET (a rede que deu origem à Internet) e tornou-se fundamental para a
|
||||
administração de sistemas e dispositivos nas décadas de 1970, 1980 e 1990. Com o
|
||||
tempo, caiu em desuso devido à falta de segurança, sendo substituído por
|
||||
alternativas mais modernas, como o SSH (Secure Shell).</p>
|
||||
<h2>Implementação</h2>
|
||||
<p><b>Porta padrão:</b> 23/TCP.<br>
|
||||
Funciona na camada de aplicação do modelo OSI.<br>
|
||||
<b>Formato:</b> Baseado em troca de caracteres ASCII, sem criptografia.<br>
|
||||
<b>RFC:</b> Definido pela RFC 854 (1983).<br>
|
||||
<b>Arquitetura:</b> Segue o modelo cliente-servidor</p>
|
||||
<h2>Funcionamento</h2>
|
||||
<p>Na prática, o Telnet funciona de maneira relativamente simples. O processo começa
|
||||
quando o cliente estabelece uma conexão TCP com o servidor por meio da porta 23.
|
||||
Em seguida, uma sessão de terminal remoto é iniciada e o usuário deve fornecer
|
||||
suas credenciais, como nome de usuário e senha. Após a autenticação, os
|
||||
comandos digitados no cliente são transmitidos em texto puro ao servidor, que os
|
||||
processa e retorna a saída correspondente. A sessão permanece ativa enquanto o
|
||||
usuário desejar, sendo encerrada normalmente com comandos como <i>exit</i> ou <i>logout</i></p>
|
||||
<h2>Cenários de uso</h2>
|
||||
<p>Durante muitos anos, o Telnet foi amplamente utilizado para acesso remoto a
|
||||
servidores Unix, Linux e Windows, especialmente em versões mais antigas desses
|
||||
sistemas. Também se tornou bastante comum na administração de dispositivos de
|
||||
rede, como roteadores e switches, até que o SSH passou a ser adotado como
|
||||
padrão. Além disso, grandes computadores centrais, conhecidos como mainframes,
|
||||
e alguns dispositivos legados ainda utilizam Telnet até hoje. Outra aplicação prática
|
||||
do protocolo está em ambientes educacionais e no diagnóstico de redes, onde é
|
||||
usado para testar portas abertas e verificar conectividade de serviços, como ao
|
||||
executar “telnet servidor.com 80” para checar se a porta de um servidor web está em
|
||||
funcionamento.</p>
|
||||
<h2>Criptografia: o problema inerente</h2>
|
||||
<p>O Telnet não possui criptografia nativa, o que o torna extremamente vulnerável. Para
|
||||
solucionar esse problema, surgiram alternativas mais seguras. A principal delas é o
|
||||
SSH (Secure Shell), desenvolvido nos anos 1990 como um substituto direto do
|
||||
Telnet. O SSH oferece as mesmas funcionalidades, mas garante a proteção dos
|
||||
dados por meio de autenticação forte e criptografia de todo o tráfego. Outra
|
||||
possibilidade, embora menos comum, é o uso de SSL/TLS para tunelar sessões
|
||||
Telnet, mas na prática essa abordagem raramente é utilizada.</p>
|
||||
<h2>Vantagens e desvantagens</h2>
|
||||
<p>Entre as vantagens do Telnet, destacam-se sua simplicidade, baixo consumo de
|
||||
recursos e compatibilidade com diferentes sistemas antigos, o que facilitou sua
|
||||
adoção ao longo dos anos. Contudo, essas qualidades são superadas por suas
|
||||
desvantagens. A principal é a ausência de criptografia, que expõe todos os dados
|
||||
transmitidos, incluindo senhas, em texto puro. Isso o torna vulnerável a ataques
|
||||
como o sniffing, que captura pacotes de rede, e o hijacking, que sequestra sessões
|
||||
ativas. Por esse motivo, o Telnet é considerado obsoleto e inseguro para uso em
|
||||
redes abertas, como a própria Internet.</p>
|
||||
<h2>Relação com outros protocolos</h2>
|
||||
<p>O Telnet faz parte da família de protocolos da pilha TCP/IP e utiliza o TCP para
|
||||
garantir a confiabilidade na comunicação. Assim como outros protocolos dessa pilha,
|
||||
como HTTP, FTP e SMTP, ele se baseia em conexões estáveis para realizar suas
|
||||
funções, mas seu diferencial sempre foi a interatividade em modo terminal. No
|
||||
entanto, devido às falhas de segurança, acabou sendo substituído por seu sucessor
|
||||
natural, o SSH, que manteve a mesma base conceitual do Telnet, mas adicionou
|
||||
camadas robustas de proteção.</p>
|
||||
<h2>Exemplo funcional</h2>
|
||||
<p>Abaixo há um simulador de conexão Telnet feito em JavaScript.</p>
|
||||
<div id="telnetSimulationLoadingHolder">
|
||||
<p id="telnetSimulationLoadingText">Loading...</p>
|
||||
<div class="ellipsis-loader" aria-role="alert" aria-label="Loading. Please wait">
|
||||
<div class="ellipsis-loader__dot"></div>
|
||||
<div class="ellipsis-loader__dot"></div>
|
||||
<div class="ellipsis-loader__dot"></div>
|
||||
<div class="ellipsis-loader__dot"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="telnetSimulation">
|
||||
<div id="telnetSimulationServer">
|
||||
<h3>Servidor</h3>
|
||||
<textarea name="" id="telnetSimulationServerScreen" readonly>Bem vindo ao Zubuntu 30.1!
|
||||
Rodando script de inicialização: start_telnet_server.sh
|
||||
Servidor Telnet iniciado em localhost:23
|
||||
Pronto para receber comandos.
|
||||
----
|
||||
</textarea>
|
||||
<button id="telnetSimulationServerClean">Limpar</button>
|
||||
</div>
|
||||
<div id="telnetSimulationClient">
|
||||
<h3>Cliente</h3>
|
||||
<textarea name="" id="telnetSimulationClientScreen" readonly>Envie help para ver a lista de comandos suportados pelo servidor!
|
||||
----
|
||||
</textarea>
|
||||
<div id="telnetSimulationInput">
|
||||
<input type="text" id="telnetSimulationInputBox">
|
||||
<button id="telnetSimulationClientSend">Enviar</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</article>
|
||||
</main>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -1,100 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="pt">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Adrian Victor - Sobre as recentes mudanças nos requisitos de distribuição de apps no sistema Android feitas pela Google.</title>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<link rel="stylesheet" href="/static/main.css?fixcache=1">
|
||||
<script src="/static/scripts/ccd.js"></script>
|
||||
<script src="/static/scripts/main.js" defer></script>
|
||||
<link rel="apple-touch-icon" sizes="180x180" href="/static/apple-touch-icon.png">
|
||||
<link rel="icon" type="image/png" sizes="32x32" href="/static/favicon-32x32.png">
|
||||
<link rel="icon" type="image/png" sizes="16x16" href="/static/favicon-16x16.png">
|
||||
<link rel="manifest" href="/static/site.webmanifest">
|
||||
<script src="https://keepandroidopen.org/banner.js" defer></script>
|
||||
</head>
|
||||
<body>
|
||||
<style>
|
||||
.bg {
|
||||
opacity: 0.35!important;
|
||||
}
|
||||
</style>
|
||||
<div id="everythingHelper">
|
||||
<img src="/static/images/android-jellybean.jpg" class="bg">
|
||||
<header>
|
||||
<div>
|
||||
<h1>Adrian Victor:Blog</h1>
|
||||
<a id="headerSubtitle"><i>Fanasy is not a crime, find your castle in the sky.</i></a>
|
||||
<script>
|
||||
const headeri18n =
|
||||
{
|
||||
by: "por",
|
||||
options: "Options",
|
||||
hideBackground: "Esconder imagem de fundo",
|
||||
back: "voltar"
|
||||
}
|
||||
</script>
|
||||
</div>
|
||||
<div id="linksHelper">
|
||||
<div id="music">
|
||||
</div>
|
||||
<ul id="headerLinks">
|
||||
<a href="/pt/">início</a>
|
||||
<a href="/pt/blog/">blog</a>
|
||||
</ul>
|
||||
</div>
|
||||
</header>
|
||||
<div id="mainHelper">
|
||||
<main>
|
||||
<article>
|
||||
<div id="postHeader">
|
||||
<h1>Sobre as recentes mudanças nos requisitos de distribuição de apps no sistema Android feitas pela Google.</h1>
|
||||
<p>Adrian Victor - Fri Aug 29 2025 21:00:00 GMT-0300 (Brasilia Standard Time)</p>
|
||||
</div>
|
||||
<h2>Recapitulando</h2>
|
||||
|
||||
<p>Android é aquele sistema operacional open-source que funciona bem para os usuários, e que os desenvolvedores amam. Sempre conhecido por quebrar barreiras e por ser aberto, expansível, versátil e até amigável com os mais nerds, coisa que nem todo sistema tem a cara e coragem de ser (iOS, Windows Phone). É assim que, por muito tempo, o Android foi visto em relação aos seus concorrentes: Um suspiro de ar puro em relação às práticas abusivas de empresas como a Apple. Mas parece que o Android que cultivamos por duas décadas não cabe mais no bolso dos executivos da Google, é livre demais, e isso criou barreiras éticas e técnicas no lucrativo caminho de exploração adotado pela sua desenvolvedora.</p>
|
||||
|
||||
<h2>O que aconteceu com o Android?</h2>
|
||||
|
||||
<p>A Google anunciou no final deste mês (Agosto de 2025) que a partir de Setembro de 2026 todos os apps instalados em dispositivos certificados (aqueles com o Android da Google e de bootloader bloqueado) precisarão passar pelo processo de verificação de desenvolvedor, processo cujo consiste da coleta de dados pessoais do indivíduo que vai distribuir a aplicação para que o mesmo possa ser identificado e atribuído a possíveis atividades maliciosas relacionadas ao seu software, o mesmo vale para empresas, que além disso precisam pagar uma taxa de 25 USD. O processo é forçado e necessário mesmo com a distribuição do app sendo feita fora das lojas oficiais da Google, o que trouxe óbvias preocupações sobre privacidade e liberdade dos usuários do sistema.</p>
|
||||
|
||||
<h2>As implicações, justificativas e motivações da nova política</h2>
|
||||
|
||||
<p>É importante analisar a justificativa e tentar entender a real motivação que a Google teve ao criar tal política de distribuição. Portanto começamos analisando a fala da Google:</p>
|
||||
|
||||
<blockquote cite="https://developer.android.com/developer-verification">"Para tornar o Android mais seguro, estamos protegendo o ambiente aberto que permite que desenvolvedores e usuários criem e se conectem com confiança. A nova verificação de desenvolvedor do Android é uma camada que detém atores maliciosos e faz com que seja mais difícil para que eles espalhem o mau."</blockquote>
|
||||
|
||||
<p>Ela argumenta que as novas regras do sistema foram feitas com a intenção de aprimorar a segurança do usuário, evitando que software malicioso seja instalado em dispositivos Android certificados. Outra vez vemos segurança sendo usada como forma de justificar práticas controversas que limitam o poder do usuário final no seu próprio dispositivo. Essa também era a justificativa dada para a prática comprovadamente abusiva de bloqueio de sideloading de apps que levou a Google a perder seu caso no tribunal contra a empresa Epic Games, aqui vemos uma versão mais sofisticada da mesma.</p>
|
||||
|
||||
<p>É fácil simpatizar com a empresa quando as palavras são bem colocadas, mas como usuário ávido de softwares alternativos aos das big-techs, eu já vi exemplos de abuso de autoridade suficientes para concluir que as recentes ações da Google não passam de uma forma de recuperar parte, se não todo o controle que ela tinha sobre os dispositivos Android antes do caso mencionado anteriormente.</p>
|
||||
|
||||
<p>Um exemplo desses abusos é o caso do software kio-gdrive, que era amplamente utilizado para integrar o Google Drive ao explorador de arquivos do KDE, um ambiente para sistemas Linux. O software foi bloqueado de perguntar para os usuários se eles autorizavam o acesso a sua conta do Google Drive, no lugar do popup de permissão, a Google colocou um aviso informando os usuários que o software legítimo poderia ser malicioso, seguem os relatos dos desenvolvedores:</p>
|
||||
|
||||
<blockquote cite="https://bugs.kde.org/show_bug.cgi?id=480779#c54">"Google bloqueou o nosso acesso a essa função em junho porque não conseguimos explicar o nosso uso da API de forma que eles julgam satisfatória. Por causa disso o sistema de permissões agora está bloqueado [...] tornando 25% das KAccounts KCM não funcionais. Remova as permissões [...] para que pelo menos o restante das integrações funcione (pelo menos em teoria)."</blockquote>
|
||||
|
||||
<blockquote cite="https://bugs.kde.org/show_bug.cgi?id=480779#c54">"É mais que estúpido (na minha humilde opinião) usuários individuais não poderem indicar que eles concordam com um software específico acessando seus dados supostamente sensíveis!"</blockquote>
|
||||
|
||||
<p>Por mais que durante minhas pesquisas eu não tenha achado exatamente quais conversas foram trocadas pelo time de desenvolvedores - e com isso estou dando um grande benefício da dúvida para a Google -, é no mínimo suspeito que a Google não tenha concordado que um software que exerce suas funções primárias dentro do ambiente do Google Drive tem um motivo válido para usufruir do mesmo. Esse não foi um caso único, a Google age nas entrelinhas para controlar o que acontece ou não no Android, como quando apps compilados para versões mais antigas do sistema mostravam um aviso assustador sobre segurança pois mudanças recentes haviam colocado mais barreiras no sistema de permissões, porém os apps antigos não tinham suporte a elas. Um aviso sobre as permissões que seriam dadas ao aplicativo instalado, enfatizando que elas teriam que ser dadas ao aplicativo por ele não suportar as permissões opcionais é razoável, entretanto a mensagem exibida foi bem mais vaga do que deveria ser, o que convenientemente serviu para assustar os usuários que experimentavam sideloading e ajudou a manter o monopólio da Google Play Store.</p>
|
||||
|
||||
<p>Falando em avisos assustadores, chegou a hora de falar do Play Protect, um software embutido na Google Play Store que escaneia os apps instalados no seu dispositivo via sideloading e retorna o resultado para a base de dados da Google, uma ideia boa a primeira vista, levando em conta que a empresa respeita a escolha do usuário com o modelo <i>opt-in</i>, questionando o mesmo se ele gostaria de enviar seus apps instalados para a análise. O grande problema aparece quando a diferença entre as mensagens de detecção de malware e as que são acionadas pelo simples fato do software estar desatualizado é tão turva que causa dois efeitos graves, que juntos tornam o serviço de proteção da Google praticamente inútil para o usuário, enquanto mantém o monopólio da Google.</p>
|
||||
|
||||
<p>Suponhamos que você está experimentando sideloading pela primeira vez: você tenta instalar uma versão antiga de um software que você gosta. Você recebe a mensagem exacerbada sobre os supostos perigos de instalar o software desatualizado, desiste da instalação e instala a versão atual pela Google Play Store. Assim a Google força, mesmo que indiretamente, mais um usuário a usar sua loja, garantindo os lucrativos 30% de taxa nas transações dos apps.</p>
|
||||
|
||||
<p>Agora apresento um segundo cenário hipotético: você é um usuário mais avançado do sistema Android que tem total noção do que se trata o sideloading e adora instalar seus aplicativos de código aberto por fora da Play Store. Porém você clica em um link duvidoso e baixa um arquivo APK malicioso. Na hora de instalar você recebe o aviso do Play Protect, mas ele é tão frequente e exagerado - até mesmo quando nenhum malware foi detectado - que você acaba dispensando-o por já estar acostumado a ter que fazer isso (isso quando o usuário já não desativou ele nas configurações da Play Store). Agora o usuário tem um malware em seu dispositivo, o Play Protect foi inútil.</p>
|
||||
|
||||
<p>Em certas situações baixar um software por fora da loja da Google é a única opção, pois existem casos onde o desenvolvedor não quer publicar seu app na Play Store, tanto por questões de privacidade - já que os desenvolvedores são forçados a revelar certos dados pessoais para o público quando publicam seus apps -, quanto pela taxa imposta na publicação e vendas internas do aplicativo, que pode afastar desenvolvedores sustentados puramente por doações dos usuários. Pouco importa o motivo, os usuários devem ser livres para escolher o que roda em seus dispositivos.</p>
|
||||
|
||||
<p>De acordo com as informações disponibilizadas até agora, os desenvolvedores não precisarão tornar seus dados públicos caso optem por não distribuir sua aplicação na Play Store, e isso é o mínimo que a Google poderia fazer para tornar as novas políticas de distribuição mais justas para os desenvolvedores. A empresa também afirma que essa verificação não tem o objetivo de verificar o que há dentro da aplicação ou sua finalidade, portanto estaria sendo imposta puramente para barrar a distribuição contínua de malwares, resta ver se a afirmação se sustenta, tendo em vista que isso também pode ser uma ferramenta de abuso de poder conveniente para a Google, como outras serviram nos exemplos citados acima.</p>
|
||||
|
||||
<h2>Próximos passos</h2>
|
||||
|
||||
<p>Devemos ficar atentos a como essas novas políticas vão ser aplicadas, e como as mesmas afetarão o ecossistema do Android. Uma consequência inevitável das mudanças é que um número inestimável de aplicações abandonadas pelos desenvolvedores, que - se não fosse pelos novos requisitos - seriam perfeitamente funcionais serão perdidas de um dia para o outro. Nem todo software antigo se conecta à internet, nem todo software antigo representa um perigo constante ao usuário. A Google está tirando do usuário experiente a opção de assumir a responsabilidade e dizer: "Eu sei o que estou fazendo!", nos segurando como crianças, como se soubessem o que é melhor para todos.</p>
|
||||
|
||||
<p>O Android comercializado nos celulares é baseado no <abbr title="Android Open Source Project">AOSP</abbr>, o que significa que a força vital do Android é aberta, e isso a Google ainda não tirou dos usuários. Portanto pretendo fazer um outro post explicando como você pode recuperar o controle do seu dispositivo por meio de modificações no sistema, da forma mais simples, segura e estável possível, até as formas mais avançadas, caso você se sinta confiante.</p>
|
||||
</article>
|
||||
</main>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -1,80 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="pt">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Adrian Victor</title>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<link rel="stylesheet" href="/static/main.css?fixcache=1">
|
||||
<script src="/static/scripts/ccd.js"></script>
|
||||
<script src="/static/scripts/main.js" defer></script>
|
||||
<link rel="apple-touch-icon" sizes="180x180" href="/static/apple-touch-icon.png">
|
||||
<link rel="icon" type="image/png" sizes="32x32" href="/static/favicon-32x32.png">
|
||||
<link rel="icon" type="image/png" sizes="16x16" href="/static/favicon-16x16.png">
|
||||
<link rel="manifest" href="/static/site.webmanifest">
|
||||
<script src="https://keepandroidopen.org/banner.js" defer></script>
|
||||
</head>
|
||||
<body>
|
||||
<style>
|
||||
.bg {
|
||||
opacity: .4!important;
|
||||
}
|
||||
</style>
|
||||
<div id="everythingHelper">
|
||||
<img src="/static/images/bear.jpg" class="bg">
|
||||
<header>
|
||||
<div>
|
||||
<h1>Adrian Victor:Blog</h1>
|
||||
<a id="headerSubtitle"><i>Fanasy is not a crime, find your castle in the sky.</i></a>
|
||||
<script>
|
||||
const headeri18n =
|
||||
{
|
||||
by: "por",
|
||||
options: "Options",
|
||||
hideBackground: "Esconder imagem de fundo",
|
||||
back: "voltar"
|
||||
}
|
||||
</script>
|
||||
</div>
|
||||
<div id="linksHelper">
|
||||
<div id="music">
|
||||
</div>
|
||||
<ul id="headerLinks">
|
||||
<a href="/pt/">início</a>
|
||||
<a href="/pt/blog/">blog</a>
|
||||
</ul>
|
||||
</div>
|
||||
</header>
|
||||
<div id="mainHelper">
|
||||
|
||||
<main>
|
||||
<p><b>Listando Postagens do Blog:</b></p>
|
||||
<ul>
|
||||
|
||||
|
||||
|
||||
|
||||
<li>
|
||||
<p>
|
||||
<a href="/posts/verificacao-de-desenvolvedor-no-android/">Sobre as recentes mudanças nos requisitos de distribuição de apps no sistema Android feitas pela Google.</a><br>
|
||||
Fri Aug 29 2025 21:00:00 GMT-0300 (Brasilia Standard Time)
|
||||
</p>
|
||||
</li>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<li>
|
||||
<p>
|
||||
<a href="/posts/telnet-pt/">Telnet</a><br>
|
||||
Tue Aug 26 2025 21:00:00 GMT-0300 (Brasilia Standard Time)
|
||||
</p>
|
||||
</li>
|
||||
|
||||
|
||||
</ul>
|
||||
</main>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -1,149 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="pt">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Adrian Victor</title>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<link rel="stylesheet" href="/static/main.css?fixcache=1">
|
||||
<script src="/static/scripts/ccd.js"></script>
|
||||
<script src="/static/scripts/main.js" defer></script>
|
||||
<link rel="apple-touch-icon" sizes="180x180" href="/static/apple-touch-icon.png">
|
||||
<link rel="icon" type="image/png" sizes="32x32" href="/static/favicon-32x32.png">
|
||||
<link rel="icon" type="image/png" sizes="16x16" href="/static/favicon-16x16.png">
|
||||
<link rel="manifest" href="/static/site.webmanifest">
|
||||
<script src="https://keepandroidopen.org/banner.js" defer></script>
|
||||
</head>
|
||||
<body>
|
||||
<style>
|
||||
.bg {
|
||||
opacity: .4!important;
|
||||
}
|
||||
</style>
|
||||
<div id="everythingHelper">
|
||||
<img src="/static/images/bear.jpg" class="bg">
|
||||
<header>
|
||||
<div>
|
||||
<h1>Adrian Victor</h1>
|
||||
<a id="headerSubtitle"><i>Fanasy is not a crime, find your castle in the sky.</i></a>
|
||||
<script>
|
||||
const headeri18n =
|
||||
{
|
||||
by: "por",
|
||||
options: "Options",
|
||||
hideBackground: "Esconder imagem de fundo",
|
||||
back: "voltar"
|
||||
}
|
||||
</script>
|
||||
</div>
|
||||
<div id="linksHelper">
|
||||
<div id="music">
|
||||
</div>
|
||||
<ul id="headerLinks">
|
||||
<a href="/pt/">início</a>
|
||||
<a href="/pt/blog/">blog</a>
|
||||
</ul>
|
||||
</div>
|
||||
</header>
|
||||
<div id="mainHelper">
|
||||
|
||||
<div id="homeSquares">
|
||||
</div>
|
||||
<main>
|
||||
<script src="/static/scripts/home.js" defer></script>
|
||||
<noscript><style>
|
||||
.hs {
|
||||
display: unset!important;
|
||||
}
|
||||
#homeSquares {
|
||||
display: none;
|
||||
}
|
||||
</style></noscript>
|
||||
<div class="hs" id="hsDefault">
|
||||
<h1 id="homeTitle">Bem-vindo</h1>
|
||||
<p>Parece que você encontrou meu website! Olá, sou <b>Adrian Victor</b> (ou <b>tenkuma</b>), um cara brasileiro que gosta de mexer com computadores, programas de computadores e <i>enimatpirtlitemídios</i>.</p>
|
||||
<h2>Redes Sociais e Contato</h2>
|
||||
<p>
|
||||
Estou publicamente disponível no Mastodon <a href='https://mstdn.social/@tenkuma'>(@tenkuma@mstdn.social)</a>,
|
||||
GitHub <a href='https://github.com/adrianvic'>(adrianvic)</a>,
|
||||
Disroot Git <a href='https://git.disroot.org/adrianvictor'>(adrianvictor)</a>,
|
||||
Discord <a href='https://discord.com/users/681643259764015116'>(@adrianvic)</a>,
|
||||
YouTube <a href='https://www.youtube.com/@adrianvictor8'>(@adrianvictor8)</a>,
|
||||
BitView <a href='https://www.bitview.net/user/tenkuma'>(tenkuma)</a>,
|
||||
Modrinth <a href='https://modrinth.com/user/tenkumabear'>(tenkumabear)</a>
|
||||
e XMPP <a href='xmpp:adrianvictor@disroot.org'>(adrianvictor@disroot.org)</a>.
|
||||
</p>
|
||||
<p>Você pode me enviar um correio eletrônico para <a href="mailto:adrianvictor@disroot.org">(adrianvictor@disroot.org)</a> ou me contactar por qualquer outro meio citado acima. Para assuntos relativos a projetos específicos, verifique o campo de contato do projeto, caso não haja um adicione <i>+nomedoprojeto</i> ao meu endereço de E-mail (exemplo: adrianvictor+projetolegal@disroot.org).</p>
|
||||
<p><i><b>Por favor, evite me contactar por meios não citados acima :)</b></i></p>
|
||||
</div>
|
||||
<div class="hs" id="hsMusic">
|
||||
<h1>Música</h1>
|
||||
<p>Eu e meus amigos temos uma gravadora de música amadora chamada <span class="margarinaColor">Margarina Records</span>, as coisas andam devagar com meus projetos musicais, geralmente por causa da escola ou falta de conhecimento no campo, mas eu estou dando um jeito.</p>
|
||||
<p>Você pode conferir minhas músicas mais recentes no <a href="https://margarina-records.rf.gd">site da gravadora</a> e no <a href="https://genius.com/tenkuma">Genius</a>. Você provavelmente vai gostar do trabalho dos outros membros, então dê uma olhada nas outras tracks da MGR.</p>
|
||||
</div>
|
||||
<div class="hs" id="hsVideo">
|
||||
<h1>Vídeos</h1>
|
||||
<p>Eu tenho um canal no YouTube em que na maioria das vezes eu posto vídeos de Minecraft, mas pretendo expandir a variedade de conteúdos no futuro. Não tenho nenhuma previsão de publicação no meu canal, pois editar os vídeos leva tempo e eu tenho pouco tempo para trabalhar nos meus projetos, você deveria se inscrever se quiser saber quando eu posto meus vídeos!</p>
|
||||
<p>Aqui está um vídeo aleatório que eu me orgulho de ter postado:</p>
|
||||
<a href="https://youtu.be/tZLoSxzsfpM" id="youtubeVideo">
|
||||
<img src="/static/images/youtube_video.jpg" alt="" id="youtubeVideoImage">
|
||||
<p>Como usar o MCA Selector para juntar mundos do Minecraft Java!</p>
|
||||
</a>
|
||||
</div>
|
||||
<div class="hs" id="hsCode">
|
||||
<h1>Software</h1>
|
||||
<p>Estou estudando informática no IFC (SC, Brazil) mas no meu tempo livre tenho projetos como programas de computador, plugins para Minecraft, servidores Minecraft, etc... Todos meus projetos públicos estão disponíveis no meu <a href="https://github.com/adrianvic">perfil do GitHub</a>.</p>
|
||||
|
||||
<div class="hsProjects">
|
||||
<div class="hsProject">
|
||||
<div class="hsProjectHeader">
|
||||
<div class="hsProjectImage"><img src="/static/images/jamfish-wide.png" alt="Um desenho digital do topo de um garfo com uma borda preta, à direita um texto branco diz 'Pesto Wiki'"></div>
|
||||
<a href="https://github.com/adrianvic/jamfish" class="hsProjectHeaderIcon">
|
||||
<img src="/static/visual/github.svg" class="invertedc">
|
||||
</a>
|
||||
</div>
|
||||
<div class="hsProjectContent">
|
||||
<p>Reprodutor de música nativo para dispositivos Android que se conecta a servidores de mídia Jellyfin. O código é baseado no repositório arquivado do Gelli, que por sua vez se baseia em uma versão antiga do Phonograph.</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="hsProject">
|
||||
<div class="hsProjectHeader">
|
||||
<div class="hsProjectImage"><img src="/static/images/eye_of_nemesis.png" alt=""></div>
|
||||
<a href="https://github.com/adrianvic/NemesisEye" class="hsProjectHeaderIcon">
|
||||
<img src="/static/visual/github.svg" class="invertedc">
|
||||
</a>
|
||||
</div>
|
||||
<div class="hsProjectContent">
|
||||
<p>Eye of Nemesis é um plugin que permite aos administradores de servidores escrever políticas que negarão ou permitirão (lista negra/branca) que os jogadores façam coisas específicas com base no valor dos nós.</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="hsProject">
|
||||
<div class="hsProjectHeader">
|
||||
<div class="hsProjectImage"><img src="/static/images/itemeconomy2-wide.png" alt=""></div>
|
||||
<a href="https://github.com/adrianvic/ItemEconomy" class="hsProjectHeaderIcon">
|
||||
<img src="/static/visual/github.svg" class="invertedc">
|
||||
</a>
|
||||
</div>
|
||||
<div class="hsProjectContent">
|
||||
<p>Este plugin PaperMC integra-se ao VaultUnlocked para fornecer um sistema de economia único baseado em itens para o seu servidor Minecraft. Em vez de depender apenas de saldos virtuais, os jogadores usam itens do jogo como moeda física, adicionando uma camada de imersão e realismo à sua economia.</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="hsProject">
|
||||
<div class="hsProjectHeader">
|
||||
<div class="hsProjectImage"><img src="/static/images/pestowikifullwhite.png" alt=""></div>
|
||||
<a href="https://github.com/Margarina-not-butter/PestoWiki" class="hsProjectHeaderIcon">
|
||||
<img src="/static/visual/github.svg" class="invertedc">
|
||||
</a>
|
||||
</div>
|
||||
<div class="hsProjectContent">
|
||||
<p>Cliente personalizável multiplataforma para wikis escrito em Python usando PySide6 (QT).</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -1,179 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="pt">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Adrian Victor - Demonstração da API do Prof. Rodrigo Ribeiro</title>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<link rel="stylesheet" href="/static/main.css?fixcache=1">
|
||||
<script src="/static/scripts/ccd.js"></script>
|
||||
<script src="/static/scripts/main.js" defer></script>
|
||||
<link rel="apple-touch-icon" sizes="180x180" href="/static/apple-touch-icon.png">
|
||||
<link rel="icon" type="image/png" sizes="32x32" href="/static/favicon-32x32.png">
|
||||
<link rel="icon" type="image/png" sizes="16x16" href="/static/favicon-16x16.png">
|
||||
<link rel="manifest" href="/static/site.webmanifest">
|
||||
<script src="https://keepandroidopen.org/banner.js" defer></script>
|
||||
</head>
|
||||
<body>
|
||||
<style>
|
||||
.bg {
|
||||
opacity: .4!important;
|
||||
}
|
||||
</style>
|
||||
<div id="everythingHelper">
|
||||
<img src="/static/images/bear.jpg" class="bg">
|
||||
<header>
|
||||
<div>
|
||||
<h1>Adrian Victor:Trabalhos</h1>
|
||||
<a id="headerSubtitle"><i>Fanasy is not a crime, find your castle in the sky.</i></a>
|
||||
<script>
|
||||
const headeri18n =
|
||||
{
|
||||
by: "por",
|
||||
options: "Options",
|
||||
hideBackground: "Esconder imagem de fundo",
|
||||
back: "voltar"
|
||||
}
|
||||
</script>
|
||||
</div>
|
||||
<div id="linksHelper">
|
||||
<div id="music">
|
||||
</div>
|
||||
<ul id="headerLinks">
|
||||
<a href="/pt/">início</a>
|
||||
<a href="/pt/blog/">blog</a>
|
||||
</ul>
|
||||
</div>
|
||||
</header>
|
||||
<div id="mainHelper">
|
||||
<style>
|
||||
#mainAPI, #login {
|
||||
display: none;
|
||||
}
|
||||
|
||||
#mainAPI.selected, #login.selected {
|
||||
display: flex;
|
||||
}
|
||||
</style>
|
||||
<div style="display: flex; gap: 1em; flex-direction: column;">
|
||||
<h1>Demonstração da API do Prof. Rodrigo Ribeiro</h1>
|
||||
<p>A API do Prof. Rodrigo Ribeiro permite que o <i>client</i> envie uma imagem, assim retornando o resultado de uma leitura óptica realizada sobre a mesma com inteligência artificial. Esse client lê o resultado e o mostra de forma simples para o usuário.</p>
|
||||
<p><a href="https://api.rodrigoribeiro.net/doc">Mais informações sobre a API podem ser encontradas no seu website.</a></p>
|
||||
<div id="token">Token: Ausente</div>
|
||||
<div id="login" class="selected" style="flex-direction: column; gap: .6em;">
|
||||
<input type="text" id="username" placeholder="E-mail">
|
||||
<input type="password" id="password" placeholder="Senha">
|
||||
<div>
|
||||
<button id="submit">Logar</button>
|
||||
<button id="submitb">Criar Usuário</button>
|
||||
</div>
|
||||
</div>
|
||||
<div id="mainAPI" style="flex-direction: column; gap: 1em;">
|
||||
<div style="display: flex; flex-direction: column; gap: .6em;">
|
||||
<input type="file" id="file">
|
||||
<div>
|
||||
<button id="submitImage">Enviar imagem.</button>
|
||||
<button id="logout">Deletar token</button>
|
||||
</div>
|
||||
</div>
|
||||
<div id="imageResults">
|
||||
<p>Resultados da leitura óptica:</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script>
|
||||
const usernameInput = document.getElementById('username');
|
||||
const passwordInput = document.getElementById('password');
|
||||
const tokenLabel = document.getElementById('token');
|
||||
const submitButton = document.getElementById('submit');
|
||||
const cuButton = document.getElementById('submitb');
|
||||
const fileEl = document.getElementById('file');
|
||||
const submitImageButton = document.getElementById('submitImage');
|
||||
const imageResults = document.getElementById("imageResults");
|
||||
const loginDiv = document.getElementById("login");
|
||||
const apiDiv = document.getElementById("mainAPI");
|
||||
const logoutButton = document.getElementById("logout");
|
||||
|
||||
let token = '';
|
||||
|
||||
async function api(endpoint, data) {
|
||||
const info = {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'Authorization': `Bearer ${token}`
|
||||
},
|
||||
body: JSON.stringify(data),
|
||||
}
|
||||
let res = await fetch(`https://api.rodrigoribeiro.net/${endpoint}`, info);
|
||||
res = await res.json()
|
||||
console.log(res)
|
||||
return res;
|
||||
}
|
||||
|
||||
function login(username, password, createAccount = false) {
|
||||
return api(createAccount ? "registrar" : "login", { email: username, senha: password });
|
||||
}
|
||||
|
||||
submitButton.addEventListener('click', async () => {
|
||||
if (!usernameInput.value && !passwordInput.value) {
|
||||
alert("Preencha os campos necessários.")
|
||||
return;
|
||||
}
|
||||
res = await login(usernameInput.value, passwordInput.value);
|
||||
const is_logged = (res.status_code == 200);
|
||||
if (is_logged) {
|
||||
token = res.response.token;
|
||||
toggleDivsVisibility();
|
||||
}
|
||||
tokenLabel.innerHTML = `Token: ${is_logged ? 'Presente' : 'Ausente (erro de autenticação)'}`;
|
||||
})
|
||||
|
||||
cuButton.addEventListener('click', async () => {
|
||||
if (!usernameInput.value && !passwordInput.value) {
|
||||
alert("Preencha os campos necessários.")
|
||||
return;
|
||||
}
|
||||
res = await login(usernameInput.value, passwordInput.value, true);
|
||||
const is_logged = (res.status_code == 201);
|
||||
tokenLabel.innerHTML = `Token: ${is_logged ? 'Ausente (conta criada e pronta para logar)' : 'Ausente (erro ao criar usuário)'}`;
|
||||
})
|
||||
|
||||
submitImageButton.addEventListener('click', async () => {
|
||||
const file = fileEl.files[0];
|
||||
if (!file) return;
|
||||
|
||||
const fr = new FileReader();
|
||||
fr.onload = async () => {
|
||||
const dataUrl = fr.result;
|
||||
const base64 = dataUrl.split(',')[1];
|
||||
const res = await api('detectar', {
|
||||
"image": base64,
|
||||
"preview": true
|
||||
})
|
||||
|
||||
imageResults.innerHTML = "";
|
||||
|
||||
res.response.objects.forEach(object => {
|
||||
let resultsEntry = document.createElement("p");
|
||||
resultsEntry.innerHTML = `<i>${object.class}</i> detectado com confiança de ${object.score * 100}%`
|
||||
imageResults.appendChild(resultsEntry);
|
||||
});
|
||||
};
|
||||
fr.readAsDataURL(file);
|
||||
});
|
||||
|
||||
logout.addEventListener('click', () => {
|
||||
token = "";
|
||||
toggleDivsVisibility();
|
||||
tokenLabel.innerText = "Token: Ausente"
|
||||
})
|
||||
|
||||
function toggleDivsVisibility() {
|
||||
apiDiv.classList.toggle('selected');
|
||||
loginDiv.classList.toggle('selected');
|
||||
}
|
||||
</script>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -1,138 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="pt">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Adrian Victor - Guia para novatos no IFC.</title>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<link rel="stylesheet" href="/static/main.css?fixcache=1">
|
||||
<script src="/static/scripts/ccd.js"></script>
|
||||
<script src="/static/scripts/main.js" defer></script>
|
||||
<link rel="apple-touch-icon" sizes="180x180" href="/static/apple-touch-icon.png">
|
||||
<link rel="icon" type="image/png" sizes="32x32" href="/static/favicon-32x32.png">
|
||||
<link rel="icon" type="image/png" sizes="16x16" href="/static/favicon-16x16.png">
|
||||
<link rel="manifest" href="/static/site.webmanifest">
|
||||
<script src="https://keepandroidopen.org/banner.js" defer></script>
|
||||
</head>
|
||||
<body>
|
||||
<style>
|
||||
.bg {
|
||||
opacity: 0.35!important;
|
||||
}
|
||||
</style>
|
||||
<div id="everythingHelper">
|
||||
<img src="/static/images/ifc.jpg" class="bg">
|
||||
<header>
|
||||
<div>
|
||||
<h1>Adrian Victor:Escola</h1>
|
||||
<a id="headerSubtitle"><i>Fanasy is not a crime, find your castle in the sky.</i></a>
|
||||
<script>
|
||||
const headeri18n =
|
||||
{
|
||||
by: "por",
|
||||
options: "Options",
|
||||
hideBackground: "Esconder imagem de fundo",
|
||||
back: "voltar"
|
||||
}
|
||||
</script>
|
||||
</div>
|
||||
<div id="linksHelper">
|
||||
<div id="music">
|
||||
</div>
|
||||
<ul id="headerLinks">
|
||||
<a href="/pt/">início</a>
|
||||
<a href="/pt/blog/">blog</a>
|
||||
</ul>
|
||||
</div>
|
||||
</header>
|
||||
<div id="mainHelper">
|
||||
<main>
|
||||
<article>
|
||||
<div id="postHeader">
|
||||
<h1>Guia para novatos no IFC.</h1>
|
||||
<p>Adrian Victor - Mon Jan 12 2026 21:00:00 GMT-0300 (Brasilia Standard Time)</p>
|
||||
</div>
|
||||
<style>
|
||||
.screenshotBox img {
|
||||
margin: auto;
|
||||
max-width: 80%;
|
||||
box-shadow:
|
||||
2px 7px 5px rgba(0,0,0,0.4),
|
||||
0px -4px 10px rgba(0,0,0,0.4);
|
||||
border: medium solid white
|
||||
}
|
||||
|
||||
.screenshotBox {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 1em;
|
||||
margin: 2em 0;
|
||||
}
|
||||
|
||||
.screenshotBox p {
|
||||
text-align: center;
|
||||
}
|
||||
</style>
|
||||
<p>Antes de tudo, quero dar boas vindas a qualquer novato que esteja lendo esse documento, o IF é uma grande oportunidade que felizmente você não deixou passar! Não vou me extender muito nesse tópico pois tenho certeza que vocês vão ouvir depoimentos de ex-alunos bem-sucedidos ao longo do período letivo.</p>
|
||||
<p>Estou organizando esse documento para evitar que os veteranos tenham que explicar tudo para cada novato que apresentar a mesma dúvida, centralizando o conteúdo para facilitar quando você dá aquela esquecida sobre como algo funciona. Ao mesmo tempo, não quero que ele substitua o contato que você poderia ter com um veterano, não deixe de conversar e fazer novas amizades!</p>
|
||||
<p>Para correções ou dúvidas que não sanei aqui, você pode me mandar um e-mail (adrianvictor@disroot.org) ou me contactar por qualquer outro lugar que você conseguir, vou corrigir/adicionar o mais rápido possível. Caso algum veterano se interesse em escrever algo para complementar essa postagem, fico feliz em adicionar seu texto ou link aqui.</p>
|
||||
|
||||
<h2>O SIGAA</h2>
|
||||
<p>SIGAA (Sistema Integrado Para Ferrar com os Alunos) vai ser o lugar onde você vê as suas notas, frequências, aplica para auxílios e entrega trabalhos – caso você encontre um professor que ainda tem sanidade pra usar essa coisa além do que se faz obrigatório.</p>
|
||||
<p>Ofensas à parte, vamos dar uma olhada nas partes importantes do sistema.</p>
|
||||
<h3>Login e cadastro</h3>
|
||||
<div class="screenshotBox">
|
||||
<img class="screenshotImg" src="/static/images/sigaa-login.png" alt="">
|
||||
<p>1 - Tela de login do SIGAA.</p>
|
||||
</div>
|
||||
<p>Após acessar o site do SIGAA, você deve ver a tela de login mostrada na imagem. Antes de tudo, verifique se você está no SIGAA dos alunos.<sup>(1.1)</sup></p>
|
||||
<p>Caso você tenha um login, o acesso é bem simples, apenas preencha os campos de usuário e senha<sup>(1.2)</sup> e confirme. O login expira em 1 minuto de inatividade.</p>
|
||||
|
||||
<p>No caso de você não possuir um cadastro, use o link abaixo da tela de login<sup>(1.3)</sup> para abrir o formulário de cadastro.</p>
|
||||
|
||||
<h3>Tela Principal</h3>
|
||||
<div class="screenshotBox">
|
||||
<img src="/static/images/sigaa-inicio.png" alt="">
|
||||
<p>2 - Tela inicial do SIGAA</p>
|
||||
</div>
|
||||
|
||||
<p>A tela principal do SIGAA é uma bagunça, mas você não vai usar nem metade do que tem nela, por isso vamos dar uma olhada somente nas funcionalidades principais dela.</p>
|
||||
|
||||
<p>No cabeçalho<sup>(2.1)</sup> você tem acesso a coisas como boletim, atestado de frequência, etc... Também é o lugar que você gerencia seus auxílios.</p>
|
||||
|
||||
<p>É possível gerenciar seu perfil público e dados na barra lateral<sup>(2.2)</sup>, assim como acessar alguns links úteis (como o da biblioteca digital). O seu perfil fica visível em postagens e respostas enviadas no forum do SIGAA.<sup>(2.6)</sup> Por algum motivo, minha foto de perfil some toda hora, já não me dou mais o trabalho de colocar de volta.</p>
|
||||
|
||||
<p>Não cadastre um e-mail que você usa com frequência no SIGAA, pois ele vai entupir sua caixa de entrada com SPAM. E os e-mails que seriam úteis chegam tão tarde que perdem a utilidade (já recebemos e-mail sobre cancelamento de aulas com um mês de atraso). Se você quiser manter seu e-mail pessoal no SIGAA, já que eles realmente mandam alguma coisa importante uma vez ou outra por ano, configure um filtro para o endereço do IF (ifc.edu.br) que joga todos os e-mails do SIGAA para uma caixa diferente no seu e-mail.</p>
|
||||
|
||||
<p>Continuando, chegamos na lista de matérias do seu ano letivo<sup>(2.5)</sup>, você vai usar ela para acessar a <a href="#página-da-matéria">página da matéria.</a></p>
|
||||
|
||||
<p>E por fim, temos o forum<sup>(2.6)</sup>, que eu incluí por dó, pois ninguém nunca usa ele. Em teoria ele serve para alunos tirarem suas dúvidas e/ou buscarem ajuda sobre algum tópico relevante do curso, mas acabou que ele virou uma bagunça empoierada que quase não tem atividade nenhuma.</p>
|
||||
|
||||
<h3>Página da Matéria</h3>
|
||||
<div class="screenshotBox">
|
||||
<img src="/static/images/sigaa-materia.png" alt="">
|
||||
<p>3 - Página da matéria no SIGAA</p>
|
||||
</div>
|
||||
|
||||
<p>Essa é, provavelmente, a página que você mais vai usar do SIGAA, ela mostra todas as atividades do ano na lista principal<sup>(3.2)</sup>. Essa lista vai ficando mais bagunçada ao decorrer do ano, ela mostra as atividades das mais antigas para as mais novas, portanto quando o ano passar e o(a) professor(a) adicionar muitas atividades, você vai ter que rolar até o final para achar a mais recente. Se o seu professor adicionar atividades futuras na lista, você também terá que procurar a desse dia.</p>
|
||||
|
||||
<p>O Menu da Turma Virtual<sup>(3.1)</sup> também é importantíssimo, e dessa vez não tenho muito o que dizer, ele funciona como um menu. Os itens que você mais vai usar são <i>Alunos > Frequência</i> para ver sua frequência nessa matéria e <i>Alunos > Ver notas</i>, que mostra suas notas individuais dessa matéria, até mesmo as que não aparecem no boletim ainda.</p>
|
||||
|
||||
<p>Na barra lateral da direita<sup>(3.3)</sup> você encontra o andamento das aulas, que é a quantidade de aulas ministradas em relação ao total. O número de aulas ministradas pode exceder o número de aulas totais, porém as excedentes não vão afetar a sua média de faltas. Também tem algumas outras caixas de notícias, enquetes, atividades, avaliações e forum, mas nenhuma é usada com frequência.</p>
|
||||
|
||||
<p>Vale ressaltar que no celular é difícil rolar a página quando você dá zoom, para resolver isso você precisa rolar (arrastar) no Menu da Turma Virtual, porque na lista principal vai rolar apenas a lista de atividades.</p>
|
||||
|
||||
<h2>Frequência</h2>
|
||||
<p>As frequências são contabilizadas pela chamada que os professores fazem no começo da aula. Eventos como a FICE e OLINCAC também contam presença e geralmente um professor fica encarregado de fazer a chamada da manhã, enquanto outro fica na tarde (é bem fácil pegar a chamada da manhã/tarde e ir embora).</p>
|
||||
<p>O aluno não pode exceder em faltas 25% do total de aulas e o limite por matéria do SIGAA não conta no boletim, portanto se você exceder ele sem ultrapassar o limite total, você ainda passa. As matérias optativas são uma excessão, com essas você precisa tomar cuidado para não atingir o limite de faltas.</p>
|
||||
<p>Por mais que o limite esteja entorno de 300 faltas, não recomendo que se acostume a faltar, pois temos 9 aulas por dia, ou seja, 9 faltas. Até as faltas em aulas específicas somam rápido.</p>
|
||||
|
||||
<h2>Referências</h2>
|
||||
<ul>
|
||||
<li><a href="https://desciclopedia.ws/wiki/Cambori%C3%BA#Instituto_CannabialFederal_Catarinense">https://desciclopedia.ws/wiki/Cambori%C3%BA#Instituto_CannabialFederal_Catarinense</a></li>
|
||||
</ul>
|
||||
</article>
|
||||
</main>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
BIN
docs/static/android-chrome-192x192.png
vendored
|
Before Width: | Height: | Size: 7.3 KiB |
BIN
docs/static/android-chrome-512x512.png
vendored
|
Before Width: | Height: | Size: 22 KiB |
BIN
docs/static/apple-touch-icon.png
vendored
|
Before Width: | Height: | Size: 6.6 KiB |
BIN
docs/static/favicon-16x16.png
vendored
|
Before Width: | Height: | Size: 531 B |
BIN
docs/static/favicon-32x32.png
vendored
|
Before Width: | Height: | Size: 968 B |
BIN
docs/static/favicon.ico
vendored
|
Before Width: | Height: | Size: 15 KiB |
4
docs/static/images/8thNote.svg
vendored
|
|
@ -1,4 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" version="1.0" width="90" height="90">
|
||||
<path d="M 23.7,87.9 C 18.1,82.8 21.2,74.7 30.4,69.9 C 33.5,68.4 35.8,67.7 39.8,67.8 C 42.3,67.9 45.1,69.3 45.1,69.3 C 45.1,51.2 45.0,17.0 45.0,0.2 C 46.0,0.2 46.7,0.1 48.1,0.1 C 48.1,1.1 48.1,1.9 48.1,2.7 C 48.1,3.6 48.1,4.1 48.2,4.7 C 49.2,11.0 50.6,13.5 57.6,21.2 C 66.5,31.1 69.1,37.0 69.1,44.9 C 69.0,52.3 62.5,68.1 61.1,67.5 C 63.1,61.9 65.9,55.9 66.6,50.9 C 67.5,44.8 65.0,36.2 61.0,31.7 C 57.8,27.9 50.2,24.6 48.1,24.6 C 48.1,24.6 48.0,61.0 48.0,74.8 C 48.0,77.1 45.9,81.2 44.7,82.6 C 39.2,89.2 28.5,92.2 23.7,87.9 z"/>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 669 B |
BIN
docs/static/images/android-jellybean.jpg
vendored
|
Before Width: | Height: | Size: 134 KiB |
BIN
docs/static/images/androidrecovery.jpg
vendored
|
Before Width: | Height: | Size: 40 KiB |
2
docs/static/images/arrow-cursor.svg
vendored
|
|
@ -1,2 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?><!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
|
||||
<svg width="800px" height="800px" viewBox="0 0 512 512" xmlns="http://www.w3.org/2000/svg"><path fill="#000000" d="M123.193 29.635L121 406.18l84.31-82.836 65.87 159.02 67.5-27.96-65.87-159.02L391 294.342z"/></svg>
|
||||
|
Before Width: | Height: | Size: 332 B |
BIN
docs/static/images/bear-fade-old.jpg
vendored
|
Before Width: | Height: | Size: 876 KiB |
BIN
docs/static/images/bear-fade.jpg
vendored
|
Before Width: | Height: | Size: 876 KiB |
BIN
docs/static/images/bear.jpg
vendored
|
Before Width: | Height: | Size: 642 KiB |
4
docs/static/images/cameraroll.svg
vendored
|
|
@ -1,4 +0,0 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="48" height="48" viewBox="0 0 48 48">
|
||||
<path d="M0 0h48v48h-48z" fill="none"/>
|
||||
<path d="M28 10c0-2.21-1.79-4-4-4h-2v-2c0-1.1-.9-2-2-2h-8c-1.1 0-2 .9-2 2v2h-2c-2.21 0-4 1.79-4 4v30c0 2.21 1.79 4 4 4h16c2.21 0 4-1.79 4-4h16v-30h-16zm-4 26h-4v-4h4v4zm0-18h-4v-4h4v4zm8 18h-4v-4h4v4zm0-18h-4v-4h4v4zm8 18h-4v-4h4v4zm0-18h-4v-4h4v4z"/>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 391 B |
BIN
docs/static/images/eye_of_nemesis.png
vendored
|
Before Width: | Height: | Size: 11 KiB |
7
docs/static/images/file-code.svg
vendored
|
|
@ -1,7 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!-- Svg Vector Icons : http://www.onlinewebfonts.com/icon -->
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 256 256" enable-background="new 0 0 256 256" xml:space="preserve">
|
||||
<metadata> Svg Vector Icons : http://www.onlinewebfonts.com/icon </metadata>
|
||||
<g><g><g><path fill="#000000" d="M43,11.1l-1.2,1.2V128c0,113.2,0,115.7,0.9,116.8l0.9,1.1H128h84.4l0.9-1.1c0.9-1.1,0.9-3.2,0.9-94.5c0-74.1-0.1-93.6-0.6-94.2c-0.3-0.4-13.7-10.9-29.7-23.3l-29.1-22.6l-55.4-0.1L44.1,10L43,11.1z M149.9,42.9v25.3l1.2,1.1c0.6,0.7,1.6,1.2,2.2,1.2c0.6,0,12.8-1.7,27.1-3.8c14.3-2,26.1-3.6,26.3-3.5c0.2,0.1,0.3,39.6,0.3,87.8v87.6H128H48.9V128.1V17.6h50.5h50.5V42.9z M179.7,39.1c20.6,16,21.7,16.9,20.4,17.2c-0.8,0.2-10.6,1.7-21.8,3.3c-16.5,2.3-20.5,2.8-20.8,2.2c-0.6-0.9-0.5-40,0-39.8C157.8,22.1,167.8,29.8,179.7,39.1z"/><path fill="#000000" d="M139.6,95.7c-0.6,0.2-1.2,0.9-1.5,1.3c-0.9,1.6-23.9,87.9-23.9,89.5c0,3.1,4,4.7,6,2.3c0.7-0.8,4.3-13.6,12.7-44.9c6.5-24.1,11.8-44.4,11.8-45.1C144.7,96.5,141.9,94.8,139.6,95.7z"/><path fill="#000000" d="M84.7,130.3c-10.6,5.9-19.6,11-19.9,11.5c-0.7,0.9-0.8,3.4-0.2,4.3c0.9,1.4,39.6,22.5,41.2,22.5c1.5,0,3-1.4,3.4-3.1c0.5-2-1-3.3-6.7-6.5c-19.2-10.5-26.9-14.9-26.6-15.2c0.2-0.2,7.5-4.2,16.1-9c8.7-4.8,16-8.9,16.3-9.2c1.2-1.1,1.2-3.4,0.1-4.8C106.5,118.3,105.7,118.6,84.7,130.3z"/><path fill="#000000" d="M150,120.8c-1.2,1.6-1.3,3.1-0.1,4.4c0.4,0.6,6.3,4,13,7.6c13.7,7.5,19.1,10.5,19.6,11c0.2,0.2-6.7,4.2-15.2,8.9c-8.6,4.7-16.2,9.2-17,9.9c-1.1,1.1-1.3,1.6-1,2.9c0.3,1.8,1.9,3.2,3.5,3.2c1.2,0,38.6-20.4,40.5-22.1c1.3-1.2,1.4-3.6,0.2-5c-0.9-1-9.3-5.8-29.1-16.5C153.1,119,151.7,118.6,150,120.8z"/></g></g></g>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 1.8 KiB |
36
docs/static/images/gears.svg
vendored
|
|
@ -1,36 +0,0 @@
|
|||
<?xml version="1.0" encoding="iso-8859-1"?>
|
||||
<!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg fill="#000000" version="1.1" id="Capa_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
width="800px" height="800px" viewBox="0 0 30.998 30.998"
|
||||
xml:space="preserve">
|
||||
<g>
|
||||
<g>
|
||||
<path d="M18.73,16.686l-1.713-0.205c-0.176-0.654-0.433-1.271-0.763-1.844l1.063-1.354c0.164-0.209,0.145-0.531-0.043-0.718
|
||||
l-1.766-1.767c-0.187-0.187-0.509-0.206-0.717-0.044l-1.356,1.067c-0.571-0.33-1.188-0.587-1.841-0.761L11.39,9.345
|
||||
c-0.031-0.262-0.273-0.477-0.537-0.477H8.354c-0.264,0-0.506,0.215-0.537,0.477l-0.206,1.714
|
||||
c-0.653,0.174-1.271,0.432-1.842,0.762l-1.357-1.065c-0.207-0.163-0.53-0.145-0.716,0.042l-1.767,1.769
|
||||
c-0.187,0.187-0.206,0.509-0.043,0.717l1.065,1.354c-0.331,0.572-0.586,1.19-0.761,1.844l-1.713,0.205
|
||||
C0.215,16.718,0,16.959,0,17.225v2.498c0,0.265,0.215,0.506,0.477,0.536l1.714,0.207c0.175,0.651,0.431,1.269,0.761,1.841
|
||||
l-1.064,1.354c-0.163,0.21-0.144,0.532,0.043,0.719l1.765,1.767c0.186,0.188,0.509,0.207,0.716,0.045l1.357-1.068
|
||||
c0.571,0.33,1.189,0.588,1.842,0.762L7.817,27.6c0.031,0.262,0.273,0.477,0.537,0.477h2.499c0.264,0,0.506-0.215,0.537-0.477
|
||||
l0.206-1.715c0.653-0.174,1.271-0.432,1.843-0.762l1.356,1.064c0.208,0.162,0.53,0.145,0.716-0.041l1.767-1.77
|
||||
c0.187-0.188,0.207-0.51,0.043-0.717l-1.065-1.354c0.331-0.572,0.586-1.19,0.761-1.844l1.715-0.205
|
||||
c0.263-0.031,0.477-0.271,0.477-0.537v-2.498C19.209,16.957,18.994,16.718,18.73,16.686z M9.605,23.271
|
||||
c-2.651,0-4.801-2.148-4.801-4.801c0-2.652,2.15-4.802,4.801-4.802c2.652,0,4.801,2.149,4.801,4.802
|
||||
C14.407,21.123,12.257,23.271,9.605,23.271z"/>
|
||||
<path d="M30.641,8.804L29.35,8.651c-0.132-0.492-0.324-0.959-0.574-1.39l0.803-1.02c0.123-0.155,0.107-0.399-0.033-0.54
|
||||
l-1.33-1.329c-0.14-0.142-0.383-0.156-0.54-0.033l-1.021,0.803c-0.43-0.249-0.896-0.441-1.385-0.571l-0.156-1.29
|
||||
c-0.022-0.198-0.205-0.359-0.402-0.359H22.83c-0.199,0-0.381,0.161-0.404,0.359l-0.154,1.29c-0.492,0.13-0.957,0.323-1.388,0.572
|
||||
l-1.021-0.802c-0.156-0.122-0.399-0.107-0.539,0.031l-1.331,1.332c-0.142,0.141-0.155,0.383-0.032,0.539l0.803,1.021
|
||||
c-0.25,0.43-0.441,0.896-0.574,1.388L16.9,8.806c-0.198,0.023-0.359,0.206-0.359,0.405v1.881c0,0.197,0.162,0.381,0.359,0.402
|
||||
l1.289,0.157c0.133,0.49,0.326,0.955,0.574,1.386l-0.803,1.02c-0.122,0.156-0.107,0.4,0.033,0.54l1.328,1.329
|
||||
c0.141,0.143,0.383,0.156,0.539,0.033l1.021-0.804c0.43,0.249,0.896,0.442,1.387,0.572l0.155,1.292
|
||||
c0.022,0.195,0.206,0.356,0.404,0.356h1.881c0.198,0,0.38-0.161,0.403-0.356l0.154-1.292c0.492-0.13,0.957-0.323,1.387-0.572
|
||||
l1.021,0.802c0.157,0.123,0.399,0.109,0.54-0.031l1.33-1.332c0.141-0.139,0.155-0.382,0.032-0.538l-0.802-1.021
|
||||
c0.25-0.429,0.44-0.895,0.572-1.386l1.291-0.154c0.198-0.025,0.359-0.205,0.359-0.405V9.21
|
||||
C30.999,9.009,30.837,8.829,30.641,8.804z M23.771,13.764c-1.998,0-3.615-1.618-3.615-3.614c0-1.997,1.619-3.614,3.615-3.614
|
||||
c1.994,0,3.613,1.617,3.613,3.614C27.384,12.145,25.766,13.764,23.771,13.764z"/>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 3.1 KiB |
BIN
docs/static/images/ifc.jpg
vendored
|
Before Width: | Height: | Size: 667 KiB |
BIN
docs/static/images/itemeconomy2-wide.png
vendored
|
Before Width: | Height: | Size: 3.1 KiB |
BIN
docs/static/images/jamfish-wide.png
vendored
|
Before Width: | Height: | Size: 135 KiB |
BIN
docs/static/images/me.png
vendored
|
Before Width: | Height: | Size: 136 KiB |
BIN
docs/static/images/pestowikifull.png
vendored
|
Before Width: | Height: | Size: 781 KiB |
BIN
docs/static/images/pestowikifullwhite.png
vendored
|
Before Width: | Height: | Size: 807 KiB |
BIN
docs/static/images/redes.jpg
vendored
|
Before Width: | Height: | Size: 479 KiB |
BIN
docs/static/images/sigaa-inicio.png
vendored
|
Before Width: | Height: | Size: 248 KiB |
BIN
docs/static/images/sigaa-login.png
vendored
|
Before Width: | Height: | Size: 78 KiB |
BIN
docs/static/images/sigaa-materia.png
vendored
|
Before Width: | Height: | Size: 169 KiB |
BIN
docs/static/images/songs/pg.jpg
vendored
|
Before Width: | Height: | Size: 60 KiB |
BIN
docs/static/images/songs/velkommen.jpg
vendored
|
Before Width: | Height: | Size: 360 KiB |
BIN
docs/static/images/songs/winds.png
vendored
|
Before Width: | Height: | Size: 910 KiB |
BIN
docs/static/images/sound-off.png
vendored
|
Before Width: | Height: | Size: 8 KiB |
BIN
docs/static/images/sound-on.png
vendored
|
Before Width: | Height: | Size: 9.2 KiB |
5
docs/static/images/video.svg
vendored
|
|
@ -1,5 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
|
||||
<svg fill="#000000" xmlns="http://www.w3.org/2000/svg" width="800px" height="800px" viewBox="0 0 52 52" enable-background="new 0 0 52 52" xml:space="preserve">
|
||||
<path d="M46.9,13.1L35.9,21v-5.6c0-1.5-1.2-2.7-2.7-2.7H4.7c-1.5,0-2.7,1.2-2.7,2.7v21.3c0,1.5,1.2,2.7,2.7,2.7h28.6 c1.5,0,2.7-1.2,2.7-2.7v-5.5L46.9,39c0.7,0.7,1.9,0.2,1.9-0.8V13.9C48.8,12.9,47.6,12.4,46.9,13.1z"/>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 500 B |
BIN
docs/static/images/youtube_video.jpg
vendored
|
Before Width: | Height: | Size: 224 KiB |
800
docs/static/main.css
vendored
|
|
@ -1,800 +0,0 @@
|
|||
:root {
|
||||
--theme-color: #4c6d6e;
|
||||
--theme-color-lighter: #84b9bb;
|
||||
--theme-color-variation: #22e6ed;
|
||||
}
|
||||
|
||||
* {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
body {
|
||||
background-color: black;
|
||||
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
|
||||
font-size: 1em;
|
||||
color: white;
|
||||
}
|
||||
|
||||
a {
|
||||
transition: .2s;
|
||||
color: lightgray;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
a:hover {
|
||||
color: var(--theme-color-lighter);
|
||||
}
|
||||
|
||||
li {
|
||||
list-style-type: none;
|
||||
}
|
||||
|
||||
select {
|
||||
background-color: transparent;
|
||||
color: white;
|
||||
border: none;
|
||||
font-size: 1em;
|
||||
}
|
||||
|
||||
#music {
|
||||
padding: 0;
|
||||
display: flex;
|
||||
gap: .4em;
|
||||
inline-size: fit-content;
|
||||
height: 1.4em;
|
||||
margin-top: auto;
|
||||
opacity: .6;
|
||||
}
|
||||
|
||||
#music:hover {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
header {
|
||||
display: flex;
|
||||
border-bottom: thick solid rgba(255, 255, 255, 0.1);
|
||||
width: 100%;
|
||||
box-shadow:
|
||||
2px 7px 5px rgba(0,0,0,0.3),
|
||||
0px -4px 10px rgba(0,0,0,0.3);
|
||||
background-color: rgba(0, 0, 0, 0.15);
|
||||
}
|
||||
|
||||
header div {
|
||||
padding: 1rem;
|
||||
}
|
||||
|
||||
#everythingHelper {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
#everythingHelper .bg {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
z-index: -1;
|
||||
opacity: .5;
|
||||
width: 100%;
|
||||
height: auto;
|
||||
-webkit-mask-image: linear-gradient(to bottom, rgba(0, 0, 0, 1) 90%, rgba(0, 0, 0, 0) 100%);
|
||||
-webkit-mask-repeat: no-repeat;
|
||||
-webkit-mask-size: 100% 100%;
|
||||
mask-image: linear-gradient(to bottom, rgba(0, 0, 0, 1) 40%, rgba(0, 0, 0, 0) 100%);
|
||||
mask-repeat: no-repeat;
|
||||
mask-size: 100% 100%;
|
||||
user-select: none;
|
||||
transition: .4s;
|
||||
}
|
||||
|
||||
header ul {
|
||||
transition: .2s;
|
||||
font-size: larger;
|
||||
margin: auto 0 auto 0;
|
||||
padding: 0;
|
||||
opacity: 0.6;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
header ul a {
|
||||
transition: .2s;
|
||||
color: white;
|
||||
}
|
||||
|
||||
header ul a:hover {
|
||||
color: var(--theme-color);
|
||||
}
|
||||
|
||||
header ul:hover {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
#mainHelper {
|
||||
padding-top: 3rem;
|
||||
max-width: 50vw;
|
||||
margin: auto;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
main {
|
||||
margin-bottom: 2em;
|
||||
}
|
||||
|
||||
h1, h2, h3 {
|
||||
text-shadow: 2px 7px 5px rgba(0,0,0,0.3),
|
||||
0px -4px 10px rgba(0,0,0,0.3);
|
||||
}
|
||||
|
||||
blockquote, main p {
|
||||
margin-bottom: 1em;
|
||||
}
|
||||
|
||||
main h1, main h2 {
|
||||
margin-bottom: .5em;
|
||||
}
|
||||
|
||||
main h2 {
|
||||
margin-top: 1em;
|
||||
}
|
||||
|
||||
b {
|
||||
color: var(--theme-color-lighter);
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
blockquote {
|
||||
margin-left: 2.8em;
|
||||
}
|
||||
|
||||
#headerSubtitle {
|
||||
color: white;
|
||||
opacity: 0.6;
|
||||
}
|
||||
|
||||
h2 {
|
||||
font-weight: normal;
|
||||
color: var(--theme-color-lighter);
|
||||
}
|
||||
|
||||
textarea, input, button {
|
||||
border: medium solid var(--theme-color-lighter);
|
||||
background-color: black;
|
||||
color: white;
|
||||
padding: .6em;
|
||||
}
|
||||
|
||||
#sound {
|
||||
filter: invert();
|
||||
}
|
||||
|
||||
#sound:hover {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
#linksHelper {
|
||||
margin: auto 1em auto auto;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: .2em;
|
||||
}
|
||||
|
||||
#linksHelper:hover {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
#headerLinks {
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
#headerLinks a {
|
||||
color: white;
|
||||
}
|
||||
|
||||
#headerLinks a {
|
||||
margin-right: .2em;
|
||||
margin-left: .2em;
|
||||
}
|
||||
|
||||
#headerLinks:last-child {
|
||||
margin-left: 0;
|
||||
}
|
||||
|
||||
#headerLinks a:first-child {
|
||||
margin-left: 0;
|
||||
}
|
||||
|
||||
#headerLinks a:last-child {
|
||||
margin-right: 0;
|
||||
}
|
||||
|
||||
header div:first-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
#headerSquareMusic img, #headerSquareVideo img, #headerSquareCode img, #defaultSquare img {
|
||||
filter: invert();
|
||||
}
|
||||
|
||||
.headerSquare, #defaultSquare {
|
||||
transition: .4s;
|
||||
border: medium solid white;
|
||||
height: 7vh;
|
||||
overflow: hidden;
|
||||
width: 10vh;
|
||||
opacity: .4;
|
||||
padding: .4em;
|
||||
cursor: pointer;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
.headerSquare img, #defaultSquare img {
|
||||
width: 100%;
|
||||
height: auto;
|
||||
}
|
||||
|
||||
.headerSquare:hover, #defaultSquare {
|
||||
z-index: 1;
|
||||
/* height: 10vh; */
|
||||
/* background-color: black; */
|
||||
}
|
||||
|
||||
.headerSquare.selected, #defaultSquare.selected {
|
||||
opacity: 1;
|
||||
height: 10vh;
|
||||
box-shadow:
|
||||
2px 7px 5px rgba(0,0,0,0.4),
|
||||
0px -4px 10px rgba(0,0,0,0.4);
|
||||
background-color: rgba(0, 0, 0, 0.3);
|
||||
}
|
||||
|
||||
#homeSquares {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
transition: .4s;
|
||||
width: fit-content;
|
||||
height: fit-content;
|
||||
margin-right: 3vw;
|
||||
margin-bottom: 3rem;
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
div.hs {
|
||||
display: none;
|
||||
}
|
||||
|
||||
div.hs.selected {
|
||||
display: unset;
|
||||
}
|
||||
|
||||
.ytembed {
|
||||
display: block;
|
||||
margin: auto;
|
||||
}
|
||||
|
||||
.margarinaColor {
|
||||
color: #ff85e1;
|
||||
}
|
||||
|
||||
.hsProjects {
|
||||
gap: .6em;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.hsProject {
|
||||
margin-bottom: .4em;
|
||||
/* padding: 1em; */
|
||||
border: medium solid rgba(255, 255, 255, 0.6);
|
||||
width: 100%;
|
||||
height: fit-content;
|
||||
transition: .2s;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 1em;
|
||||
box-shadow:
|
||||
2px 7px 5px rgba(0,0,0,0.4),
|
||||
0px -4px 10px rgba(0,0,0,0.4);
|
||||
background-color: rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
|
||||
.hsProjectHeader {
|
||||
transition: .2s;
|
||||
display: flex;
|
||||
height: 7em;
|
||||
border-bottom: medium solid rgba(255, 255, 255, 0.6);
|
||||
padding: 1em;
|
||||
}
|
||||
|
||||
.hsProjectHeaderIcon {
|
||||
transition: .2s;
|
||||
fill: white;
|
||||
stroke: white;
|
||||
height: 50%;
|
||||
width: auto;
|
||||
margin: auto 0;
|
||||
opacity: .6;
|
||||
}
|
||||
|
||||
.hsProjectHeaderIcon img {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.hsProject:hover {
|
||||
border-color: white;
|
||||
}
|
||||
|
||||
.hsProject:hover .hsProjectHeader {
|
||||
border-color: white;
|
||||
}
|
||||
|
||||
.hsProject:hover .hsProjectHeaderIcon {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.hsProjectImage {
|
||||
width: 100%;
|
||||
max-height: 100%;
|
||||
}
|
||||
|
||||
.hsProjectImage img {
|
||||
height: 100%;
|
||||
width: auto;
|
||||
}
|
||||
|
||||
.hsProjectContent {
|
||||
padding: 1em;
|
||||
}
|
||||
|
||||
.invertedc {
|
||||
filter: invert();
|
||||
}
|
||||
|
||||
#hsCode {
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
#hsCode.selected {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.ellipsis-loader {
|
||||
animation: 1.8s infinite ellipsis-loader;
|
||||
display: inline-block;
|
||||
height: 8px;
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
width: 140px;
|
||||
margin: auto;
|
||||
}
|
||||
.ellipsis-loader__dot {
|
||||
animation: 1.8s infinite ellipsis-loader__dot;
|
||||
background: #FFF;
|
||||
border-radius: 50%;
|
||||
float: left;
|
||||
height: 8px;
|
||||
position: absolute;
|
||||
width: 8px;
|
||||
}
|
||||
.ellipsis-loader__dot:nth-child(1) {
|
||||
animation-delay: 0.15s;
|
||||
left: -13px;
|
||||
}
|
||||
.ellipsis-loader__dot:nth-child(2) {
|
||||
animation-delay: 0.3s;
|
||||
left: -26px;
|
||||
}
|
||||
.ellipsis-loader__dot:nth-child(3) {
|
||||
animation-delay: 0.45s;
|
||||
left: -39px;
|
||||
}
|
||||
.ellipsis-loader__dot:nth-child(4) {
|
||||
animation-delay: 0.6s;
|
||||
left: -52px;
|
||||
}
|
||||
|
||||
#telnetSimulation {
|
||||
display: flex;
|
||||
width: 100%;
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
#telnetSimulation div {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 10px;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
#telnetSimulation div textarea {
|
||||
width: 100%;
|
||||
resize: none;
|
||||
height: 300px;
|
||||
}
|
||||
|
||||
#telnetSimulationInput {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
#telnetSimulationLoadingHolder {
|
||||
text-align: center;
|
||||
margin: 10px;
|
||||
display: none;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
#youtubeVideo p {
|
||||
font-size: 2vh;
|
||||
}
|
||||
|
||||
#youtubeVideoImage {
|
||||
width: 100%;
|
||||
transition: .3s;
|
||||
box-shadow:
|
||||
2px 7px 5px rgba(0,0,0,0.3),
|
||||
0px -4px 10px rgba(0,0,0,0.3);
|
||||
}
|
||||
|
||||
#youtubeVideoImage:hover {
|
||||
opacity: .8;
|
||||
}
|
||||
|
||||
#languageList {
|
||||
font-size: 2vh;
|
||||
}
|
||||
|
||||
#languageList li {
|
||||
margin-bottom: .5em;
|
||||
}
|
||||
|
||||
#languageList li a {
|
||||
transition: 1s;
|
||||
}
|
||||
|
||||
.languagesHighlightedLink {
|
||||
color: var(--theme-color-variation);
|
||||
}
|
||||
|
||||
.fadeIn {
|
||||
animation: fadeIn .5s ease-in 1 forwards;
|
||||
}
|
||||
.fadeOut {
|
||||
opacity: 1;
|
||||
animation: fadeOut .5s ease-out 1 forwards;
|
||||
}
|
||||
|
||||
.oneLineClamp {
|
||||
overflow: hidden;
|
||||
width: 100%;
|
||||
display: -webkit-box;
|
||||
/* height: 1em; */
|
||||
line-clamp: 1;
|
||||
-webkit-line-clamp: 1;
|
||||
-webkit-box-orient: vertical
|
||||
}
|
||||
|
||||
aside.metromenu {
|
||||
z-index: 2;
|
||||
position: fixed;
|
||||
top: 0;
|
||||
right: 0;
|
||||
width: 30vw;
|
||||
background-color: black;
|
||||
height: 100vh;
|
||||
transition: .2s;
|
||||
transition-timing-function: cubic-bezier(0.1, 0.2, 0.3, 0.955);
|
||||
padding: 2em;
|
||||
}
|
||||
|
||||
aside.metromenu.closed {
|
||||
transform: translateX(100%);
|
||||
}
|
||||
|
||||
aside.metromenu h2 {
|
||||
font-size: xx-large;
|
||||
}
|
||||
|
||||
aside.metromenu p {
|
||||
margin-bottom: .4em;
|
||||
}
|
||||
|
||||
aside.metromenu .optionsToggle {
|
||||
margin-bottom: 1em;
|
||||
}
|
||||
|
||||
.optionsToggle {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
aside.metromenu .optionsToggle {
|
||||
opacity: .6;
|
||||
width: fit-content;
|
||||
}
|
||||
|
||||
aside.metromenu #content {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 1em;
|
||||
}
|
||||
|
||||
.checkbox {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.checkbox p {
|
||||
flex-grow: 1;
|
||||
}
|
||||
|
||||
input[type="checkbox"] {
|
||||
border: thick solid white;
|
||||
}
|
||||
|
||||
input[type="range"] {
|
||||
width: 100%;
|
||||
border: none;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
input[type="range"]::-webkit-slider-thumb, input[type="range"]::-moz-range-thumb {
|
||||
background-color: black;
|
||||
transition: .2s;
|
||||
border-radius: 0;
|
||||
border: medium solid white;
|
||||
height: 1.2em;
|
||||
}
|
||||
|
||||
input[type="range"]:hover::-webkit-slider-thumb, input[type="range"]:hover::-moz-range-thumb {
|
||||
height: 2em;
|
||||
background-color: white;
|
||||
border-width: thin;
|
||||
}
|
||||
|
||||
input[type="range"]::-webkit-slider-runnable-track, input[type="range"]::-moz-range-track {
|
||||
background-color: white;
|
||||
height: 1em;
|
||||
}
|
||||
|
||||
#songDrawer {
|
||||
display: flex;
|
||||
height: 10em;
|
||||
overflow-x: auto;
|
||||
overflow-y: hidden;
|
||||
gap: .2em;
|
||||
}
|
||||
|
||||
.drawerSong {
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.drawerSong img {
|
||||
transition: .4s;
|
||||
width: 5em;
|
||||
height: 100%;
|
||||
object-fit: cover;
|
||||
object-position: left top;
|
||||
opacity: .4;
|
||||
filter: grayscale(1);
|
||||
}
|
||||
|
||||
.drawerSong p {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
display: inline;
|
||||
}
|
||||
|
||||
.drawerSong:hover img, .drawerSong.selected img {
|
||||
opacity: 1;
|
||||
overflow: hidden;
|
||||
width: 10em;
|
||||
}
|
||||
|
||||
.drawerSong.selected img {
|
||||
filter: none;
|
||||
/* width: auto; */
|
||||
}
|
||||
|
||||
.drawerSong.selected {
|
||||
width: 10em;
|
||||
}
|
||||
|
||||
.playlistTitle {
|
||||
background-color: white;
|
||||
color: black;
|
||||
}
|
||||
|
||||
#playlist {
|
||||
transition: .2s;
|
||||
max-height: 10em;
|
||||
overflow: auto;
|
||||
border: medium solid white;
|
||||
}
|
||||
|
||||
#playlist p {
|
||||
cursor: pointer;
|
||||
padding: 0 .4em;
|
||||
}
|
||||
|
||||
#playlist p:first-child {
|
||||
padding-bottom: .2em;
|
||||
}
|
||||
|
||||
.playingSong {
|
||||
font-size: larger;
|
||||
}
|
||||
|
||||
hs {
|
||||
border-bottom: thin solid white;
|
||||
}
|
||||
|
||||
#linksHelper hs {
|
||||
margin: .2em 0;
|
||||
opacity: .6;
|
||||
}
|
||||
|
||||
#linkshelper:hover hs {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.hidden {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.invisible {
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
.bg.invisible {
|
||||
opacity: 0!important;
|
||||
}
|
||||
|
||||
@keyframes ellipsis-loader {
|
||||
0%, 25% {
|
||||
transform: translateX(0);
|
||||
}
|
||||
100% {
|
||||
transform: translate(20px);
|
||||
}
|
||||
}
|
||||
@keyframes ellipsis-loader__dot {
|
||||
0% {
|
||||
animation-timing-function: cubic-bezier(0.23, 1, 0.32, 1);
|
||||
transform: translateX(0);
|
||||
}
|
||||
55% {
|
||||
animation-timing-function: cubic-bezier(0.785, 0.135, 0.15, 0.86);
|
||||
opacity: 1;
|
||||
transform: translateX(98px);
|
||||
}
|
||||
75%, 100% {
|
||||
transform: translateX(212px);
|
||||
}
|
||||
90% {
|
||||
opacity: 0.2;
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (max-width: 1280px) {
|
||||
body {
|
||||
font-size: 2vh;
|
||||
}
|
||||
|
||||
header {
|
||||
padding-top: 1.4rem;
|
||||
text-align: center;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
header ul {
|
||||
margin: auto;
|
||||
margin-bottom: 1.4rem;
|
||||
}
|
||||
|
||||
main {
|
||||
max-width: 90vw;
|
||||
}
|
||||
|
||||
main h1 {
|
||||
font-size: 3vh;
|
||||
}
|
||||
|
||||
#headerLinks {
|
||||
text-align: center;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
#homeTitle {
|
||||
font-size: 4vh;
|
||||
}
|
||||
|
||||
#linksHelper {
|
||||
margin: 0 auto 0 auto;
|
||||
}
|
||||
|
||||
#mainHelper {
|
||||
flex-direction: column;
|
||||
max-width: 90vw;
|
||||
}
|
||||
|
||||
#homeSquares {
|
||||
flex-direction: row;
|
||||
align-content: center;
|
||||
justify-content: center;
|
||||
width: 40vw;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
}
|
||||
|
||||
.headerSquare, #defaultSquare {
|
||||
aspect-ratio: 1/1;
|
||||
height: 100%;
|
||||
flex-grow: 1;
|
||||
}
|
||||
|
||||
.headerSquare.selected, #defaultSqaure.selected {
|
||||
height: unset!important;
|
||||
}
|
||||
|
||||
|
||||
#languageList {
|
||||
font-size: 2.5vh;
|
||||
}
|
||||
|
||||
#postHeader {
|
||||
/* border-bottom: 8px dashed rgba(255, 255, 255, 0.1); */
|
||||
}
|
||||
|
||||
.hsProjectHeader {
|
||||
height: fit-content;
|
||||
flex-direction: column;
|
||||
gap: 1em;
|
||||
}
|
||||
|
||||
.hsProjectImage {
|
||||
max-height: 5em;
|
||||
margin: auto;
|
||||
width: fit-content;
|
||||
}
|
||||
|
||||
.hsProjectImage img {
|
||||
height: 100%;
|
||||
max-height: inherit;
|
||||
}
|
||||
|
||||
.hsProjectHeaderIcon {
|
||||
margin: auto;
|
||||
}
|
||||
|
||||
aside.metromenu {
|
||||
width: 50%;
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (max-width: 800px) {
|
||||
#homeSquares {
|
||||
width: 60vw;
|
||||
}
|
||||
|
||||
aside.metromenu {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (max-width: 720px) {
|
||||
#homeSquares {
|
||||
width: 80vw;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes fadeIn {
|
||||
to {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
@keyframes fadeOut {
|
||||
to {
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
BIN
docs/static/music/PG2.mp3
vendored
BIN
docs/static/music/Velkommen.mp3
vendored
BIN
docs/static/music/dreamscape.mp3
vendored
BIN
docs/static/music/skychat.mp3
vendored
14
docs/static/scripts/ccd.js
vendored
|
|
@ -1,14 +0,0 @@
|
|||
const konamiCode = ['ArrowUp', 'ArrowUp', 'ArrowDown', 'ArrowDown', 'ArrowLeft', 'ArrowRight', 'ArrowLeft', 'ArrowRight', 'KeyB', 'KeyA'];
|
||||
let keyIndex = 0;
|
||||
|
||||
document.addEventListener('keydown', function(event) {
|
||||
if (event.code === konamiCode[keyIndex]) {
|
||||
keyIndex++;
|
||||
if (keyIndex === konamiCode.length) {
|
||||
window.location.href = './toyourdreams.txt'
|
||||
keyIndex = 0;
|
||||
}
|
||||
} else {
|
||||
keyIndex = 0;
|
||||
}
|
||||
});
|
||||
51
docs/static/scripts/home.js
vendored
|
|
@ -1,51 +0,0 @@
|
|||
const _homeSquares = document.querySelector("#homeSquares");
|
||||
const main = document.querySelector("main");
|
||||
|
||||
let info = [
|
||||
["Default", "defaultSquare", "arrow-cursor.svg", "Computer cursor arrow line drawing"],
|
||||
["Music", "headerSquareMusic", "8thNote.svg", "Music note line drawing"],
|
||||
["Video", "headerSquareVideo", "video.svg", "Video roll line drawing"],
|
||||
["Code", "headerSquareCode", "file-code.svg", "Computer code file line drawing"]
|
||||
]
|
||||
|
||||
info.forEach(square => {
|
||||
let rawHTML = `<div class='headerSquare' id='${square[1]}'><img src='/static/images/${square[2]}' alt='${square[3]}'></div>`;
|
||||
_homeSquares.innerHTML += rawHTML;
|
||||
});
|
||||
|
||||
const homeSquares = document.querySelectorAll(".headerSquare");
|
||||
let selectedSquare = "defaultSquare";
|
||||
let selectedSquareDiv;
|
||||
updateSquare();
|
||||
|
||||
homeSquares.forEach(square =>
|
||||
square.addEventListener('click', () => {
|
||||
toggleSquare(square);
|
||||
})
|
||||
)
|
||||
|
||||
function toggleSquare(square) {
|
||||
if (selectedSquare && (selectedSquare == square.id)) {
|
||||
return
|
||||
}
|
||||
else if (selectedSquare) {
|
||||
oldSquare = document.getElementById(selectedSquare);
|
||||
oldSquare.classList.toggle("selected");
|
||||
document.querySelector(`#${selectedSquareDiv}`).classList.toggle("selected");
|
||||
}
|
||||
selectedSquare = square.id;
|
||||
updateSquare()
|
||||
}
|
||||
|
||||
function getSquareDivByID(id) {
|
||||
divID = `hs${info.find(item => item[1] === id)[0]}`;
|
||||
return document.querySelector(`#${divID}`);
|
||||
}
|
||||
|
||||
function updateSquare() {
|
||||
square = document.getElementById(selectedSquare);
|
||||
square.classList.toggle("selected");
|
||||
div = getSquareDivByID(square.id);
|
||||
selectedSquareDiv = div.id;
|
||||
div.classList.toggle("selected");
|
||||
}
|
||||
37
docs/static/scripts/language.js
vendored
|
|
@ -1,37 +0,0 @@
|
|||
const el = document.getElementById("languageTitle");
|
||||
const texts = [["Pick a language", "English"], ["Escolha um idioma", "Português Brasileiro"]];
|
||||
let i = 0;
|
||||
let fadeTime = 1000;
|
||||
let holdTime = 2000;
|
||||
const links = document.querySelectorAll("#languageList li a");
|
||||
let currentLang = 0;
|
||||
|
||||
el.style.transition = `opacity ${fadeTime}ms`;
|
||||
el.style.opacity = 1;
|
||||
|
||||
function cycle() {
|
||||
el.style.opacity = 0;
|
||||
removeOldHighlightedLang();
|
||||
setTimeout(() => {
|
||||
i = (i + 1) % texts.length;
|
||||
currentLang = i;
|
||||
el.textContent = texts[i][0];
|
||||
el.style.opacity = 1;
|
||||
setNewHighlightedLang()
|
||||
}, fadeTime);
|
||||
}
|
||||
|
||||
function removeOldHighlightedLang() {
|
||||
document.querySelector(".languagesHighlightedLink").classList.remove("languagesHighlightedLink");
|
||||
}
|
||||
|
||||
function setNewHighlightedLang() {
|
||||
links.forEach(link => {
|
||||
if (link.innerText == texts[currentLang][1]) {
|
||||
link.classList.add('languagesHighlightedLink');
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
setNewHighlightedLang()
|
||||
setInterval(cycle, fadeTime * 2 + holdTime);
|
||||
213
docs/static/scripts/main.js
vendored
|
|
@ -1,213 +0,0 @@
|
|||
// This script handles the playback of music in the header's miniplayer ;)
|
||||
const body = document.querySelector("body");
|
||||
|
||||
const musicdiv = document.getElementById("music");
|
||||
musicdiv.innerHTML = `
|
||||
<img src="/static/images/gears.svg" class="optionsToggle invertedc">
|
||||
<img src="/static/images/sound-on.png" id="sound">
|
||||
<select name="song" id="songSelection"></select>
|
||||
`
|
||||
const linksHelper = document.getElementById("linksHelper");
|
||||
linksHelper.insertBefore(document.createElement("hs"), document.getElementById("headerLinks"));
|
||||
|
||||
const songs = [
|
||||
{ file: "Velkommen.mp3", name: 'Velkommen', artwork: "velkommen.jpg" },
|
||||
{ file: "PG2.mp3", name: 'Frugal APE', artwork: "pg.jpg" },
|
||||
{ file: "dreamscape.mp3", name: 'Dreamscape', artwork: "winds.png" },
|
||||
{ file: "skychat.mp3", name: 'Skychat', artwork: "winds.png" }
|
||||
];
|
||||
|
||||
// Options page
|
||||
const optionsAside = document.createElement("aside");
|
||||
optionsAside.classList.add("closed");
|
||||
optionsAside.classList.add("metromenu");
|
||||
{
|
||||
const back = document.createElement("p");
|
||||
back.textContent = headeri18n.back;
|
||||
back.classList.add("optionsToggle");
|
||||
|
||||
const title = document.createElement("h2");
|
||||
title.textContent = headeri18n.options;
|
||||
optionsAside.appendChild(title);
|
||||
optionsAside.appendChild(back);
|
||||
|
||||
const content = document.createElement("div");
|
||||
content.innerHTML = `
|
||||
<div id="content">
|
||||
<div id="songDrawer"></div>
|
||||
<div>
|
||||
<p class="playingSong"></p>
|
||||
<p>${headeri18n.by} tenkuma</p>
|
||||
</div>
|
||||
<div id="playlist"></div>
|
||||
<div>
|
||||
<p>Volume</p>
|
||||
<input id="volume" oninput="setVolume(this.value / 100)" type="range" min="0" max="100"></input>
|
||||
</div>
|
||||
<div class="checkbox">
|
||||
<p>${headeri18n.hideBackground}</p>
|
||||
<input id="background" type="checkbox"></input>
|
||||
</div>
|
||||
</div>
|
||||
`
|
||||
optionsAside.appendChild(content);
|
||||
}
|
||||
body.appendChild(optionsAside);
|
||||
|
||||
|
||||
const toggleIMG = document.querySelector('#sound');
|
||||
toggleIMG.addEventListener('click', () => {
|
||||
toggleAudio();
|
||||
})
|
||||
|
||||
const hideBG = document.querySelector("input#background");
|
||||
if (localStorage.getItem("bgHidden") === "true") hideBG.checked = true, toggleBG();
|
||||
hideBG.addEventListener("click", () => {
|
||||
toggleBG();
|
||||
})
|
||||
|
||||
function toggleBG() {
|
||||
const bg = document.querySelector(".bg");
|
||||
bg.classList.toggle("invisible");
|
||||
localStorage.setItem("bgHidden", bg.classList.contains("invisible"))
|
||||
}
|
||||
|
||||
const songsDrawer = document.querySelector("#songDrawer");
|
||||
const drawerSongs = [];
|
||||
const playlist = document.querySelector("#playlist");
|
||||
const expandButton = document.createElement('p');
|
||||
expandButton.textContent = "Playlist";
|
||||
expandButton.classList.add("playlistTitle");
|
||||
playlist.appendChild(expandButton);
|
||||
|
||||
songs.forEach(song => {
|
||||
const songElement = document.createElement("div");
|
||||
songElement.classList.add("drawerSong");
|
||||
songElement.dataset.song = song.file;
|
||||
const songImage = document.createElement("img");
|
||||
songImage.src = `/static/images/songs/${song.artwork}`;
|
||||
songElement.appendChild(songImage);
|
||||
songElement.addEventListener('click', () => {
|
||||
changeSong(song.file);
|
||||
});
|
||||
drawerSongs.push(songElement);
|
||||
songsDrawer.appendChild(songElement);
|
||||
|
||||
// Playlist
|
||||
const playlistEntry = document.createElement("p");
|
||||
playlistEntry.textContent = song.name;
|
||||
playlistEntry.addEventListener('click', () => {
|
||||
changeSong(song.file);
|
||||
})
|
||||
playlist.appendChild(playlistEntry);
|
||||
})
|
||||
|
||||
const audioSelect = document.getElementById("songSelection");
|
||||
songs.forEach(song => {
|
||||
const songOption = document.createElement("option");
|
||||
songOption.value = song.file;
|
||||
songOption.textContent = song.name;
|
||||
audioSelect.appendChild(songOption);
|
||||
});
|
||||
|
||||
const playingSongLabel = document.querySelector(".playingSong");
|
||||
|
||||
function updatePlayingLabel(label) {
|
||||
drawerSongs.forEach(sng => {
|
||||
sng.classList.remove("selected");
|
||||
if (sng.dataset.song == label) {
|
||||
sng.classList.add("selected");
|
||||
}
|
||||
});
|
||||
|
||||
const songString = songs.find(item => item.file === label).name;
|
||||
playingSongLabel.textContent = songString;
|
||||
}
|
||||
|
||||
const savedSong = localStorage.getItem("song");
|
||||
|
||||
if (savedSong) {
|
||||
audioSelect.value = savedSong;
|
||||
updatePlayingLabel(savedSong);
|
||||
} else {
|
||||
audioSelect.value = songs[0].file;
|
||||
updatePlayingLabel(songs[0].file);
|
||||
}
|
||||
|
||||
const optionsButton = document.querySelectorAll(".optionsToggle");
|
||||
optionsButton.forEach(button => {
|
||||
button.addEventListener('click', () => {
|
||||
optionsAside.classList.toggle('closed');
|
||||
});
|
||||
});
|
||||
|
||||
// Create the audio object using the current select value
|
||||
let audio = new Audio(`/static/music/${audioSelect.value}`);
|
||||
|
||||
const savedTime = localStorage.getItem("audioTime");
|
||||
const savedVolume = localStorage.getItem("volume");
|
||||
const wasPlaying = localStorage.getItem("audioPlaying") === 'true';
|
||||
|
||||
function play() {
|
||||
audio.volume = localStorage.getItem("volume");
|
||||
audio.play();
|
||||
localStorage.setItem("audioPlaying", "true")
|
||||
toggleIMG.src = "/static/images/sound-on.png"
|
||||
console.log(`[Music Player] playing ${audioSelect.value}`)
|
||||
}
|
||||
|
||||
function stop() {
|
||||
audio.pause();
|
||||
localStorage.setItem("audioPlaying", "false")
|
||||
toggleIMG.src = "/static/images/sound-off.png"
|
||||
}
|
||||
|
||||
function setVolume(volume) {
|
||||
audio.volume = volume;
|
||||
localStorage.setItem("volume", volume);
|
||||
}
|
||||
|
||||
function toggleAudio() {
|
||||
if (!audio.paused) {
|
||||
stop();
|
||||
} else {
|
||||
play();
|
||||
}
|
||||
}
|
||||
|
||||
window.addEventListener("beforeunload", () => {
|
||||
localStorage.setItem("audioTime", audio.currentTime);
|
||||
localStorage.setItem("audioPlaying", !audio.paused);
|
||||
});
|
||||
|
||||
function changeSong(song) {
|
||||
const wasPlaying = !audio.paused;
|
||||
stop();
|
||||
localStorage.removeItem("audioTime");
|
||||
audio = new Audio(`/static/music/${song}`);
|
||||
if (savedVolume) setVolume(savedVolume);
|
||||
console.log(`[Music Player] changing song to ${song}`)
|
||||
localStorage.setItem("song", song);
|
||||
updatePlayingLabel(song);
|
||||
if (wasPlaying) play();
|
||||
}
|
||||
|
||||
// hooking into the options menu 'change' event to update the song
|
||||
audioSelect.addEventListener('change', () => {
|
||||
changeSong(audioSelect.value);
|
||||
})
|
||||
|
||||
// Set initial playback state and volume based on saved preferences
|
||||
if (savedTime) audio.currentTime = parseFloat(savedTime);
|
||||
|
||||
if (savedVolume) {
|
||||
document.getElementById("volume").value = savedVolume * 100;
|
||||
} else {
|
||||
document.getElementById("volume").value = 100;
|
||||
}
|
||||
|
||||
if (wasPlaying) {
|
||||
play();
|
||||
} else {
|
||||
stop();
|
||||
}
|
||||
66
docs/static/scripts/telnetSimulator.js
vendored
|
|
@ -1,66 +0,0 @@
|
|||
const screen = document.getElementById('telnetSimulationClientScreen');
|
||||
const input = document.getElementById('telnetSimulationInputBox');
|
||||
const btn = document.getElementById('telnetSimulationClientSend')
|
||||
const sbtn = document.getElementById('telnetSimulationServerClean');
|
||||
const sscreen = document.getElementById('telnetSimulationServerScreen');
|
||||
const loading = document.getElementById("telnetSimulationLoadingHolder")
|
||||
const loadingText = document.getElementById("telnetSimulationLoadingText")
|
||||
let loadingms = 2500;
|
||||
|
||||
btn.addEventListener('click', () => {
|
||||
send_command();
|
||||
})
|
||||
|
||||
sbtn.addEventListener('click', () => {
|
||||
screen.innerHTML = '';
|
||||
sscreen.innerHTML = '';
|
||||
})
|
||||
|
||||
async function send_command() {
|
||||
if (!input.value) return;
|
||||
const command = input.value;
|
||||
input.value = '';
|
||||
screen.value += `telnet> ${command}\n`;
|
||||
await wait(loadingms, "<b>Camada OSI #7 - Aplicação:</b> Usuário digitou o texto na aplicação.");
|
||||
await wait(loadingms, "<b>Camada OSI #6 - Apresentação:</b> Tradução do comando para um pacote legível para o servidor.");
|
||||
await wait(loadingms, "<b>Camada OSI #5 - Sessão:</b> Sistema do cliente abre uma conexão com o servidor.");
|
||||
await wait(loadingms, "<b>Camada OSI #4 - Transporte:</b> Sistema do cliente troca informações com o servidor.");
|
||||
await wait(loadingms, "<b>Camada OSI #3 - Rede:</b> O sistema do cliente resolve o endereço do servidor.");
|
||||
await wait(loadingms, "<b>Camada OSI #2 - Enlace de dados:</b> Os frames são entregues ao dispositivo com o endereço MAC correto.");
|
||||
await wait(loadingms, "<b>Camada OSI #1 - Física:</b> Os dados são transmitidos por cabo, ou via <i>wireless</i>, para o dispositivo de destino.");
|
||||
process_command(command);
|
||||
}
|
||||
|
||||
async function process_command(command) {
|
||||
sscreen.value += `Comando recebido: ${command}\n`;
|
||||
args = command.split(" ");
|
||||
command = args[0]
|
||||
args.shift();
|
||||
await wait(loadingms, "<b>O servidor empacota uma resposta, que também será passada por todas camadas até chegar no cliente.");
|
||||
switch (command) {
|
||||
case 'help':
|
||||
screen.value += `Comandos disponíveis:\nhelp - mostra essa mensagem de ajuda\nping - responde 'pong'\necho [texto] - retorna o texto especificado no comando\ntimeout [milissegundos] - muda o tempo que as mensagens de carregamento da simulação duram`
|
||||
break;
|
||||
case 'echo':
|
||||
screen.value += `Resposta do servidor: ${args.join(' ')}\n`
|
||||
break;
|
||||
case 'ping':
|
||||
screen.value += `Pong!\n`
|
||||
break;
|
||||
case 'timeout':
|
||||
loadingms = args[0]
|
||||
screen.value += `O tempo das mensagens de carregamento foi mudado para ${args[0]}ms!`
|
||||
break;
|
||||
default:
|
||||
screen.value += `Comando desconhecido! Envie help para ver a lista de comandos.\n`
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
async function wait(ms, txt = '') {
|
||||
const delay = ms => new Promise(res => setTimeout(res, ms));
|
||||
loadingText.innerHTML = txt;
|
||||
loading.style.display = "flex"
|
||||
await delay(ms)
|
||||
loading.style.display = "none"
|
||||
}
|
||||
1
docs/static/site.webmanifest
vendored
|
|
@ -1 +0,0 @@
|
|||
{"name":"","short_name":"","icons":[{"src":"/static/android-chrome-192x192.png","sizes":"192x192","type":"image/png"},{"src":"/static/android-chrome-512x512.png","sizes":"512x512","type":"image/png"}],"theme_color":"#ffffff","background_color":"#ffffff","display":"standalone"}
|
||||
1
docs/static/visual/github.svg
vendored
|
|
@ -1 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?><svg width="24px" height="24px" stroke-width="1.5" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg" color="#000000"><path d="M16 22.0268V19.1568C16.0375 18.68 15.9731 18.2006 15.811 17.7506C15.6489 17.3006 15.3929 16.8902 15.06 16.5468C18.2 16.1968 21.5 15.0068 21.5 9.54679C21.4997 8.15062 20.9627 6.80799 20 5.79679C20.4558 4.5753 20.4236 3.22514 19.91 2.02679C19.91 2.02679 18.73 1.67679 16 3.50679C13.708 2.88561 11.292 2.88561 8.99999 3.50679C6.26999 1.67679 5.08999 2.02679 5.08999 2.02679C4.57636 3.22514 4.54413 4.5753 4.99999 5.79679C4.03011 6.81549 3.49251 8.17026 3.49999 9.57679C3.49999 14.9968 6.79998 16.1868 9.93998 16.5768C9.61098 16.9168 9.35725 17.3222 9.19529 17.7667C9.03334 18.2112 8.96679 18.6849 8.99999 19.1568V22.0268" stroke="#000000" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"></path><path d="M9 20.0267C6 20.9999 3.5 20.0267 2 17.0267" stroke="#000000" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"></path></svg>
|
||||
|
Before Width: | Height: | Size: 1 KiB |