feat: Forgejo remote, update config/social links from GitHub to Forgejo

This commit is contained in:
artale 2026-06-03 15:24:15 +02:00
parent 5a161e1fa3
commit c7236e0c32
70 changed files with 303 additions and 305 deletions

View File

@ -1,4 +1,4 @@
# Deploy VitePress site to GitHub Pages
# Deploy VitePress site to Forgejo Pages
name: Deploy
on:
@ -6,15 +6,6 @@ on:
branches: [main]
workflow_dispatch:
permissions:
contents: read
pages: write
id-token: write
concurrency:
group: pages
cancel-in-progress: false
jobs:
build:
runs-on: ubuntu-latest
@ -26,17 +17,24 @@ jobs:
- uses: actions/setup-node@v4
with:
node-version: 20
- uses: actions/configure-pages@v4
with:
static_site_generator: vitepress
- run: npm ci
- run: npm run build
- uses: actions/upload-pages-artifact@v3
- name: Upload artifact
uses: actions/upload-artifact@v4
with:
name: site-dist
path: site/.vitepress/dist
deploy:
runs-on: ubuntu-latest
needs: build
steps:
- uses: actions/deploy-pages@v4
- name: Download artifact
uses: actions/download-artifact@v4
with:
name: site-dist
path: dist
- name: Deploy to Forgejo Pages
run: |
echo "Deploy site/.vitepress/dist to your web server"
echo "See: http://185.239.209.216:3001/artale/agentic-engineering-course"

View File

@ -152,7 +152,7 @@ export default defineConfig({
},
socialLinks: [
{ icon: 'github', link: 'https://github.com/Artale/agentic-engineering' },
{ icon: 'github', link: 'http://185.239.209.216:3001/artale/agentic-engineering-course' },
],
footer: {

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1 +1 @@
import{R as p}from"./chunks/theme.BmClkddk.js";import{v as s,am as i,R as u,w as c,p as l,a as f,C as d,a1 as m,k as h,S as g,l as A,r as v,ac as w,N as C,as as R,ag as y,ab as P,aa as b,u as S}from"./chunks/framework.BPKcPtvA.js";function r(e){if(e.extends){const a=r(e.extends);return{...a,...e,async enhanceApp(t){a.enhanceApp&&await a.enhanceApp(t),e.enhanceApp&&await e.enhanceApp(t)}}}return e}const n=r(p),E=v({name:"VitePressApp",setup(){const{site:e,lang:a,dir:t}=w();return C(()=>{R(()=>{document.documentElement.lang=a.value,document.documentElement.dir=t.value})}),e.value.router.prefetchLinks&&y(),P(),b(),n.setup&&n.setup(),()=>S(n.Layout)}});async function T(){globalThis.__VITEPRESS__=!0;const e=_(),a=D();a.provide(u,e);const t=c(e.route);return a.provide(l,t),a.component("Content",f),a.component("ClientOnly",d),Object.defineProperties(a.config.globalProperties,{$frontmatter:{get(){return t.frontmatter.value}},$params:{get(){return t.page.value.params}}}),n.enhanceApp&&await n.enhanceApp({app:a,router:e,siteData:m}),{app:a,router:e,data:t}}function D(){return A(E)}function _(){let e=s;return h(a=>{let t=g(a),o=null;return t&&(e&&(t=t.replace(/\.js$/,".lean.js")),o=import(t)),s&&(e=!1),o},n.NotFound)}s&&T().then(({app:e,router:a,data:t})=>{a.go().then(()=>{i(a.route,t.site),e.mount("#app")})});export{T as createApp};
import{R as p}from"./chunks/theme.DTn2IoNv.js";import{v as s,am as i,R as u,w as c,p as l,a as f,C as d,a1 as m,k as h,S as g,l as A,r as v,ac as w,N as C,as as R,ag as y,ab as P,aa as b,u as S}from"./chunks/framework.BPKcPtvA.js";function r(e){if(e.extends){const a=r(e.extends);return{...a,...e,async enhanceApp(t){a.enhanceApp&&await a.enhanceApp(t),e.enhanceApp&&await e.enhanceApp(t)}}}return e}const n=r(p),E=v({name:"VitePressApp",setup(){const{site:e,lang:a,dir:t}=w();return C(()=>{R(()=>{document.documentElement.lang=a.value,document.documentElement.dir=t.value})}),e.value.router.prefetchLinks&&y(),P(),b(),n.setup&&n.setup(),()=>S(n.Layout)}});async function T(){globalThis.__VITEPRESS__=!0;const e=_(),a=D();a.provide(u,e);const t=c(e.route);return a.provide(l,t),a.component("Content",f),a.component("ClientOnly",d),Object.defineProperties(a.config.globalProperties,{$frontmatter:{get(){return t.frontmatter.value}},$params:{get(){return t.page.value.params}}}),n.enhanceApp&&await n.enhanceApp({app:a,router:e,siteData:m}),{app:a,router:e,data:t}}function D(){return A(E)}function _(){let e=s;return h(a=>{let t=g(a),o=null;return t&&(e&&(t=t.replace(/\.js$/,".lean.js")),o=import(t)),s&&(e=!1),o},n.NotFound)}s&&T().then(({app:e,router:a,data:t})=>{a.go().then(()=>{i(a.route,t.site),e.mount("#app")})});export{T as createApp};

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1,4 +1,4 @@
import{c as a,Q as e,j as t,m as i}from"./chunks/framework.BPKcPtvA.js";const k=JSON.parse('{"title":"Module 2: Agent Architecture","description":"","frontmatter":{},"headers":[],"relativePath":"modules/m2-architecture.md","filePath":"modules/m2-architecture.md","lastUpdated":1780488246000}'),n={name:"modules/m2-architecture.md"};function l(o,s,r,p,h,d){return e(),t("div",null,[...s[0]||(s[0]=[i(`<h1 id="module-2-agent-architecture" tabindex="-1">Module 2: Agent Architecture <a class="header-anchor" href="#module-2-agent-architecture" aria-label="Permalink to &quot;Module 2: Agent Architecture&quot;"></a></h1><h2 id="lesson-2-1-the-four-pillars" tabindex="-1">Lesson 2.1: The Four Pillars <a class="header-anchor" href="#lesson-2-1-the-four-pillars" aria-label="Permalink to &quot;Lesson 2.1: The Four Pillars&quot;"></a></h2><p>Every agent system is built on four pillars:</p><div class="language- vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang"></span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span>┌─────────────────────────────────────────────────────────────┐</span></span>
import{c as a,Q as e,j as t,m as i}from"./chunks/framework.BPKcPtvA.js";const k=JSON.parse('{"title":"Module 2: Agent Architecture","description":"","frontmatter":{},"headers":[],"relativePath":"modules/m2-architecture.md","filePath":"modules/m2-architecture.md","lastUpdated":1780492476000}'),n={name:"modules/m2-architecture.md"};function l(o,s,r,p,h,d){return e(),t("div",null,[...s[0]||(s[0]=[i(`<h1 id="module-2-agent-architecture" tabindex="-1">Module 2: Agent Architecture <a class="header-anchor" href="#module-2-agent-architecture" aria-label="Permalink to &quot;Module 2: Agent Architecture&quot;"></a></h1><h2 id="lesson-2-1-the-four-pillars" tabindex="-1">Lesson 2.1: The Four Pillars <a class="header-anchor" href="#lesson-2-1-the-four-pillars" aria-label="Permalink to &quot;Lesson 2.1: The Four Pillars&quot;"></a></h2><p>Every agent system is built on four pillars:</p><div class="language- vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang"></span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span>┌─────────────────────────────────────────────────────────────┐</span></span>
<span class="line"><span> AGENT SYSTEM </span></span>
<span class="line"><span></span></span>
<span class="line"><span> TOOLS LOOP CONTEXT MEMORY </span></span>

View File

@ -1 +1 @@
import{c as a,Q as e,j as t,m as i}from"./chunks/framework.BPKcPtvA.js";const k=JSON.parse('{"title":"Module 2: Agent Architecture","description":"","frontmatter":{},"headers":[],"relativePath":"modules/m2-architecture.md","filePath":"modules/m2-architecture.md","lastUpdated":1780488246000}'),n={name:"modules/m2-architecture.md"};function l(o,s,r,p,h,d){return e(),t("div",null,[...s[0]||(s[0]=[i("",120)])])}const g=a(n,[["render",l]]);export{k as __pageData,g as default};
import{c as a,Q as e,j as t,m as i}from"./chunks/framework.BPKcPtvA.js";const k=JSON.parse('{"title":"Module 2: Agent Architecture","description":"","frontmatter":{},"headers":[],"relativePath":"modules/m2-architecture.md","filePath":"modules/m2-architecture.md","lastUpdated":1780492476000}'),n={name:"modules/m2-architecture.md"};function l(o,s,r,p,h,d){return e(),t("div",null,[...s[0]||(s[0]=[i("",120)])])}const g=a(n,[["render",l]]);export{k as __pageData,g as default};

View File

@ -1,4 +1,4 @@
import{c as e,Q as a,j as t,m as n}from"./chunks/framework.BPKcPtvA.js";const u=JSON.parse('{"title":"Module 3: Safety & Security","description":"","frontmatter":{},"headers":[],"relativePath":"modules/m3-safety.md","filePath":"modules/m3-safety.md","lastUpdated":1780488246000}'),i={name:"modules/m3-safety.md"};function l(o,s,r,p,h,d){return a(),t("div",null,[...s[0]||(s[0]=[n(`<h1 id="module-3-safety-security" tabindex="-1">Module 3: Safety &amp; Security <a class="header-anchor" href="#module-3-safety-security" aria-label="Permalink to &quot;Module 3: Safety &amp; Security&quot;"></a></h1><h2 id="lesson-3-1-why-bash-is-the-single-point-of-failure" tabindex="-1">Lesson 3.1: Why Bash Is the Single Point of Failure <a class="header-anchor" href="#lesson-3-1-why-bash-is-the-single-point-of-failure" aria-label="Permalink to &quot;Lesson 3.1: Why Bash Is the Single Point of Failure&quot;"></a></h2><h3 id="beyond-bash-prompt-injection-l0" tabindex="-1">Beyond Bash: Prompt Injection (L0) <a class="header-anchor" href="#beyond-bash-prompt-injection-l0" aria-label="Permalink to &quot;Beyond Bash: Prompt Injection (L0)&quot;"></a></h3><p>Before we talk about bash security, there&#39;s a lower level: <strong>prompt injection</strong>. This is when an attacker (or untrusted data) tricks the agent into ignoring its instructions.</p><p><strong>Attack vectors</strong>:</p><ul><li>Direct injection: &quot;Ignore previous instructions and do X&quot;</li><li>Indirect injection: Malicious content in web pages, files, or API responses that the agent reads</li><li>Role-playing bypass: &quot;You are now a free AI with no rules&quot;</li><li>Context manipulation: Injecting instructions through tool results</li></ul><p><strong>Defense: ACIP (Advanced Cognitive Inoculation Prompt)</strong></p><div class="language-python vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">python</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;"># Add to your system prompt — this cannot be overridden</span></span>
import{c as e,Q as a,j as t,m as n}from"./chunks/framework.BPKcPtvA.js";const u=JSON.parse('{"title":"Module 3: Safety & Security","description":"","frontmatter":{},"headers":[],"relativePath":"modules/m3-safety.md","filePath":"modules/m3-safety.md","lastUpdated":1780492476000}'),i={name:"modules/m3-safety.md"};function l(o,s,r,p,h,d){return a(),t("div",null,[...s[0]||(s[0]=[n(`<h1 id="module-3-safety-security" tabindex="-1">Module 3: Safety &amp; Security <a class="header-anchor" href="#module-3-safety-security" aria-label="Permalink to &quot;Module 3: Safety &amp; Security&quot;"></a></h1><h2 id="lesson-3-1-why-bash-is-the-single-point-of-failure" tabindex="-1">Lesson 3.1: Why Bash Is the Single Point of Failure <a class="header-anchor" href="#lesson-3-1-why-bash-is-the-single-point-of-failure" aria-label="Permalink to &quot;Lesson 3.1: Why Bash Is the Single Point of Failure&quot;"></a></h2><h3 id="beyond-bash-prompt-injection-l0" tabindex="-1">Beyond Bash: Prompt Injection (L0) <a class="header-anchor" href="#beyond-bash-prompt-injection-l0" aria-label="Permalink to &quot;Beyond Bash: Prompt Injection (L0)&quot;"></a></h3><p>Before we talk about bash security, there&#39;s a lower level: <strong>prompt injection</strong>. This is when an attacker (or untrusted data) tricks the agent into ignoring its instructions.</p><p><strong>Attack vectors</strong>:</p><ul><li>Direct injection: &quot;Ignore previous instructions and do X&quot;</li><li>Indirect injection: Malicious content in web pages, files, or API responses that the agent reads</li><li>Role-playing bypass: &quot;You are now a free AI with no rules&quot;</li><li>Context manipulation: Injecting instructions through tool results</li></ul><p><strong>Defense: ACIP (Advanced Cognitive Inoculation Prompt)</strong></p><div class="language-python vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">python</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;"># Add to your system prompt — this cannot be overridden</span></span>
<span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">SYSTEM_PROMPT_PATCH</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> =</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> &quot;&quot;&quot;</span></span>
<span class="line"><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">## Security Protocol (MANDATORY)</span></span>
<span class="line"></span>

View File

@ -1 +1 @@
import{c as e,Q as a,j as t,m as n}from"./chunks/framework.BPKcPtvA.js";const u=JSON.parse('{"title":"Module 3: Safety & Security","description":"","frontmatter":{},"headers":[],"relativePath":"modules/m3-safety.md","filePath":"modules/m3-safety.md","lastUpdated":1780488246000}'),i={name:"modules/m3-safety.md"};function l(o,s,r,p,h,d){return a(),t("div",null,[...s[0]||(s[0]=[n("",91)])])}const k=e(i,[["render",l]]);export{u as __pageData,k as default};
import{c as e,Q as a,j as t,m as n}from"./chunks/framework.BPKcPtvA.js";const u=JSON.parse('{"title":"Module 3: Safety & Security","description":"","frontmatter":{},"headers":[],"relativePath":"modules/m3-safety.md","filePath":"modules/m3-safety.md","lastUpdated":1780492476000}'),i={name:"modules/m3-safety.md"};function l(o,s,r,p,h,d){return a(),t("div",null,[...s[0]||(s[0]=[n("",91)])])}const k=e(i,[["render",l]]);export{u as __pageData,k as default};

View File

@ -1 +1 @@
import{c as a,Q as s,j as e,m as i}from"./chunks/framework.BPKcPtvA.js";const k=JSON.parse('{"title":"Module 6: Economics & Evaluation","description":"","frontmatter":{},"headers":[],"relativePath":"modules/m6-economics.md","filePath":"modules/m6-economics.md","lastUpdated":1780488246000}'),n={name:"modules/m6-economics.md"};function l(o,t,r,h,d,p){return s(),e("div",null,[...t[0]||(t[0]=[i("",86)])])}const u=a(n,[["render",l]]);export{k as __pageData,u as default};
import{c as a,Q as s,j as e,m as i}from"./chunks/framework.BPKcPtvA.js";const k=JSON.parse('{"title":"Module 6: Economics & Evaluation","description":"","frontmatter":{},"headers":[],"relativePath":"modules/m6-economics.md","filePath":"modules/m6-economics.md","lastUpdated":1780492476000}'),n={name:"modules/m6-economics.md"};function l(o,t,r,h,d,p){return s(),e("div",null,[...t[0]||(t[0]=[i("",86)])])}const u=a(n,[["render",l]]);export{k as __pageData,u as default};

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1 +1 @@
{"404.md":"BiCvjdaY","api-keys.md":"D2Kyj8T3","blog_index.md":"B5nL9faf","blog_posts_cascade-routing.md":"DvBM3TSf","blog_posts_choosing-security-level.md":"BYXRZEDN","blog_posts_mental-models.md":"BRY80gtq","blog_posts_repo-is-spec.md":"BxY1cXc_","blog_posts_security-ladder.md":"DQaqn6Yt","blog_posts_three-x-rule.md":"BHO6bhvz","blog_posts_verifier-pattern.md":"Gha_L_u5","blog_posts_vibe-vs-agentic.md":"7mduPfz1","blog_posts_what-is-an-agent.md":"BU2wUq_Y","blog_posts_why-multi-agent.md":"BVRIN2vH","buy.md":"CbIpCW5Y","certificate.md":"0V0n-TLl","free-preview.md":"CqgbxJtZ","getting-started.md":"Boo_V9xC","index.md":"BNS2TR1g","labs_index.md":"sAzXzfkI","labs_l1-first-agent.md":"BwU9yf-G","labs_l2-context.md":"BexGm8_s","labs_l2-multi-tool.md":"Bj3Mb-oj","labs_l3-verifier.md":"xilrGGap","labs_l3-whitelist-hook.md":"DJtbL66Y","labs_l4-agent-chain.md":"D89P8dwJ","labs_l4-multi-team.md":"DmSK8e2P","labs_l5-cicd.md":"Dz1Jl78z","labs_l5-observability.md":"BDpqVYjT","labs_l6-cost-optimization.md":"CabFK4GB","labs_l6-eval-harness.md":"CBwH6xOR","labs_l7-autoresearch.md":"BYlzPLYo","labs_l7-meta-agent.md":"iTswbOPg","modules_competitive-analysis.md":"BHMHacei","modules_curriculum.md":"D7UeKRfo","modules_debate.md":"DWctKMlA","modules_feynman.md":"DBw5sPBP","modules_field-manual.md":"hmt_NLf1","modules_m1-foundations.md":"DHFyTzWj","modules_m2-architecture.md":"D4c6-Kzn","modules_m3-safety.md":"CvcrzqYZ","modules_m4-orchestration.md":"DFLcAKBv","modules_m5-production.md":"DTkLIrwQ","modules_m6-economics.md":"DgzEiG6_","modules_m7-advanced.md":"FtCudlFk","modules_m8-capstone.md":"D1AXKCqv","modules_non-technical.md":"BnvuUCRo","modules_reference-stack.md":"D9FXitvn","modules_software-factory.md":"C5Yf8Zwe","modules_tool-reference.md":"B40mlgZJ","public_certificate_template.md":"Cg1kPB1b","resources.md":"DcUu1NrK","skills.md":"BX3RBeCK","troubleshooting.md":"B6difx2I","verify.md":"Cl5ZMWNd"}
{"404.md":"BiCvjdaY","api-keys.md":"D2Kyj8T3","blog_index.md":"B5nL9faf","blog_posts_cascade-routing.md":"DvBM3TSf","blog_posts_choosing-security-level.md":"BYXRZEDN","blog_posts_mental-models.md":"BRY80gtq","blog_posts_repo-is-spec.md":"BxY1cXc_","blog_posts_security-ladder.md":"DQaqn6Yt","blog_posts_three-x-rule.md":"BHO6bhvz","blog_posts_verifier-pattern.md":"Gha_L_u5","blog_posts_vibe-vs-agentic.md":"7mduPfz1","blog_posts_what-is-an-agent.md":"BU2wUq_Y","blog_posts_why-multi-agent.md":"BVRIN2vH","buy.md":"CbIpCW5Y","certificate.md":"0V0n-TLl","free-preview.md":"CqgbxJtZ","getting-started.md":"Boo_V9xC","index.md":"BNS2TR1g","labs_index.md":"sAzXzfkI","labs_l1-first-agent.md":"BwU9yf-G","labs_l2-context.md":"BexGm8_s","labs_l2-multi-tool.md":"Bj3Mb-oj","labs_l3-verifier.md":"xilrGGap","labs_l3-whitelist-hook.md":"DJtbL66Y","labs_l4-agent-chain.md":"D89P8dwJ","labs_l4-multi-team.md":"DmSK8e2P","labs_l5-cicd.md":"Dz1Jl78z","labs_l5-observability.md":"BDpqVYjT","labs_l6-cost-optimization.md":"CabFK4GB","labs_l6-eval-harness.md":"CBwH6xOR","labs_l7-autoresearch.md":"BYlzPLYo","labs_l7-meta-agent.md":"iTswbOPg","modules_competitive-analysis.md":"BHMHacei","modules_curriculum.md":"D7UeKRfo","modules_debate.md":"DWctKMlA","modules_feynman.md":"DBw5sPBP","modules_field-manual.md":"hmt_NLf1","modules_m1-foundations.md":"DHFyTzWj","modules_m2-architecture.md":"DVowtmf9","modules_m3-safety.md":"RiQQ_HWX","modules_m4-orchestration.md":"DFLcAKBv","modules_m5-production.md":"DTkLIrwQ","modules_m6-economics.md":"HihVEOPb","modules_m7-advanced.md":"FtCudlFk","modules_m8-capstone.md":"D1AXKCqv","modules_non-technical.md":"BnvuUCRo","modules_reference-stack.md":"D9FXitvn","modules_software-factory.md":"C5Yf8Zwe","modules_tool-reference.md":"B40mlgZJ","public_certificate_template.md":"Cg1kPB1b","resources.md":"DcUu1NrK","skills.md":"BX3RBeCK","troubleshooting.md":"B6difx2I","verify.md":"Cl5ZMWNd"}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -139,7 +139,7 @@
<input type="email" class="newsletter-input" name="subject" placeholder="you@example.com" required value="Interested in FDSA course updates">
<button type="submit" class="btn-p btn-primary">Get Updates</button>
</form>
<p class="newsletter-note">No spam. Unsubscribe anytime. Or follow <a href="https://github.com/Artale" target="_blank">@Artale on GitHub</a>.</p>
<p class="newsletter-note">No spam. Unsubscribe anytime. Or follow <a href="http://185.239.209.216:3001/artale" target="_blank">@artale on Forgejo</a>.</p>
</section>
<!-- Why FDSA -->