Compare commits
26 Commits
28d1dc8d50
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
| 333eaa2dca | |||
| 96c8643769 | |||
| 5df865ee3b | |||
| 6e8c3f911d | |||
| ef877ad303 | |||
| 700073571e | |||
| 873b4bfc0d | |||
| ec0498f425 | |||
| fb1b49a3b2 | |||
| a5351efcec | |||
| 81c82188d3 | |||
| d734131325 | |||
|
|
80ed9c8978 | ||
|
|
17271c1e52 | ||
|
|
9ab9089f4f | ||
|
|
6c0243c5e2 | ||
|
|
f37572f0cf | ||
|
|
1c85792839 | ||
|
|
ccb5978831 | ||
|
|
5f4b2cf1d5 | ||
|
|
7b97fbe816 | ||
|
|
ea8d8c880d | ||
|
|
b66149a0ec | ||
|
|
c89df4cf2f | ||
|
|
0ade5e6e9c | ||
|
|
fd3563d124 |
@@ -5,15 +5,33 @@
|
||||
--foreground: #171717;
|
||||
}
|
||||
|
||||
@theme inline {
|
||||
--color-background: var(--background);
|
||||
--color-foreground: var(--foreground);
|
||||
--font-sans: var(--font-geist-sans);
|
||||
--font-mono: var(--font-geist-mono);
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: dark) {
|
||||
:root {
|
||||
--background: #0a0a0a;
|
||||
--foreground: #ededed;
|
||||
--font-merryweather: "Merriweather", serif;
|
||||
--font-open-sans: "Open Sans", sans-serif;
|
||||
}
|
||||
}
|
||||
|
||||
body {
|
||||
color: var(--foreground);
|
||||
background: var(--background);
|
||||
font-family: "JetBrains Mono", monospace;
|
||||
color: var(--foreground);
|
||||
font-family: var(--font-open-sans), sans-serif;
|
||||
}
|
||||
|
||||
h1,
|
||||
h2,
|
||||
h3,
|
||||
h4,
|
||||
h5,
|
||||
h6 {
|
||||
font-family: var(--font-noto-serif), serif;
|
||||
}
|
||||
|
||||
@@ -1,38 +1,55 @@
|
||||
import type { Metadata } from "next";
|
||||
import { Merriweather } from 'next/font/google';
|
||||
import "./globals.css";
|
||||
|
||||
import MainHeader from "@/components/header/main";
|
||||
import MainFooter from "@/components/footer/main";
|
||||
|
||||
export const metadata: Metadata = {
|
||||
title: 'AderKI Blog',
|
||||
description: 'Welcome to AderKI Blog. There will be posts about science',
|
||||
keywords: ['AderKI', 'hoodies', 'comics', 'books', 'store', 'blog'],
|
||||
authors: [{ name: 'AderKI' }],
|
||||
title: "Ader Konstantin Blog",
|
||||
description: "Welcome to AderKI Blog. There will be posts about digital design and computer architecture",
|
||||
keywords: ["blog", "risc-v"],
|
||||
authors: [{ name: "Ader Konstantin" }],
|
||||
openGraph: {
|
||||
title: 'AderKI Blog',
|
||||
description: 'Welcome to AderKI Blog. There will be posts about science',
|
||||
url: 'https://blog.aderk.tech/',
|
||||
title: "AderKI Blog",
|
||||
description: "Welcome to AderKI Blog. There will be posts about digital design and computer architecture",
|
||||
url: "https://blog.aderk.org/",
|
||||
images: [
|
||||
{
|
||||
url: '/images/logo.png', // Path to your Open Graph image
|
||||
url: "/images/logo.png", // Path to your Open Graph image
|
||||
width: 800,
|
||||
height: 600,
|
||||
alt: 'AderKI Blog Logo',
|
||||
alt: "AderKI Blog Logo",
|
||||
},
|
||||
],
|
||||
siteName: 'AderKI Blog',
|
||||
siteName: "Ader Konstantin Blog",
|
||||
},
|
||||
icons: {
|
||||
icon: '/images/favicon.ico', // Path to your favicon
|
||||
icon: "/images/favicon.ico", // Path to your favicon
|
||||
},
|
||||
};
|
||||
|
||||
export default function RootLayout({ children }: { children: React.ReactNode }) {
|
||||
import { Source_Serif_4 } from 'next/font/google';
|
||||
|
||||
const sourceSerif = Source_Serif_4({
|
||||
subsets: ['latin', 'cyrillic'],
|
||||
display: 'swap',
|
||||
});
|
||||
export default function RootLayout({
|
||||
children,
|
||||
}: {
|
||||
children: React.ReactNode;
|
||||
}) {
|
||||
return (
|
||||
<html lang="en">
|
||||
<html className="dark" lang="en">
|
||||
<body
|
||||
className={`bg-black text-white font-sans`}
|
||||
className={`${sourceSerif.className} dark:bg- dark:text-white bg-white text-black font-sans`}
|
||||
>
|
||||
<div className="text-xl 2xl:mx-75 xl:mx-36 md:mx-6">
|
||||
<MainHeader />
|
||||
{children}
|
||||
<MainFooter />
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
);
|
||||
|
||||
274
app/markdown.css
Normal file
@@ -0,0 +1,274 @@
|
||||
.markdown {
|
||||
color: #333;
|
||||
line-height: 1.2;
|
||||
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
|
||||
}
|
||||
|
||||
.markdown > *:first-child {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
.markdown > *:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.markdown h1,
|
||||
.markdown h2,
|
||||
.markdown h3,
|
||||
.markdown h4,
|
||||
.markdown h5,
|
||||
.markdown h6 {
|
||||
font-weight: 600;
|
||||
line-height: 1.25;
|
||||
margin-top: 1.5em;
|
||||
margin-bottom: 0.5em;
|
||||
color: #111;
|
||||
}
|
||||
|
||||
.markdown h1 {
|
||||
font-size: 2em;
|
||||
border-bottom: 2px solid #eaecef;
|
||||
padding-bottom: 0.3em;
|
||||
}
|
||||
|
||||
.markdown h2 {
|
||||
font-size: 1.5em;
|
||||
border-bottom: 1px solid #eaecef;
|
||||
padding-bottom: 0.3em;
|
||||
}
|
||||
|
||||
.markdown h3 { font-size: 1.25em; }
|
||||
.markdown h4 { font-size: 1em; }
|
||||
.markdown h5 { font-size: 0.875em; }
|
||||
.markdown h6 { font-size: 0.85em; color: #666; }
|
||||
|
||||
.markdown p {
|
||||
margin-top: 0;
|
||||
margin-bottom: 1em;
|
||||
}
|
||||
|
||||
.markdown strong {
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.markdown em {
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.markdown del {
|
||||
text-decoration: line-through;
|
||||
color: #666;
|
||||
}
|
||||
|
||||
.markdown hr {
|
||||
height: 1px;
|
||||
border: none;
|
||||
background-color: #eaecef;
|
||||
margin: 2em 0;
|
||||
}
|
||||
|
||||
.markdown a {
|
||||
color: #0366d6;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.markdown a:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
.markdown a:visited {
|
||||
color: #5a32a3;
|
||||
}
|
||||
|
||||
/* Lists - ФИКС ДЛЯ ЧЕКБОКСОВ */
|
||||
.markdown ul,
|
||||
.markdown ol {
|
||||
padding-left: 2em;
|
||||
margin-top: 0.5em;
|
||||
margin-bottom: 0.75em;
|
||||
}
|
||||
|
||||
.markdown li {
|
||||
margin-bottom: 0.5em;
|
||||
list-style: inherit;
|
||||
display: list-item;
|
||||
}
|
||||
|
||||
/* Особые стили для списков задач */
|
||||
.markdown ul:has(input[type="checkbox"]) {
|
||||
list-style: none;
|
||||
padding-left: 0;
|
||||
}
|
||||
|
||||
.markdown ul:has(input[type="checkbox"]) li {
|
||||
list-style: none;
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
gap: 8px;
|
||||
margin-bottom: 0.75em;
|
||||
padding-left: 0;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
/* Чекбоксы */
|
||||
.markdown input[type="checkbox"] {
|
||||
margin: 0;
|
||||
margin-top: 0.25em;
|
||||
flex-shrink: 0;
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
cursor: pointer;
|
||||
accent-color: #0366d6;
|
||||
}
|
||||
|
||||
/* Если браузер не поддерживает :has() */
|
||||
.markdown .contains-task-list {
|
||||
list-style: none;
|
||||
padding-left: 0;
|
||||
}
|
||||
|
||||
.markdown .task-list-item {
|
||||
list-style: none;
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
gap: 8px;
|
||||
margin-bottom: 0.75em;
|
||||
padding-left: 0;
|
||||
}
|
||||
|
||||
/* Обычные списки (без чекбоксов) */
|
||||
.markdown ul:not(:has(input[type="checkbox"])) {
|
||||
list-style-type: disc;
|
||||
}
|
||||
|
||||
.markdown ul ul:not(:has(input[type="checkbox"])) {
|
||||
list-style-type: circle;
|
||||
}
|
||||
|
||||
.markdown ol:not(:has(input[type="checkbox"])) {
|
||||
list-style-type: decimal;
|
||||
}
|
||||
|
||||
/* Код - ИЗМЕНЕНИЯ ЗДЕСЬ: JetBrains Mono и уменьшенный размер */
|
||||
.markdown code {
|
||||
background-color: #f6f8fa;
|
||||
padding: 0.2em 0.4em;
|
||||
border-radius: 3px;
|
||||
font-family: 'JetBrains Mono', 'SFMono-Regular', Consolas, 'Liberation Mono', monospace;
|
||||
font-size: 0.85em;
|
||||
color: #e74c3c;
|
||||
}
|
||||
|
||||
.markdown pre {
|
||||
background-color: #f6f8fa;
|
||||
padding: 1em;
|
||||
border-radius: 6px;
|
||||
overflow: auto;
|
||||
margin-bottom: 1em;
|
||||
border: 1px solid #e1e4e8;
|
||||
}
|
||||
|
||||
.markdown pre code {
|
||||
background-color: transparent;
|
||||
padding: 0;
|
||||
color: inherit;
|
||||
font-family: 'JetBrains Mono', 'SFMono-Regular', Consolas, 'Liberation Mono', monospace;
|
||||
font-size: 0.85em;
|
||||
line-height: 1.2;
|
||||
}
|
||||
|
||||
.markdown blockquote {
|
||||
margin: 0;
|
||||
padding: 0 1em;
|
||||
color: #666;
|
||||
border-left: 4px solid #dfe2e5;
|
||||
}
|
||||
|
||||
.markdown blockquote > :first-child {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
.markdown blockquote > :last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.markdown table {
|
||||
border-collapse: collapse;
|
||||
width: 100%;
|
||||
margin-bottom: 1em;
|
||||
}
|
||||
|
||||
.markdown table th,
|
||||
.markdown table td {
|
||||
border: 1px solid #dfe2e5;
|
||||
padding: 0.5em 1em;
|
||||
}
|
||||
|
||||
.markdown table th {
|
||||
background-color: #f6f8fa;
|
||||
font-weight: 600;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.markdown table tr:nth-child(even) {
|
||||
background-color: #fafbfc;
|
||||
}
|
||||
|
||||
.markdown img {
|
||||
max-width: 100%;
|
||||
height: auto;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.markdown img + em {
|
||||
display: block;
|
||||
text-align: center;
|
||||
color: #666;
|
||||
font-size: 0.9em;
|
||||
margin-top: 0.5em;
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: dark) {
|
||||
.markdown {
|
||||
color: #e0e0e0;
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
.markdown h1,
|
||||
.markdown h2,
|
||||
.markdown h3,
|
||||
.markdown h4,
|
||||
.markdown h5,
|
||||
.markdown h6 {
|
||||
color: #fff;
|
||||
border-color: #444;
|
||||
}
|
||||
|
||||
.markdown code,
|
||||
.markdown pre {
|
||||
background-color: #2d2d2d;
|
||||
border-color: #444;
|
||||
}
|
||||
|
||||
.markdown a {
|
||||
color: #58a6ff;
|
||||
}
|
||||
|
||||
.markdown blockquote {
|
||||
color: #aaa;
|
||||
border-color: #555;
|
||||
}
|
||||
|
||||
.markdown table th,
|
||||
.markdown table td {
|
||||
border-color: #444;
|
||||
}
|
||||
|
||||
.markdown table th {
|
||||
background-color: #2d2d2d;
|
||||
}
|
||||
|
||||
.markdown table tr:nth-child(even) {
|
||||
background-color: #2a2a2a;
|
||||
}
|
||||
}
|
||||
133
app/page.tsx
@@ -1,123 +1,20 @@
|
||||
import mastodonPic from '../public/mastodon.svg';
|
||||
import githubPic from '../public/github.svg';
|
||||
import instagramPic from '../public/instagram.svg';
|
||||
import steamPic from '../public/steam.svg';
|
||||
|
||||
import gamePic from '../public/gamepad.svg';
|
||||
import projectPic from '../public/project.svg';
|
||||
|
||||
import Image from "next/image";
|
||||
import Link from "next/link";
|
||||
import AnimatedLink from '../components/animatedLink';
|
||||
import BlogArea from "../components/blogpost";
|
||||
|
||||
import MainHeader from "@/components/header/main";
|
||||
|
||||
// Mock data for blog posts
|
||||
const blogposts = [
|
||||
{
|
||||
label: 'Retro Futurism: A Journey Through Time',
|
||||
body: 'Explore the fascinating world of retro futurism and its impact on modern science and culture.',
|
||||
publish: '2023-10-01',
|
||||
get_absolute_url: '/blog/retro-futurism',
|
||||
tags: ["science", "retro", "science-friction"]
|
||||
},
|
||||
{
|
||||
label: 'The Science Behind Video Games',
|
||||
body: 'Discover how video games are pushing the boundaries of technology and human interaction.',
|
||||
publish: '2023-09-25',
|
||||
get_absolute_url: '/blog/science-video-games',
|
||||
tags: ["science", "math", "games"]
|
||||
},
|
||||
{
|
||||
label: 'How to install Docker & Docker Compose',
|
||||
body: 'Guide to install Docker & Docker Compose on your machine.',
|
||||
publish: '2023-09-25',
|
||||
get_absolute_url: '/blog/docker-installation',
|
||||
tags: ["docker", "docker-compose", "linux"]
|
||||
},
|
||||
{
|
||||
label: 'Rocket Science',
|
||||
body: 'Discover how rocket are work.',
|
||||
publish: '2023-09-25',
|
||||
get_absolute_url: '/blog/rocket-science',
|
||||
tags: ["rocket", "space", "engineering"]
|
||||
},
|
||||
];
|
||||
import { getSortedPostsData } from '@/lib/posts';
|
||||
import BlogArea from '@/components/blogpost';
|
||||
|
||||
export default function Home() {
|
||||
return (
|
||||
<div className="text-xl 2xl:mx-64 xl:mx-32 md:mx-6">
|
||||
<MainHeader />
|
||||
const blogposts = getSortedPostsData();
|
||||
|
||||
<main>
|
||||
<BlogArea blogposts={blogposts} />
|
||||
</main>
|
||||
const formattedPosts = blogposts.map(post => ({
|
||||
label: post.title,
|
||||
body: post.description,
|
||||
publish: new Date(post.date).toLocaleDateString('ru-RU', {
|
||||
day: 'numeric',
|
||||
month: 'long',
|
||||
year: 'numeric',
|
||||
}),
|
||||
get_absolute_url: `/post/${post.slug}`,
|
||||
tags: post.tags,
|
||||
}));
|
||||
|
||||
<footer className="border-t border-white pt-4 flex lg:flex-row max-md:flex-col justify-around text-2xl">
|
||||
<ul className="list-none m-4">
|
||||
<li className="text-2xl mb-3"><h3>Socials</h3></li>
|
||||
<li className="inline text-xl pr-2 mr-2">
|
||||
<Link href="https://www.instagram.com/aderkitty/">
|
||||
<Image
|
||||
src={instagramPic}
|
||||
alt="lang"
|
||||
width={32}
|
||||
height={32}
|
||||
className="inline filter brightness-0 invert"
|
||||
/>
|
||||
</Link>
|
||||
</li>
|
||||
<li className="inline text-xl pr-2 mr-2">
|
||||
<Link href="https://mastodon.social/@aderkonstantin">
|
||||
<Image
|
||||
src={mastodonPic}
|
||||
alt="lang"
|
||||
width={32}
|
||||
height={32}
|
||||
className="inline filter brightness-0 invert"
|
||||
/>
|
||||
</Link>
|
||||
</li>
|
||||
<li className="inline text-xl pr-2 mr-2">
|
||||
<Link href="https://github.com/AderKonstantin">
|
||||
<Image
|
||||
src={githubPic}
|
||||
alt="lang"
|
||||
width={32}
|
||||
height={32}
|
||||
className="inline filter brightness-0 invert"
|
||||
/>
|
||||
</Link>
|
||||
</li>
|
||||
<li className="inline text-xl pr-2 mr-2">
|
||||
<Link href="https://steamcommunity.com/yourprofile">
|
||||
<Image
|
||||
src={steamPic}
|
||||
alt="lang"
|
||||
width={32}
|
||||
height={32}
|
||||
className="inline filter brightness-0 invert"
|
||||
/>
|
||||
</Link>
|
||||
</li>
|
||||
</ul>
|
||||
<ul className="list-none m-4">
|
||||
<li className="text-2xl mb-3"><h3 className='inline'>Games</h3><Image src={gamePic} alt="lang" width={24} height={24} className="ml-2 inline filter brightness-0 invert" /></li>
|
||||
<li className="text-xl">
|
||||
<AnimatedLink href="#">Robot Fire</AnimatedLink>
|
||||
</li>
|
||||
</ul>
|
||||
<ul className="list-none m-4">
|
||||
<li className="text-2xl mb-3"><h3 className='inline'>Other Projects</h3><Image src={projectPic} alt="lang" width={24} height={24} className="ml-2 inline filter brightness-0 invert" /></li>
|
||||
<li className="text-xl">
|
||||
<AnimatedLink href="#">cloudberrygames</AnimatedLink>
|
||||
</li>
|
||||
<li className="text-xl">
|
||||
<AnimatedLink href="#">northfamily</AnimatedLink>
|
||||
</li>
|
||||
</ul>
|
||||
</footer>
|
||||
</div>
|
||||
);
|
||||
return <BlogArea blogposts={formattedPosts} />;
|
||||
}
|
||||
99
app/post/[slug]/page.tsx
Normal file
@@ -0,0 +1,99 @@
|
||||
import { getPostData, getAllPostSlugs } from '@/lib/posts';
|
||||
import { notFound } from 'next/navigation';
|
||||
import Link from 'next/link';
|
||||
import "@/app/markdown.css";
|
||||
|
||||
interface PostPageProps {
|
||||
params: Promise<{ slug: string }>;
|
||||
}
|
||||
|
||||
export async function generateStaticParams() {
|
||||
const slugs = getAllPostSlugs();
|
||||
console.log('Генерация статических путей для slugs:', slugs);
|
||||
|
||||
return slugs.map((slug) => ({
|
||||
slug,
|
||||
}));
|
||||
}
|
||||
|
||||
export async function generateMetadata({ params }: PostPageProps) {
|
||||
const { slug } = await params;
|
||||
const post = await getPostData(slug);
|
||||
|
||||
if (!post) {
|
||||
return {
|
||||
title: 'Пост не найден',
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
title: post.title,
|
||||
description: post.description,
|
||||
};
|
||||
}
|
||||
|
||||
export default async function PostPage({ params }: PostPageProps) {
|
||||
const { slug } = await params;
|
||||
const post = await getPostData(slug);
|
||||
|
||||
console.log(`Загрузка поста: ${slug}, результат:`, post ? 'найден' : 'не найден');
|
||||
|
||||
if (!post) {
|
||||
notFound();
|
||||
}
|
||||
|
||||
const formatDate = (dateStr: string) => {
|
||||
try {
|
||||
const date = new Date(dateStr);
|
||||
return new Intl.DateTimeFormat('ru-RU', {
|
||||
weekday: 'long',
|
||||
year: 'numeric',
|
||||
month: 'long',
|
||||
day: 'numeric',
|
||||
}).format(date);
|
||||
} catch {
|
||||
return dateStr;
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<main className="flex flex-col gap-[32px] row-start-2 items-center">
|
||||
<section className="space-y-1 text-center max-w-4xl w-full px-4 mt-2 pt-[1em]">
|
||||
<dl className="space-y-10">
|
||||
<div>
|
||||
<dt className="sr-only">Опубликовано</dt>
|
||||
<dd className="text-base leading-6 font-medium text-gray-500 dark:text-gray-400">
|
||||
{formatDate(post.date)}
|
||||
</dd>
|
||||
</div>
|
||||
</dl>
|
||||
<div>
|
||||
<h1 className="text-3xl leading-9 font-extrabold tracking-tight text-gray-900 sm:text-4xl sm:leading-10 md:text-5xl md:leading-14 dark:text-gray-100">
|
||||
{post.title}
|
||||
</h1>
|
||||
</div>
|
||||
{post.tags.length > 0 && (
|
||||
<div className="flex flex-wrap justify-center gap-2 mt-4">
|
||||
{post.tags.map((tag) => (
|
||||
<Link
|
||||
key={tag}
|
||||
href={`/tags/${tag}`}
|
||||
className="inline-block border border-slate-400 px-3 py-1 rounded-full text-sm font-medium text-gray-700 dark:text-gray-300 hover:bg-gray-100 dark:hover:bg-gray-800 transition-colors"
|
||||
>
|
||||
{tag}
|
||||
</Link>
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
</section>
|
||||
<section className="mx-auto px-4 pb-[4em] w-full px-[3em]">
|
||||
<article
|
||||
className="markdown"
|
||||
dangerouslySetInnerHTML={{ __html: post.contentHtml }}
|
||||
/>
|
||||
</section>
|
||||
</main>
|
||||
</>
|
||||
);
|
||||
}
|
||||
@@ -5,16 +5,26 @@ interface AnimatedLinkProps {
|
||||
href: string;
|
||||
children: React.ReactNode;
|
||||
className?: string;
|
||||
underlineColor?: string;
|
||||
textColor?: string;
|
||||
}
|
||||
|
||||
const AnimatedLink = ({ href, children, className = '' }: AnimatedLinkProps) => {
|
||||
const AnimatedLink = ({
|
||||
href,
|
||||
children,
|
||||
className = '',
|
||||
underlineColor = 'bg-black dark:bg-white',
|
||||
textColor = 'text-black dark:text-white'
|
||||
}: AnimatedLinkProps) => {
|
||||
return (
|
||||
<Link
|
||||
href={href}
|
||||
className={`group relative text-white hover:text-white ${className}`}
|
||||
className={`group relative ${textColor} transition-colors duration-300 ${className}`}
|
||||
>
|
||||
{children}
|
||||
<span className="absolute bottom-0 left-0 w-full h-0.5 bg-white transform scale-x-0 origin-left transition-transform duration-300 ease-in-out group-hover:scale-x-100"></span>
|
||||
<span
|
||||
className={`absolute bottom-0 left-0 w-full h-0.5 ${underlineColor} transform scale-x-0 origin-left transition-transform duration-300 ease-in-out group-hover:scale-x-100`}
|
||||
></span>
|
||||
</Link>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -1,10 +1,8 @@
|
||||
'use client';
|
||||
|
||||
import tagsPic from '../public/tags.svg';
|
||||
import calendarPic from '../public/calendar.svg'
|
||||
|
||||
import AnimatedLink from '../components/animatedLink';
|
||||
import Link from 'next/link';
|
||||
import Image from 'next/image';
|
||||
import { FaTags, FaCalendarAlt } from 'react-icons/fa';
|
||||
|
||||
interface BlogPost {
|
||||
label: string;
|
||||
@@ -20,55 +18,68 @@ interface BlogAreaProps {
|
||||
|
||||
export default function BlogArea({ blogposts }: BlogAreaProps) {
|
||||
return (
|
||||
<div className="blog-area pt-16 pb-8 w-full">
|
||||
<div className="blog-area my-4 py-16 w-full">
|
||||
<div className="blogposts">
|
||||
{blogposts.map((blogpost, index) => (
|
||||
<div key={index} className="blogpost flex flex-row overflow-hidden mb-14">
|
||||
<div key={index}>
|
||||
<div className="blogpost flex flex-row overflow-hidden">
|
||||
<div className="left mr-5">
|
||||
<div className="blogpost-image">
|
||||
<Link href={blogpost.get_absolute_url}>
|
||||
<Image
|
||||
src="/images/retrofuturism.webp" // Path to the local image
|
||||
src="/images/retrofuturism.webp"
|
||||
alt="Retrospective Science Image"
|
||||
width={384} // Set width (in pixels)
|
||||
height={384} // Set height (in pixels)
|
||||
width={384}
|
||||
height={384}
|
||||
className="rounded-lg"
|
||||
/>
|
||||
</Link>
|
||||
</div>
|
||||
</div>
|
||||
<div className="right flex flex-col w-full">
|
||||
<div className="blogpost-label text-2xl mb-4">
|
||||
<h2>
|
||||
<AnimatedLink href={blogpost.get_absolute_url}>
|
||||
<Link href={blogpost.get_absolute_url}>
|
||||
{blogpost.label}
|
||||
</AnimatedLink>
|
||||
</Link>
|
||||
</h2>
|
||||
</div>
|
||||
<ul className="blogpost-tags inline-flex items-center flex-row space-x-4 mb-4">
|
||||
<li className="tag inline px-2 py-1 rounded-full"><Image src={tagsPic} alt="lang" width={24} height={24} className='inline-flex justify-baseline filter brightness-0 invert' /></li>
|
||||
<ul className="blogpost-tags inline-flex items-center flex-row space-x-3 mb-4">
|
||||
<li className="tag inline px-2 py-1 rounded-full">
|
||||
<FaTags className="inline-flex justify-baseline text-gray-800 dark:text-gray-200" size={24} />
|
||||
</li>
|
||||
{blogpost.tags.map((tag, index) => (
|
||||
<li className="tag inline border border-slate-400 px-2 py-1 rounded-full text-base">{tag}</li>
|
||||
<li key={`${tag}-${index}`} className="tag inline border border-gray-700 px-3 py-1 rounded-full text-base">
|
||||
<Link href="#">{tag}</Link>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
<div className="blogpost-description text-base mb-4">
|
||||
<div className="blogpost-description text-base mb-4 dark:text-gray-300 text-gray-800">
|
||||
{blogpost.body.slice(0, 512)}...
|
||||
</div>
|
||||
<div className="blogpost-other flex flex-row justify-between items-end mt-auto">
|
||||
<ul className="text-base inline-flex justify-end items-center">
|
||||
<li className="inline px-2 py-1"><Image src={calendarPic} alt="lang" width={24} height={24} className="filter brightness-0 invert"/></li>
|
||||
<li className="inline"><p className='inline mx-2'>{blogpost.publish}</p></li>
|
||||
</ul>
|
||||
|
||||
<div className="text-base inline-flex justify-end items-center">
|
||||
<div className="inline px-2 py-1">
|
||||
<FaCalendarAlt className="text-gray-800 dark:text-gray-200" size={24} />
|
||||
</div>
|
||||
<div className="inline">
|
||||
<p className='inline mx-2'>{blogpost.publish}</p>
|
||||
</div>
|
||||
</div>
|
||||
<div className="text-xl">
|
||||
<AnimatedLink href={blogpost.get_absolute_url}>
|
||||
Read the article
|
||||
</AnimatedLink>
|
||||
<Link href={blogpost.get_absolute_url}>
|
||||
Читать →
|
||||
</Link>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{index < blogposts.length - 1 && (
|
||||
<hr className="my-8 border-t border-gray-200 dark:border-gray-700" />
|
||||
)}
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
{/* Include Pagination Component Here */}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
47
components/footer/main.tsx
Normal file
@@ -0,0 +1,47 @@
|
||||
import Link from "next/link";
|
||||
import {
|
||||
FaMastodon,
|
||||
FaSteam
|
||||
} from "react-icons/fa";
|
||||
import { SiGitea } from "react-icons/si";
|
||||
|
||||
export default function MainFooter() {
|
||||
return (
|
||||
<footer className="border-t dark:border-white border-black pt-4 text-2xl">
|
||||
<div className="flex lg:flex-row max-md:flex-col justify-around items-start">
|
||||
<div className="m-4">
|
||||
<h3 className="text-xl mb-3">Socials</h3>
|
||||
<div className="flex items-center gap-4">
|
||||
<Link href="https://mastodon.social/@aderkonstantin"
|
||||
className="text-gray-800 dark:text-gray-200 hover:text-primary-500 dark:hover:text-primary-400 transition-colors">
|
||||
<FaMastodon size={32} />
|
||||
</Link>
|
||||
<Link href="https://code.bimka.space/AderKonstantin"
|
||||
className="text-gray-800 dark:text-gray-200 hover:text-primary-500 dark:hover:text-primary-400 transition-colors">
|
||||
<SiGitea size={32} />
|
||||
</Link>
|
||||
<Link href="https://steamcommunity.com/id/aderkonstantin/"
|
||||
className="text-gray-800 dark:text-gray-200 hover:text-primary-500 dark:hover:text-primary-400 transition-colors">
|
||||
<FaSteam size={32} />
|
||||
</Link>
|
||||
</div>
|
||||
</div>
|
||||
<div className="m-4">
|
||||
<div className="flex items-center gap-2 mb-3">
|
||||
<h3 className="text-xl inline">Other Projects</h3>
|
||||
</div>
|
||||
<div className="text-lg">
|
||||
<Link href="https://sihirtia.ru/"
|
||||
className="text-primary-500 hover:text-primary-600 dark:hover:text-primary-400 transition-colors">
|
||||
Sihirtia Softworks
|
||||
</Link>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="mt-8 md:text-center text-foreground-accent px-6">
|
||||
<p className="text-base mt-2 dark:text-gray-200 text-gray-700">Ader Konstantin © {new Date().getFullYear()}</p>
|
||||
<p className="text-sm my-2 text-gray-500">Made with ♥ by <Link href="https://aderk.org" target="_blank" className="text-primary-500 hover:text-primary-600">AderK</Link></p>
|
||||
</div>
|
||||
</footer>
|
||||
);
|
||||
}
|
||||
@@ -1,41 +1,35 @@
|
||||
import searchPic from '@/public/search.svg';
|
||||
|
||||
|
||||
import Image from "next/image";
|
||||
import Link from "next/link";
|
||||
import Toolbar from "./toolbar";
|
||||
import { IoSearch } from "react-icons/io5";
|
||||
|
||||
import AnimatedLink from '../animatedLink';
|
||||
import HeaderToolbar from "../header/toolbar";
|
||||
import AnimatedLink from "../animatedLink";
|
||||
|
||||
export default function MainHeader() {
|
||||
return (
|
||||
<header className="flex flex-col">
|
||||
<div className="flex flex-row mt-12 mb-22">
|
||||
<header className="flex flex-col mt-4">
|
||||
<div className="flex flex-row">
|
||||
<ul className="w-full flex flex-row justify-between items-baseline list-none">
|
||||
<li className="text-4xl">
|
||||
<AnimatedLink href="https://blog.aderk.tech/en">
|
||||
aderk.tech
|
||||
<AnimatedLink href="/">
|
||||
blog.aderk.org
|
||||
</AnimatedLink>
|
||||
</li>
|
||||
|
||||
<li className="text-6xl flex items-center justify-center filter brightness-0 invert">
|
||||
<li className="text-6xl flex items-center justify-center filter brightness-0 dark:invert">
|
||||
<Link href="#">
|
||||
<Image
|
||||
src={searchPic}
|
||||
alt="search"
|
||||
width={32}
|
||||
height={32}
|
||||
/>
|
||||
<IoSearch size={32} />
|
||||
</Link>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div className="text-2xl mb-20">
|
||||
<p className="leading-10">
|
||||
Hello. I am is a programmer, hacker, and gamer. Love comics, coding, read books. There I am posting articles about science and another staff, that’s im like.
|
||||
<div className="text-lg mb-4 mt-6">
|
||||
<p className="leading-8">
|
||||
Этот блог - хроника моего погружения в мир компьютерной архитектуры. <br />
|
||||
Здесь я документирую процесс изучения и проектирования CPU и GPU на основе открытой архитектуры RISC-V. <br />
|
||||
</p>
|
||||
</div>
|
||||
<HeaderToolbar />
|
||||
<Toolbar></Toolbar>
|
||||
</header>
|
||||
);
|
||||
}
|
||||
@@ -1,60 +1,32 @@
|
||||
'use client';
|
||||
import Image from 'next/image';
|
||||
import Link from 'next/link';
|
||||
import globePic from '../../public/globe.svg';
|
||||
import emailPic from '../../public/email.svg';
|
||||
import rssPic from '../../public/rss-feed.svg';
|
||||
import supportPic from '../../public/support.svg';
|
||||
import settingsPic from '../../public/settings.svg';
|
||||
import AnimatedLink from '../animatedLink';
|
||||
|
||||
"use client";
|
||||
import Link from "next/link";
|
||||
import { FaGlobe, FaEnvelope, FaRss } from "react-icons/fa";
|
||||
|
||||
export default function Toolbar() {
|
||||
return (
|
||||
<div className="flex h-24 justify-between items-center border-white border-t border-b">
|
||||
<div className="flex h-16 justify-between items-center dark:border-white border-black border-t border-b">
|
||||
<div className="flex items-baseline">
|
||||
<p><AnimatedLink href='#'>Science</AnimatedLink> | <AnimatedLink href='#'>Software</AnimatedLink> | <AnimatedLink href='#'>Hardware</AnimatedLink> | <AnimatedLink href='#'>Rockets</AnimatedLink> | <AnimatedLink href='#'>Startups</AnimatedLink></p>
|
||||
<p>
|
||||
<Link href="#">Science</Link> |{" "}
|
||||
<Link href="#">Software</Link> |{" "}
|
||||
<Link href="#">Hardware</Link>
|
||||
</p>
|
||||
</div>
|
||||
<div className="flex items-baseline">
|
||||
<ul className="inline-flex items-center gap-4">
|
||||
<li className="inline filter brightness-0 invert">
|
||||
<li className="inline text-gray-800 dark:text-gray-200 hover:text-primary-500 dark:hover:text-primary-400 transition-colors">
|
||||
<Link href="#">
|
||||
<Image
|
||||
src={globePic}
|
||||
alt="lang"
|
||||
width={32}
|
||||
height={32}
|
||||
/>
|
||||
<FaGlobe size={24} />
|
||||
</Link>
|
||||
</li>
|
||||
<li className="inline filter brightness-0 invert">
|
||||
<Link href="#">
|
||||
<Image
|
||||
src={emailPic}
|
||||
alt="email"
|
||||
width={32}
|
||||
height={32}
|
||||
/>
|
||||
<li className="inline text-gray-800 dark:text-gray-200 hover:text-primary-500 dark:hover:text-primary-400 transition-colors">
|
||||
<Link href="emailto:konstantin@aderk.org">
|
||||
<FaEnvelope size={24} />
|
||||
</Link>
|
||||
</li>
|
||||
<li className="inline filter brightness-0 invert">
|
||||
<li className="inline text-gray-800 dark:text-gray-200 hover:text-primary-500 dark:hover:text-primary-400 transition-colors">
|
||||
<Link href="#">
|
||||
<Image
|
||||
src={rssPic}
|
||||
alt="rss"
|
||||
width={32}
|
||||
height={32}
|
||||
/>
|
||||
</Link>
|
||||
</li>
|
||||
<li className="inline filter brightness-0 invert">
|
||||
<Link href="#">
|
||||
<Image
|
||||
src={settingsPic}
|
||||
alt="settings"
|
||||
width={32}
|
||||
height={32}
|
||||
/>
|
||||
<FaRss size={24} />
|
||||
</Link>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
95
lib/posts.ts
Normal file
@@ -0,0 +1,95 @@
|
||||
import fs from 'fs';
|
||||
import path from 'path';
|
||||
import matter from 'gray-matter';
|
||||
import { remark } from 'remark';
|
||||
import html from 'remark-html';
|
||||
import { unified } from 'unified';
|
||||
import remarkParse from 'remark-parse';
|
||||
import remarkGfm from 'remark-gfm';
|
||||
import remarkRehype from 'remark-rehype';
|
||||
import rehypeRaw from 'rehype-raw';
|
||||
import rehypeStringify from 'rehype-stringify';
|
||||
import rehypePrism from 'rehype-prism-plus';
|
||||
|
||||
const postsDirectory = path.join(process.cwd(), 'posts');
|
||||
|
||||
export interface PostData {
|
||||
slug: string;
|
||||
title: string;
|
||||
date: string;
|
||||
tags: string[];
|
||||
contentHtml: string;
|
||||
description: string;
|
||||
}
|
||||
|
||||
export function getAllPostSlugs(): string[] {
|
||||
const fileNames = fs.readdirSync(postsDirectory);
|
||||
return fileNames.map((fileName) => fileName.replace(/\.md$/, ''));
|
||||
}
|
||||
|
||||
export function getSortedPostsData(): Omit<PostData, 'contentHtml'>[] {
|
||||
const fileNames = fs.readdirSync(postsDirectory);
|
||||
const allPostsData = fileNames.map((fileName) => {
|
||||
const slug = fileName.replace(/\.md$/, '');
|
||||
const fullPath = path.join(postsDirectory, fileName);
|
||||
const fileContents = fs.readFileSync(fullPath, 'utf8');
|
||||
const matterResult = matter(fileContents);
|
||||
|
||||
return {
|
||||
slug,
|
||||
title: matterResult.data.title,
|
||||
date: matterResult.data.date,
|
||||
tags: matterResult.data.tags || [],
|
||||
description: matterResult.data.description || '',
|
||||
};
|
||||
});
|
||||
|
||||
return allPostsData.sort((a, b) => {
|
||||
if (a.date < b.date) {
|
||||
return 1;
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
export async function getPostData(slug: string): Promise<PostData | null> {
|
||||
try {
|
||||
const fullPath = path.join(postsDirectory, `${slug}.md`);
|
||||
|
||||
if (!fs.existsSync(fullPath)) {
|
||||
console.error(`Файл не найден: ${fullPath}`);
|
||||
return null;
|
||||
}
|
||||
|
||||
const fileContents = fs.readFileSync(fullPath, 'utf8');
|
||||
const matterResult = matter(fileContents);
|
||||
|
||||
// Используем unified pipeline с подсветкой синтаксиса
|
||||
const processedContent = await unified()
|
||||
.use(remarkParse) // парсим Markdown
|
||||
.use(remarkGfm) // добавляем поддержку GFM (таблицы и т.д.)
|
||||
.use(remarkRehype) // конвертируем в HTML AST
|
||||
.use(rehypePrism, {
|
||||
// Настройки подсветки
|
||||
showLineNumbers: true, // показывать номера строк
|
||||
ignoreMissing: true, // игнорировать неизвестные языки
|
||||
})
|
||||
.use(rehypeStringify) // сериализуем в строку
|
||||
.process(matterResult.content || '');
|
||||
|
||||
const contentHtml = processedContent.toString();
|
||||
|
||||
return {
|
||||
slug,
|
||||
contentHtml,
|
||||
title: matterResult.data.title || 'Без названия',
|
||||
date: matterResult.data.date || new Date().toISOString().split('T')[0],
|
||||
tags: matterResult.data.tags || [],
|
||||
description: matterResult.data.description || '',
|
||||
};
|
||||
} catch (error) {
|
||||
console.error(`Ошибка при загрузке поста ${slug}:`, error);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
2164
package-lock.json
generated
26
package.json
@@ -9,19 +9,35 @@
|
||||
"lint": "next lint"
|
||||
},
|
||||
"dependencies": {
|
||||
"@tailwindcss/typography": "^0.5.19",
|
||||
"gray-matter": "^4.0.3",
|
||||
"next": "15.2.0",
|
||||
"prism-react-renderer": "^2.4.1",
|
||||
"prismjs": "^1.30.0",
|
||||
"react": "^19.0.0",
|
||||
"react-dom": "^19.0.0",
|
||||
"next": "15.2.0"
|
||||
"react-icons": "^5.5.0",
|
||||
"react-syntax-highlighter": "^16.1.0",
|
||||
"rehype-prism-plus": "^2.0.1",
|
||||
"rehype-raw": "^7.0.0",
|
||||
"rehype-sanitize": "^6.0.0",
|
||||
"rehype-stringify": "^10.0.1",
|
||||
"remark": "^15.0.1",
|
||||
"remark-gfm": "^4.0.1",
|
||||
"remark-html": "^16.0.1",
|
||||
"remark-parse": "^11.0.0",
|
||||
"remark-rehype": "^11.1.2",
|
||||
"unified": "^11.0.5"
|
||||
},
|
||||
"devDependencies": {
|
||||
"typescript": "^5",
|
||||
"@eslint/eslintrc": "^3",
|
||||
"@tailwindcss/postcss": "^4",
|
||||
"@types/node": "^20",
|
||||
"@types/react": "^19",
|
||||
"@types/react-dom": "^19",
|
||||
"@tailwindcss/postcss": "^4",
|
||||
"tailwindcss": "^4",
|
||||
"eslint": "^9",
|
||||
"eslint-config-next": "15.2.0",
|
||||
"@eslint/eslintrc": "^3"
|
||||
"tailwindcss": "^4",
|
||||
"typescript": "^5"
|
||||
}
|
||||
}
|
||||
|
||||
11
posts/chisel.md
Normal file
@@ -0,0 +1,11 @@
|
||||
---
|
||||
title: "Создание и интеграция собственного процессорного ядра на базе RISC-V с использованием языка Chisel"
|
||||
date: "2025-12-21"
|
||||
tags: ["risc-v", "chisel", "hardware"]
|
||||
description: "Краткое описание"
|
||||
---
|
||||
|
||||
|
||||
# Заголовок статьи
|
||||
|
||||
Содержимое статьи в формате Markdown...
|
||||
191
posts/code-syntax.md
Normal file
@@ -0,0 +1,191 @@
|
||||
---
|
||||
title: "Пример кода с подсветкой"
|
||||
date: "2026-01-20"
|
||||
tags: ["code", "syntax", "programming"]
|
||||
---
|
||||
|
||||
# Примеры кода с подсветкой синтаксиса
|
||||
|
||||
## JavaScript
|
||||
|
||||
```javascript
|
||||
// Комментарий
|
||||
const hello = (name) => {
|
||||
console.log(`Hello, ${name}!`);
|
||||
|
||||
const numbers = [1, 2, 3, 4, 5];
|
||||
const doubled = numbers.map(n => n * 2);
|
||||
|
||||
return doubled;
|
||||
};
|
||||
|
||||
class Person {
|
||||
constructor(name, age) {
|
||||
this.name = name;
|
||||
this.age = age;
|
||||
}
|
||||
|
||||
greet() {
|
||||
return `Hi, I'm ${this.name}`;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Python
|
||||
|
||||
```python
|
||||
def fibonacci(n):
|
||||
"""Вычисляет числа Фибоначчи"""
|
||||
if n <= 1:
|
||||
return n
|
||||
else:
|
||||
return fibonacci(n-1) + fibonacci(n-2)
|
||||
|
||||
# Генератор списка
|
||||
squares = [x**2 for x in range(10)]
|
||||
|
||||
# Декоратор
|
||||
def timer(func):
|
||||
import time
|
||||
def wrapper(*args, **kwargs):
|
||||
start = time.time()
|
||||
result = func(*args, **kwargs)
|
||||
end = time.time()
|
||||
print(f"Время выполнения: {end - start} секунд")
|
||||
return result
|
||||
return wrapper
|
||||
```
|
||||
|
||||
## RISC-V Ассемблер
|
||||
|
||||
```asm
|
||||
# Простой цикл на RISC-V
|
||||
loop:
|
||||
addi t0, t0, 1 # t0 = t0 + 1
|
||||
addi t1, t1, -1 # t1 = t1 - 1
|
||||
bnez t1, loop # if t1 != 0, goto loop
|
||||
|
||||
# Функция сложения
|
||||
add_numbers:
|
||||
add a0, a0, a1 # a0 = a0 + a1
|
||||
ret # return
|
||||
```
|
||||
|
||||
## CSS
|
||||
|
||||
```css
|
||||
/* Кастомные свойства */
|
||||
:root {
|
||||
--primary-color: #3b82f6;
|
||||
--secondary-color: #10b981;
|
||||
--text-color: #374151;
|
||||
}
|
||||
|
||||
.container {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
|
||||
gap: 1rem;
|
||||
padding: 2rem;
|
||||
}
|
||||
|
||||
.button {
|
||||
background: linear-gradient(135deg, var(--primary-color), var(--secondary-color));
|
||||
color: white;
|
||||
padding: 0.75rem 1.5rem;
|
||||
border-radius: 0.5rem;
|
||||
transition: transform 0.2s;
|
||||
}
|
||||
|
||||
.button:hover {
|
||||
transform: translateY(-2px);
|
||||
}
|
||||
```
|
||||
|
||||
## Bash/Shell
|
||||
|
||||
```bash
|
||||
#!/bin/bash
|
||||
|
||||
# Скрипт для сборки проекта
|
||||
echo "Начало сборки..."
|
||||
|
||||
# Проверка зависимостей
|
||||
if ! command -v npm &> /dev/null; then
|
||||
echo "Ошибка: npm не установлен"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Установка зависимостей
|
||||
npm install
|
||||
|
||||
# Сборка проекта
|
||||
npm run build
|
||||
|
||||
echo "Сборка завершена успешно!"
|
||||
```
|
||||
|
||||
## SQL
|
||||
|
||||
```sql
|
||||
-- Создание таблицы пользователей
|
||||
CREATE TABLE users (
|
||||
id INT PRIMARY KEY AUTO_INCREMENT,
|
||||
username VARCHAR(50) NOT NULL UNIQUE,
|
||||
email VARCHAR(100) NOT NULL UNIQUE,
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
is_active BOOLEAN DEFAULT TRUE
|
||||
);
|
||||
|
||||
-- Запрос с JOIN
|
||||
SELECT
|
||||
u.username,
|
||||
o.order_id,
|
||||
o.total_amount,
|
||||
o.order_date
|
||||
FROM users u
|
||||
JOIN orders o ON u.id = o.user_id
|
||||
WHERE u.is_active = TRUE
|
||||
ORDER BY o.order_date DESC;
|
||||
```
|
||||
|
||||
## C++
|
||||
|
||||
```cpp
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
|
||||
// Шаблонная функция
|
||||
template<typename T>
|
||||
T find_max(const std::vector<T>& vec) {
|
||||
if (vec.empty()) {
|
||||
throw std::invalid_argument("Vector is empty");
|
||||
}
|
||||
|
||||
return *std::max_element(vec.begin(), vec.end());
|
||||
}
|
||||
|
||||
// Класс для работы с матрицами
|
||||
class Matrix {
|
||||
private:
|
||||
std::vector<std::vector<double>> data;
|
||||
int rows, cols;
|
||||
|
||||
public:
|
||||
Matrix(int r, int c) : rows(r), cols(c) {
|
||||
data.resize(r, std::vector<double>(c, 0.0));
|
||||
}
|
||||
|
||||
// Перегрузка оператора
|
||||
Matrix operator+(const Matrix& other) const {
|
||||
Matrix result(rows, cols);
|
||||
for (int i = 0; i < rows; i++) {
|
||||
for (int j = 0; j < cols; j++) {
|
||||
result.data[i][j] = data[i][j] + other.data[i][j];
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
};
|
||||
```
|
||||
|
||||
68
posts/riscv.md
Normal file
@@ -0,0 +1,68 @@
|
||||
---
|
||||
title: "RISC-V: Что такое и какие варианты для работы с RISC-V в России есть"
|
||||
date: "2025-12-21"
|
||||
tags: ["risc-v", "hardware"]
|
||||
description: "Подробно о том почему российские компании выбирают RISC-V и какие варианты для развития в данной сфере есть сейчас и что может появиться в будущем. "
|
||||
---
|
||||
|
||||
**RISC-V** (произносится «риск-файв») — это открытая и свободная архитектура набора команд (Instruction Set Architecture, ISA) для процессоров. В отличие от закрытых архитектур x86 (Intel, AMD) или ARM, спецификации RISC-V находятся в открытом доступе, а их использование не требует выплаты лицензионных отчислений. Это не конкретный процессор, а стандарт, на основе которого любая компания или исследовательская группа может разработать собственное ядро.
|
||||
|
||||
В условиях современных технологических ограничений RISC-V перестал быть просто академическим проектом и превратился в стратегическую возможность для создания независимой технологической базы.
|
||||
|
||||
## Ключевые особенности архитектуры
|
||||
|
||||
* **Открытость и свобода от лицензионных отчислений**: Базовая спецификация открыта, что позволяет избежать зависимости от зарубежных вендоров.
|
||||
* **Модульность**: Архитектура построена по принципу «базовый набор + расширения». Можно создать как простое встроенное ядро, так и сложный многоядерный процессор для серверов.
|
||||
* **Простота и элегантность**: Современный дизайн, лишенный исторического балласта, упрощает разработку и верификацию.
|
||||
* **Растущая экосистема**: Вокруг RISC-V сформировалось глобальное сообщество, развиваются инструменты (компиляторы GCC, LLVM), операционные системы (Linux, Zephyr) и средства симуляции.
|
||||
|
||||
## Почему RISC-V стал стратегическим выбором для России
|
||||
|
||||
1. **Технологическая независимость**: Архитектура предоставляет полный контроль над микроархитектурой. Это значит, что можно создавать процессоры без оглядки на экспортные ограничения и политику иностранных правообладателей.
|
||||
2. **Безопасность**: Открытость спецификации позволяет проводить глубокий аудит на уровне аппаратуры, исключая недокументированные возможности (backdoors).
|
||||
3. **Экономическая эффективность**: Отсутствие лицензионных платежей и возможность кастомизации под конкретную задачу (например, ускорение криптографических алгоритмов) снижают стоимость владения и ускоряют выход на рынок.
|
||||
4. **Развитие компетенций**: Работа с открытой архитектурой стимулирует рост фундаментальных знаний в области проектирования процессоров, а не только их применения.
|
||||
|
||||
## Варианты для работы с RISC-V в России: настоящее и ближайшее будущее
|
||||
|
||||
### 1. Образование и развитие кадров
|
||||
Освоение RISC-V начинается с обучения. Уже сегодня доступны несколько путей:
|
||||
* **Вузовские программы**: Ведущие технические университеты (МФТИ, МИФИ, ИТМО, СПбПУ) постепенно включают RISC-V в учебные курсы по архитектуре компьютеров и системному программированию.
|
||||
* **Онлайн-курсы и вебинары**: Российские технологические компании и энтузиасты проводят открытые лекции и практикумы по основам RISC-V.
|
||||
* **Лаборатории и хакатоны**: Появляются студенческие проектные лаборатории, где можно получить практический опыт в проектировании простых ядер на ПЛИС (например, на платах SiFive или отечественных аналогах).
|
||||
|
||||
### 2. Промышленные разработки и коммерческие продукты
|
||||
Ряд российских компаний уже делает ставку на RISC-V:
|
||||
* **СКБ Контур**: Разработала серию 32-битных микроконтроллеров **K1986ВК028** на ядре RISC-V (BA25) для встраиваемых систем.
|
||||
* **Yadro**: Анонсировала планы по созданию собственных процессоров на основе RISC-V для инфраструктурных решений.
|
||||
* **Ростех и дочерние структуры**: Ведется исследование и разработка процессорных решений для специализированных применений (промышленная автоматизация, телеком).
|
||||
* **Научные центры (КНЦ РАН, ИППМ РАН)**: Активно участвуют в исследовании и создании прототипов высокопроизводительных ядер, работают над инструментами верификации и отладки.
|
||||
|
||||
### 3. Проекты с открытым исходным кодом
|
||||
Это фундамент для будущего развития:
|
||||
* **Участие в глобальных проектах**: Российские разработчики вносят вклад в международные open-source проекты, такие как ядро Linux, компиляторы, симуляторы QEMU и эмулятор Spike.
|
||||
* **Создание отечественных открытых ядер**: Разработка и публикация в открытом доступе собственных процессорных ядер (например, на языке Chisel или SystemVerilog) для образовательных и промышленных целей.
|
||||
* **Развитие экосистемы ПО**: Адаптация и оптимизация операционных систем (Astra Linux, Альт), компиляторов и middleware под RISC-V-платформы.
|
||||
|
||||
### 4. Государственные инициативы и поддержка
|
||||
* **Стратегические программы**: RISC-V упоминается в ключевых документах по развитию электронной промышленности и импортозамещению как одна из приоритетных архитектур.
|
||||
* **Грантовая поддержка**: Фонды (Сколково, ФСИ) и министерства финансируют НИОКР и стартапы в области проектирования процессоров и создания инструментальной базы.
|
||||
* **Стандартизация**: Ведутся работы по гармонизации отечественных требований по информационной безопасности с возможностями архитектуры RISC-V.
|
||||
|
||||
## Будущее RISC-V в России: перспективы и вызовы
|
||||
|
||||
**Сценарии развития на 5-10 лет:**
|
||||
|
||||
1. **Доминирование в нишевых и встраиваемых системах**: Микроконтроллеры на RISC-V станут стандартом для IoT, промышленной автоматизации, автомобильной электроники.
|
||||
2. **Выход в сегмент высокопроизводительных вычислений**: Появление первых отечественных серверных и HPC-процессоров на оптимизированных многоядерных RISC-V-архитектурах.
|
||||
3. **Формирование полного технологического цикла**: От проектирования и производства (с учетом развития отечественных техпроцессов) до создания законченных программно-аппаратных комплексов.
|
||||
4. **Интеграция в учебные программы**: RISC-V станет основной архитектурой для обучения в российских инженерных вузах, что обеспечит постоянный приток квалифицированных кадров.
|
||||
|
||||
**Ключевые вызовы:**
|
||||
* **Создание конкурентоспособной производственной базы** (процессоры требуют современных техпроцессов).
|
||||
* **Масштабирование экосистемы**: Необходимо привлечь широкий круг разработчиков прикладного ПО.
|
||||
* **Конкуренция с устоявшимися решениями**: Потребуются убедительные экономические и технологические аргументы для перехода с ARM и x86.
|
||||
|
||||
## Заключение
|
||||
|
||||
RISC-V — это не просто технологическая альтернатива, а **новая парадигма развития микроэлектроники**. Для России она представляет собой уникальный исторический шанс построить независимую, безопасную и конкурентоспособную отрасль проектирования процессоров. Успех будет зависеть от слаженных усилий государства, бизнеса, науки и образовательных учреждений. Уже сегодня каждый разработчик, студент или компания, начинающая работу с RISC-V, вносит вклад в создание фундамента для цифрового суверенитета страны. Будущее архитектуры в России выглядит многообещающе, и окно возможностей открыто как никогда.
|
||||
131
posts/styles.md
Normal file
@@ -0,0 +1,131 @@
|
||||
---
|
||||
title: "Тест Markdown разметки"
|
||||
date: "2026-01-19"
|
||||
tags: ["test", "markdown"]
|
||||
description: "Тестирование поддержки таблиц и списков в Markdown"
|
||||
---
|
||||
|
||||
# Тест Markdown разметки
|
||||
|
||||
## Списки
|
||||
|
||||
### Ненумерованный список
|
||||
- Первый пункт
|
||||
- Второй пункт
|
||||
- Вложенный пункт 1
|
||||
- Вложенный пункт 2
|
||||
- Третий пункт
|
||||
|
||||
### Нумерованный список
|
||||
1. Первый пункт
|
||||
2. Второй пункт
|
||||
1. Вложенный пункт 1
|
||||
2. Вложенный пункт 2
|
||||
3. Третий пункт
|
||||
|
||||
### Список задач
|
||||
- [x] Сделать поддержку таблиц
|
||||
- [ ] Добавить подсветку синтаксиса
|
||||
- [ ] Настроить стили
|
||||
|
||||
## Таблицы
|
||||
|
||||
### Простая таблица
|
||||
| Заголовок 1 | Заголовок 2 | Заголовок 3 |
|
||||
|-------------|-------------|-------------|
|
||||
| Ячейка 1 | Ячейка 2 | Ячейка 3 |
|
||||
| Ячейка 4 | Ячейка 5 | Ячейка 6 |
|
||||
|
||||
### Таблица с выравниванием
|
||||
| Левый | По центру | Правый | Числа |
|
||||
|:------|:---------:|-------:|------:|
|
||||
| текст | текст | текст | 1000 |
|
||||
| данные| данные | данные| 200 |
|
||||
| еще | еще | еще | 3 |
|
||||
|
||||
### Сложная таблица
|
||||
| Процессор | Архитектура | Частота | Ядра |
|
||||
|-----------|-------------|---------|------|
|
||||
| Cortex-A78 | ARM | 2.8 GHz | 8 |
|
||||
| Rocket | RISC-V | 1.5 GHz | 4 |
|
||||
| x86-64 | x86 | 3.5 GHz | 16 |
|
||||
|
||||
## Код
|
||||
|
||||
```python
|
||||
def hello():
|
||||
print("Hello World")
|
||||
|
||||
def calculate(a, b):
|
||||
return a + b
|
||||
```
|
||||
|
||||
|
||||
```cpp
|
||||
#include <iostream>
|
||||
#include <cstring>
|
||||
|
||||
using namespace std;
|
||||
|
||||
void quicksort(char *items, int len);
|
||||
void qs(char *items, int left, int right);
|
||||
|
||||
int main() {
|
||||
setlocale(LC_ALL, "ru_RU.UTF-8");
|
||||
char str[] = "jfmckldoelazlkper";
|
||||
int i;
|
||||
|
||||
cout << "Исходный массив: " << str << "\n";
|
||||
quicksort(str, strlen(str));
|
||||
|
||||
cout << "Отсортированный массив: " << str << "\n";
|
||||
return 0;
|
||||
}
|
||||
|
||||
void quicksort(char *items, int len)
|
||||
{
|
||||
qs(items, 0, len-1);
|
||||
}
|
||||
|
||||
void qs(char *items, int left, int right)
|
||||
{
|
||||
int i, j;
|
||||
char x, y;
|
||||
i = left, j = right;
|
||||
x = items[( left+right) / 2];
|
||||
do {
|
||||
while ((items[i] < x) && (i < right)) i++;
|
||||
while ((x < items[j]) && (j > left)) j--;
|
||||
|
||||
if (i <= j) {
|
||||
y = items[i];
|
||||
items[i] = items[j];
|
||||
items[j] = y;
|
||||
i++; j--;
|
||||
}
|
||||
} while (i <= j);
|
||||
|
||||
if(left < j) qs(items, left, j);
|
||||
if(i < right) qs(items, i, right);
|
||||
}
|
||||
```
|
||||
|
||||
## Цитата
|
||||
|
||||
> Это важная цитата из статьи о RISC-V
|
||||
> Вторая строка цитаты
|
||||
|
||||
## Ссылки и изображения
|
||||
|
||||
[Ссылка на RISC-V](https://riscv.org)
|
||||
|
||||

|
||||
|
||||
## Горизонтальная линия
|
||||
|
||||
---
|
||||
|
||||
**RISC-V** (произносится «риск-файв») — это открытая и свободная архитектура набора команд (Instruction Set Architecture, ISA) для процессоров. В отличие от закрытых архитектур x86 (Intel, AMD) или ARM, спецификации RISC-V находятся в открытом доступе, а их использование не требует выплаты лицензионных отчислений. Это не конкретный процессор, а стандарт, на основе которого любая компания или исследовательская группа может разработать собственное ядро.
|
||||
|
||||
В условиях современных технологических ограничений RISC-V перестал быть просто академическим проектом и превратился в стратегическую возможность для создания независимой технологической базы.
|
||||
|
||||
@@ -1,16 +0,0 @@
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="24"
|
||||
height="24"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
stroke-width="2"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
>
|
||||
<rect x="3" y="4" width="18" height="18" rx="2" ry="2" />
|
||||
<line x1="16" y1="2" x2="16" y2="6" />
|
||||
<line x1="8" y1="2" x2="8" y2="6" />
|
||||
<line x1="3" y1="10" x2="21" y2="10" />
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 390 B |
@@ -1,3 +0,0 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 20 16">
|
||||
<path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="m19 2-8.4 7.05a1 1 0 0 1-1.2 0L1 2m18 0a1 1 0 0 0-1-1H2a1 1 0 0 0-1 1m18 0v12a1 1 0 0 1-1 1H2a1 1 0 0 1-1-1V2"/>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 290 B |
@@ -1,11 +0,0 @@
|
||||
<svg width="24" height="24" viewBox="0 0 24 24" stroke-width="1.5" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M17.5 17.5C20 21 23.9486 18.4151 23 15C21.5753 9.87113 20.8001 7.01556 20.3969 5.50793C20.1597 4.62136 19.3562 4 18.4384 4L5.56155 4C4.64382 4 3.844 4.62481 3.62085 5.515C2.7815 8.86349 2.0326 11.8016 1.14415 15C0.195501 18.4151 4.14415 21 6.64415 17.5" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M18 8.5L18.0111 8.51" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M16.49 7L16.5011 7.01" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M16.49 10L16.5011 10.01" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M15 8.5L15.0111 8.51" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M7 7V10" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M5.5 8.5H8.5" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M8 16C9.10457 16 10 15.1046 10 14C10 12.8954 9.10457 12 8 12C6.89543 12 6 12.8954 6 14C6 15.1046 6.89543 16 8 16Z" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M16 16C17.1046 16 18 15.1046 18 14C18 12.8954 17.1046 12 16 12C14.8954 12 14 12.8954 14 14C14 15.1046 14.8954 16 16 16Z" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 1.4 KiB |
@@ -1 +0,0 @@
|
||||
<svg viewBox="0 0 496 512" xmlns="http://www.w3.org/2000/svg"><path d="m165.9 397.4c0 2-2.3 3.6-5.2 3.6-3.3.3-5.6-1.3-5.6-3.6 0-2 2.3-3.6 5.2-3.6 3-.3 5.6 1.3 5.6 3.6zm-31.1-4.5c-.7 2 1.3 4.3 4.3 4.9 2.6 1 5.6 0 6.2-2s-1.3-4.3-4.3-5.2c-2.6-.7-5.5.3-6.2 2.3zm44.2-1.7c-2.9.7-4.9 2.6-4.6 4.9.3 2 2.9 3.3 5.9 2.6 2.9-.7 4.9-2.6 4.6-4.6-.3-1.9-3-3.2-5.9-2.9zm65.8-383.2c-138.7 0-244.8 105.3-244.8 244 0 110.9 69.8 205.8 169.5 239.2 12.8 2.3 17.3-5.6 17.3-12.1 0-6.2-.3-40.4-.3-61.4 0 0-70 15-84.7-29.8 0 0-11.4-29.1-27.8-36.6 0 0-22.9-15.7 1.6-15.4 0 0 24.9 2 38.6 25.8 21.9 38.6 58.6 27.5 72.9 20.9 2.3-16 8.8-27.1 16-33.7-55.9-6.2-112.3-14.3-112.3-110.5 0-27.5 7.6-41.3 23.6-58.9-2.6-6.5-11.1-33.3 2.6-67.9 20.9-6.5 69 27 69 27 20-5.6 41.5-8.5 62.8-8.5s42.8 2.9 62.8 8.5c0 0 48.1-33.6 69-27 13.7 34.7 5.2 61.4 2.6 67.9 16 17.7 25.8 31.5 25.8 58.9 0 96.5-58.9 104.2-114.8 110.5 9.2 7.9 17 22.9 17 46.4 0 33.7-.3 75.4-.3 83.6 0 6.5 4.6 14.4 17.3 12.1 100-33.2 167.8-128.1 167.8-239 0-138.7-112.5-244-251.2-244zm-147.6 344.9c-1.3 1-1 3.3.7 5.2 1.6 1.6 3.9 2.3 5.2 1 1.3-1 1-3.3-.7-5.2-1.6-1.6-3.9-2.3-5.2-1zm-10.8-8.1c-.7 1.3.3 2.9 2.3 3.9 1.6 1 3.6.7 4.3-.7.7-1.3-.3-2.9-2.3-3.9-2-.6-3.6-.3-4.3.7zm32.4 35.6c-1.6 1.3-1 4.3 1.3 6.2 2.3 2.3 5.2 2.6 6.5 1 1.3-1.3.7-4.3-1.3-6.2-2.2-2.3-5.2-2.6-6.5-1zm-11.4-14.7c-1.6 1-1.6 3.6 0 5.9s4.3 3.3 5.6 2.3c1.6-1.3 1.6-3.9 0-6.2-1.4-2.3-4-3.3-5.6-2z"/></svg>
|
||||
|
Before Width: | Height: | Size: 1.4 KiB |
@@ -1,3 +0,0 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 21 20">
|
||||
<path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6.487 1.746c0 4.192 3.592 1.66 4.592 5.754 0 .828 1 1.5 2 1.5s2-.672 2-1.5a1.5 1.5 0 0 1 1.5-1.5h1.5m-16.02.471c4.02 2.248 1.776 4.216 4.878 5.645C10.18 13.61 9 19 9 19m9.366-6h-2.287a3 3 0 0 0-3 3v2m6-8a9 9 0 1 1-18 0 9 9 0 0 1 18 0Z"/>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 416 B |
@@ -1 +0,0 @@
|
||||
<svg fill="none" height="24" viewBox="0 0 24 24" width="24" xmlns="http://www.w3.org/2000/svg"><path clip-rule="evenodd" d="m7.46494 1.066c1.17334-.05378 1.54734-.066 4.53506-.066 2.9883 0 3.3617.01283 4.5344.066 1.1715.05317 1.9715.23956 2.6712.5115.7339.27631 1.3987.70924 1.9482 1.26867.5595.54943.9925 1.21429 1.2687 1.94822.2719.69972.4577 1.49967.5115 2.67055.0538 1.17334.066 1.54734.066 4.53506 0 2.9877-.0128 3.3617-.066 4.5351-.0532 1.1708-.2396 1.9708-.5115 2.6705-.2811.723-.6576 1.3371-1.2687 1.9482-.5494.5595-1.2143.9925-1.9482 1.2687-.6997.2719-1.4997.4577-2.6705.5115-1.1734.0538-1.5474.066-4.5351.066-2.98772 0-3.36172-.0128-4.53506-.066-1.17088-.0532-1.97083-.2396-2.67055-.5115-.72295-.2811-1.33711-.6576-1.94822-1.2687-.55953-.5494-.99249-1.2143-1.26867-1.9482-.27194-.6997-.45772-1.4997-.5115-2.6705-.05378-1.1734-.066-1.5468-.066-4.5351 0-2.98833.01283-3.36172.066-4.53444.05317-1.1715.23956-1.97145.5115-2.67117.27631-.73388.70924-1.39871 1.26867-1.94822.54942-.55953 1.21428-.99249 1.94822-1.26867.69972-.27194 1.49967-.45772 2.67055-.5115zm8.98026 1.98c-1.1599-.05256-1.5082-.06417-4.4452-.06417s-3.28533.01161-4.44522.06417c-1.0725.04889-1.65489.22794-2.04234.37889-.51333.19922-.88.43755-1.265.82255-.38438.385-.62333.75167-.82255 1.265-.15095.38745-.33.96984-.37889 2.04234-.05256 1.15989-.06417 1.50822-.06417 4.44522s.01161 3.2853.06417 4.4452c.04889 1.0725.22794 1.6549.37889 2.0424.17622.4778.4573.91.82255 1.265.3549.3652.78717.6463 1.265.8225.38745.151.96984.33 2.04234.3789 1.15989.0526 1.50761.0642 4.44522.0642 2.9376 0 3.2853-.0116 4.4452-.0642 1.0725-.0489 1.6549-.2279 2.0424-.3789.5133-.1992.88-.4375 1.265-.8225.3652-.3549.6463-.7872.8225-1.265.151-.3875.33-.9699.3789-2.0424.0526-1.1599.0642-1.5082.0642-4.4452s-.0116-3.28533-.0642-4.44522c-.0489-1.0725-.2279-1.65489-.3789-2.04234-.1992-.51333-.4375-.88-.8225-1.265-.385-.38438-.7517-.62333-1.265-.82255-.3875-.15095-.9699-.33-2.0424-.37889zm-5.8497 12.3449c.4453.1845.9225.2794 1.4045.2794.9735 0 1.907-.3867 2.5953-1.075.6884-.6883 1.0751-1.6219 1.0751-2.5953s-.3867-1.907-1.0751-2.59532c-.6883-.68832-1.6218-1.07502-2.5953-1.07502-.482 0-.9592.09494-1.4045.27939-.4454.18445-.84997.4548-1.19079.79563-.34082.34082-.61118.74542-.79563 1.19072s-.27938.9226-.27938 1.4046.09493.9593.27938 1.4046.45481.8499.79563 1.1907.74539.6112 1.19079.7956zm-2.59345-7.38889c1.06033-1.06033 2.49845-1.65602 3.99795-1.65602 1.4996 0 2.9377.59569 3.998 1.65602s1.656 2.49849 1.656 3.99799-.5957 2.9376-1.656 3.998c-1.0603 1.0603-2.4984 1.656-3.998 1.656-1.4995 0-2.93762-.5957-3.99795-1.656-1.06033-1.0604-1.65602-2.4985-1.65602-3.998s.59569-2.93766 1.65602-3.99799zm10.90565-.81363c.2506-.25065.3914-.59059.3914-.94505 0-.35447-.1408-.69441-.3914-.94505-.2507-.25064-.5906-.39145-.9451-.39145-.3544 0-.6944.14081-.945.39145-.2507.25064-.3915.59058-.3915.94505 0 .35446.1408.6944.3915.94505.2506.25064.5906.39145.945.39145.3545 0 .6944-.14081.9451-.39145z" fill="#000" fill-rule="evenodd"/></svg>
|
||||
|
Before Width: | Height: | Size: 2.9 KiB |
@@ -1 +0,0 @@
|
||||
<svg height="24" viewBox="0 0 24 24" width="24" xmlns="http://www.w3.org/2000/svg"><path d="m20.94 14c-.28 1.41-2.44 2.96-4.97 3.26-1.31.15-2.6.3-3.97.24-2.25-.11-4-.54-4-.54v.62c.32 2.22 2.22 2.35 4.03 2.42 1.82.05 3.44-.46 3.44-.46l.08 1.65s-1.28.68-3.55.81c-1.25.07-2.81-.03-4.62-.5-3.92-1.05-4.6-5.24-4.7-9.5l-.01-3.43c0-4.34 2.83-5.61 2.83-5.61 1.45-.66 3.91-.96 6.47-.96h.06c2.56 0 5.02.3 6.47.96 0 0 2.83 1.27 2.83 5.61 0 0 .04 3.21-.39 5.43m-2.94-5.09c0-1.08-.3-1.91-.85-2.56-.56-.63-1.3-.96-2.23-.96-1.06 0-1.87.41-2.42 1.23l-.5.88-.5-.88c-.56-.82-1.36-1.23-2.43-1.23-.92 0-1.66.33-2.23.96-.55.65-.84 1.48-.84 2.56v5.26h2.1v-5.11c0-1.06.45-1.62 1.36-1.62 1 0 1.5.65 1.5 1.93v2.79h2.07v-2.79c0-1.28.5-1.93 1.51-1.93.9 0 1.35.56 1.35 1.62v5.11h2.11z"/></svg>
|
||||
|
Before Width: | Height: | Size: 765 B |
@@ -1,3 +0,0 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 18 20">
|
||||
<path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M8.509 5.75c0-1.493.394-2.96 1.144-4.25h-.081a8.5 8.5 0 1 0 7.356 12.746A8.5 8.5 0 0 1 8.509 5.75Z"/>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 279 B |
@@ -1 +0,0 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M19,6.5H16v-1a3,3,0,0,0-3-3H11a3,3,0,0,0-3,3v1H5a3,3,0,0,0-3,3v9a3,3,0,0,0,3,3H19a3,3,0,0,0,3-3v-9A3,3,0,0,0,19,6.5Zm-9-1a1,1,0,0,1,1-1h2a1,1,0,0,1,1,1v1H10Zm10,13a1,1,0,0,1-1,1H5a1,1,0,0,1-1-1V13a21.71,21.71,0,0,0,8,1.53A21.75,21.75,0,0,0,20,13Zm0-7.69a19.89,19.89,0,0,1-16,0V9.5a1,1,0,0,1,1-1H19a1,1,0,0,1,1,1Z"/></svg>
|
||||
|
Before Width: | Height: | Size: 390 B |
@@ -1 +0,0 @@
|
||||
<svg height="24" preserveAspectRatio="xMinYMin" viewBox="-4 -4 24 24" width="24" xmlns="http://www.w3.org/2000/svg"><path d="m1.996 15.97a1.996 1.996 0 1 1 0-3.992 1.996 1.996 0 0 1 0 3.992zm-.876-7.993a.998.998 0 0 1 -.247-1.98 8.103 8.103 0 0 1 9.108 8.04v.935a.998.998 0 1 1 -1.996 0v-.934a6.108 6.108 0 0 0 -6.865-6.06zm-1.12-6.912a.998.998 0 0 1 .93-1.063c7.787-.519 14.518 5.372 15.037 13.158.042.626.042 1.254 0 1.88a.998.998 0 1 1 -1.992-.133c.036-.538.036-1.077 0-1.614-.445-6.686-6.225-11.745-12.91-11.299a.998.998 0 0 1 -1.065-.93z"/></svg>
|
||||
|
Before Width: | Height: | Size: 551 B |
@@ -1,6 +0,0 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 20 20">
|
||||
<g stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2">
|
||||
<path d="M19 11V9a1 1 0 0 0-1-1h-.757l-.707-1.707.535-.536a1 1 0 0 0 0-1.414l-1.414-1.414a1 1 0 0 0-1.414 0l-.536.535L12 2.757V2a1 1 0 0 0-1-1H9a1 1 0 0 0-1 1v.757l-1.707.707-.536-.535a1 1 0 0 0-1.414 0L2.929 4.343a1 1 0 0 0 0 1.414l.536.536L2.757 8H2a1 1 0 0 0-1 1v2a1 1 0 0 0 1 1h.757l.707 1.707-.535.536a1 1 0 0 0 0 1.414l1.414 1.414a1 1 0 0 0 1.414 0l.536-.535L8 17.243V18a1 1 0 0 0 1 1h2a1 1 0 0 0 1-1v-.757l1.707-.708.536.536a1 1 0 0 0 1.414 0l1.414-1.414a1 1 0 0 0 0-1.414l-.535-.536.707-1.707H18a1 1 0 0 0 1-1Z"/>
|
||||
<path d="M10 13a3 3 0 1 0 0-6 3 3 0 0 0 0 6Z"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 757 B |
@@ -1 +0,0 @@
|
||||
<svg viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path d="m11.979 0c-6.301 0-11.468 4.86-11.957 11.037l6.432 2.658c.545-.371 1.203-.59 1.912-.59.063 0 .125.004.188.006l2.861-4.142v-.059c0-2.495 2.028-4.524 4.524-4.524 2.494 0 4.524 2.031 4.524 4.527s-2.03 4.525-4.524 4.525h-.105l-4.076 2.911c0 .052.004.105.004.159 0 1.875-1.515 3.396-3.39 3.396-1.635 0-3.016-1.173-3.331-2.727l-4.605-1.907c1.426 5.037 6.05 8.73 11.543 8.73 6.627 0 11.999-5.373 11.999-12s-5.373-12-11.999-12zm-4.439 18.21-1.473-.61c.262.543.714.999 1.314 1.25 1.297.539 2.793-.076 3.332-1.375.263-.63.264-1.319.005-1.949s-.75-1.121-1.377-1.383c-.624-.26-1.29-.249-1.878-.03l1.523.63c.956.4 1.409 1.5 1.009 2.455-.397.957-1.497 1.41-2.454 1.012zm11.415-9.303c0-1.662-1.353-3.015-3.015-3.015-1.665 0-3.015 1.353-3.015 3.015 0 1.665 1.35 3.015 3.015 3.015 1.663 0 3.015-1.35 3.015-3.015zm-5.273-.005c0-1.252 1.013-2.266 2.265-2.266 1.249 0 2.266 1.014 2.266 2.266 0 1.251-1.017 2.265-2.266 2.265-1.253 0-2.265-1.014-2.265-2.265z"/></svg>
|
||||
|
Before Width: | Height: | Size: 1014 B |
@@ -1,3 +0,0 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 20 20">
|
||||
<path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M10 3V1m0 18v-2M5.05 5.05 3.636 3.636m12.728 12.728L14.95 14.95M3 10H1m18 0h-2M5.05 14.95l-1.414 1.414M16.364 3.636 14.95 5.05M14 10a4 4 0 1 1-8 0 4 4 0 0 1 8 0Z"/>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 342 B |
@@ -1 +0,0 @@
|
||||
<svg fill="none" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg"><g fill="#000"><path d="m7.824 5.937a1 1 0 0 0 .726-.312 2.042 2.042 0 0 1 2.835-.065 1 1 0 0 0 1.388-1.441 3.994 3.994 0 0 0 -5.674.13 1 1 0 0 0 .725 1.688z"/><path d="m17 7a7 7 0 1 0 -14 0 3 3 0 0 0 -3 3v2a3 3 0 0 0 3 3h1a1 1 0 0 0 1-1v-7a5 5 0 1 1 10 0v7.083a2.92 2.92 0 0 1 -2.917 2.917h-.083a2 2 0 0 0 -2-2h-1a2 2 0 0 0 -2 2v1a2 2 0 0 0 2 2h1a1.993 1.993 0 0 0 1.722-1h.361a4.92 4.92 0 0 0 4.824-4h.093a3 3 0 0 0 3-3v-2a3 3 0 0 0 -3-3z"/></g></svg>
|
||||
|
Before Width: | Height: | Size: 525 B |
@@ -1,5 +0,0 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512">
|
||||
<path fill="var(--ci-primary-color, currentColor)" d="M511.974,271.891a47.744,47.744,0,0,0-14.706-33.008L311.57,57.98a29.9,29.9,0,0,0-21.2-8.731H257.228l217.754,212.6.092.088a15.907,15.907,0,0,1,.741,22.337l-156.4,173.355,21.953,21.356L499.447,305.85A47.748,47.748,0,0,0,511.974,271.891Z" class="ci-primary"/>
|
||||
<path fill="var(--ci-primary-color, currentColor)" d="M426.9,283.161a23.924,23.924,0,0,0-5.231-24.742c-.106-.111-.2-.231-.306-.34L224.307,57.716l-.094-.094a31.791,31.791,0,0,0-22.628-9.373H60.194A44.244,44.244,0,0,0,16,92.443v141.1a32.121,32.121,0,0,0,10.045,23.28l210.32,200.2.077.073a23.817,23.817,0,0,0,16.409,6.508q.447,0,.9-.017a24.111,24.111,0,0,0,6.741-1.217,23.854,23.854,0,0,0,10.047-6.517L421.983,291.232A24.033,24.033,0,0,0,426.9,283.161ZM252.5,428.2,48.077,233.612,48,233.54V92.443A12.208,12.208,0,0,1,60.194,80.249h141.39l191.7,194.918Z" class="ci-primary"/>
|
||||
<path fill="var(--ci-primary-color, currentColor)" d="M140,112a52,52,0,1,0,52,52A52.059,52.059,0,0,0,140,112Zm0,72a20,20,0,1,1,20-20A20.023,20.023,0,0,1,140,184Z" class="ci-primary"/>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 1.1 KiB |