fix: форматирование, опечатка в статье

This commit is contained in:
Astronit 2026-02-23 12:27:32 +00:00
parent 2860cf8374
commit 07141970c9
133 changed files with 17036 additions and 15 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 46 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 48 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 71 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 88 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 76 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 167 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 56 KiB

File diff suppressed because it is too large Load Diff

View File

@ -16,7 +16,7 @@ showComments: true
└── dev ← development (dev.blog.ru)
```
**Принцип:** Одна папка, две ветки. Переключение через `git checkout`, не через разные директории.
>[!IMPORTANT] **Принцип:** Одна папка, две ветки. Переключение через `git checkout`, не через разные директории.
---
@ -395,4 +395,4 @@ git push origin main
---
**Помни:** Dev для экспериментов, main для проверенного контента. Всегда тестируй перед публикацией.
>[!IMPORTANT] **Важно:** `Dev` для экспериментов, `main` для проверенного контента. Всегда тестируй перед публикацией.

View File

@ -13,7 +13,7 @@ series_order: 6
Мораль была проста: **чисти за собой**. Сегодня делаем именно это - переносим Gitea из старого namespace в `oakazanin` и удаляем старый namespace навсегда.
Заодно разберём универсальный алгоритм миграции, который работает для любого сервиса. Показываю на примере Gitea, но всё описанное применимо к любому stateful сервису PostgreSQL, MySQL, Nextcloud, MinIO. Принципы одинаковые: экспортируй манифесты, поменяй namespace, создай новое перед удалением старого.
Заодно разберём универсальный алгоритм миграции, который работает для любого сервиса. Показываю на примере Gitea, но всё описанное применимо к любому stateful сервису - PostgreSQL, MySQL, Nextcloud, MinIO. Принципы одинаковые: экспортируй манифесты, поменяй namespace, создай новое перед удалением старого.
---
@ -311,16 +311,16 @@ curl -s -o /dev/null -w "%{http_code}" https://git.example.com # 200
- Данные остаются нетронутыми
**Nextcloud:**
- Аналогично файлы на NFS не переносятся
- Аналогично - файлы на NFS не переносятся
- Только манифесты меняют namespace
- Zero downtime если создаёшь новое до удаления старого
**MinIO (S3-хранилище):**
- Stateful, работает через PV/PVC
- Те же принципы новый namespace, тот же NFS путь
- Те же принципы - новый namespace, тот же NFS путь
**Stateless сервисы (nginx, API):**
- Ещё проще нет PV/PVC вообще
- Ещё проще - нет PV/PVC вообще
- Только Deployment + Service, меняешь namespace, готово
Главный принцип: **данные живут на PV, который привязан к NFS. Namespace меняется, путь на NFS остаётся.**

View File

@ -898,10 +898,10 @@
<div class="article-content max-w-prose mb-20">
<p>Привет! Меня зовут Олег. За 20 лет в IT проблемы росли вместе со мной: от «почему не печатает принтер» до «почему три сервера не могут договориться, кто из них главный». Техподдержка научила терпению там быстро понимаешь, что «не работает» может означать что угодно, от выключенного монитора до сбоя на другом континенте. Сети научили начинать диагностику с розетки, а не с теории заговора. Системное администрирование что между «всё работает» и «всё сломалось» обычно стоит один непрочитанный warning в логах трёхнедельной давности.</p>
<p>Сейчас я инфраструктурный инженер. Строю и чиню серверную инфраструктуру: много enterprise, ещё больше Open Source, изрядно импортозамещённого в общем, всё что работает на Linux, с Linux и благодаря Linux. Работаю в Главгосэкспертизе России. Общаюсь с серверами на Bash, Python и прочих машинопонятных языках. Иногда серверы даже отвечают. Живу в Москве.</p>
<p>Дома лаборатория. Нет, не стойка в подвале (хотя идея заманчивая). Один сервер, но серьёзный: виртуализация, Kubernetes, хранилище, мониторинг — всё по-взрослому, но если что-то упало — нет многомиллионных издержек и мир не остановился. Идеальный полигон: придумал, реализовал, сломал, починил, задокументировал. Полный цикл.</p>
<p>Этот блог не enterprise-гайды для внедрения в банке. Это production, но в человеческом масштабе: домашний сервер, небольшая компания, стартап на трёх разработчиках. Решения, которые реально работают — просто без бюджета на команду SRE из десяти человек — инженеров надёжности, чьи зарплаты съедают бюджет стартапа за квартал. Документирую грабли, чтобы вы на них не наступали. Чем больнее наступил сам тем подробнее статья.</p>
<p>Привет! Меня зовут Олег. За 20 лет в IT проблемы росли вместе со мной: от «почему не печатает принтер» до «почему три сервера не могут договориться, кто из них главный». Техподдержка научила терпению - там быстро понимаешь, что «не работает» может означать что угодно, от выключенного монитора до сбоя на другом континенте. Сети научили начинать диагностику с розетки, а не с теории заговора. Системное администрирование - что между «всё работает» и «всё сломалось» обычно стоит один непрочитанный warning в логах трёхнедельной давности.</p>
<p>Сейчас я инфраструктурный инженер. Строю и чиню серверную инфраструктуру: много enterprise, ещё больше Open Source, изрядно импортозамещённого - в общем, всё что работает на Linux, с Linux и благодаря Linux. Работаю в Главгосэкспертизе России. Общаюсь с серверами на Bash, Python и прочих машинопонятных языках. Иногда серверы даже отвечают. Живу в Москве.</p>
<p>Дома - лаборатория. Нет, не стойка в подвале (хотя идея заманчивая). Один сервер, но серьёзный: виртуализация, Kubernetes, хранилище, мониторинг - всё по-взрослому, но если что-то упало - нет многомиллионных издержек и мир не остановился. Идеальный полигон: придумал, реализовал, сломал, починил, задокументировал. Полный цикл.</p>
<p>Этот блог - не enterprise-гайды для внедрения в банке. Это production, но в человеческом масштабе: домашний сервер, небольшая компания, стартап на трёх разработчиках. Решения, которые реально работают - просто без бюджета на команду SRE из десяти человек - инженеров надёжности, чьи зарплаты съедают бюджет стартапа за квартал. Документирую грабли, чтобы вы на них не наступали. Чем больнее наступил сам - тем подробнее статья.</p>

View File

@ -1155,8 +1155,13 @@
<div class="highlight-wrapper"><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="cl">~/projects/blog/ ← одна папка, две ветки
</span></span><span class="line"><span class="cl"> ├── main ← production (blog.ru)
</span></span><span class="line"><span class="cl"> └── dev ← development (dev.blog.ru)</span></span></code></pre></div></div>
<p><strong>Принцип:</strong> Одна папка, две ветки. Переключение через <code>git checkout</code>, не через разные директории.</p>
<hr>
<div class="admonition relative overflow-hidden rounded-lg border-l-4 my-3 px-4 py-3 shadow-sm" data-type="important">
<div class="flex items-center gap-2 font-semibold text-inherit">
<div class="flex shrink-0 h-5 w-5 items-center justify-center text-lg"><span class="relative block icon"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512"><path fill="currentColor" d="M287.9 0C297.1 0 305.5 5.25 309.5 13.52L378.1 154.8L531.4 177.5C540.4 178.8 547.8 185.1 550.7 193.7C553.5 202.4 551.2 211.9 544.8 218.2L433.6 328.4L459.9 483.9C461.4 492.9 457.7 502.1 450.2 507.4C442.8 512.7 432.1 513.4 424.9 509.1L287.9 435.9L150.1 509.1C142.9 513.4 133.1 512.7 125.6 507.4C118.2 502.1 114.5 492.9 115.1 483.9L142.2 328.4L31.11 218.2C24.65 211.9 22.36 202.4 25.2 193.7C28.03 185.1 35.5 178.8 44.49 177.5L197.7 154.8L266.3 13.52C270.4 5.249 278.7 0 287.9 0L287.9 0zM287.9 78.95L235.4 187.2C231.9 194.3 225.1 199.3 217.3 200.5L98.98 217.9L184.9 303C190.4 308.5 192.9 316.4 191.6 324.1L171.4 443.7L276.6 387.5C283.7 383.7 292.2 383.7 299.2 387.5L404.4 443.7L384.2 324.1C382.9 316.4 385.5 308.5 391 303L476.9 217.9L358.6 200.5C350.7 199.3 343.9 194.3 340.5 187.2L287.9 78.95z"/></svg></span></div>
<div class="grow">
<strong>Принцип:</strong> Одна папка, две ветки. Переключение через <code>git checkout</code>, не через разные директории.
</div>
</div></div><hr>
<h2 class="relative group">Золотые правила
<div id="золотые-правила" class="anchor"></div>
@ -1618,8 +1623,13 @@
</span></span><span class="line"><span class="cl">git merge dev --no-edit
</span></span><span class="line"><span class="cl">git push origin main</span></span></code></pre></div></div>
<hr>
<p><strong>Помни:</strong> Dev для экспериментов, main для проверенного контента. Всегда тестируй перед публикацией.</p>
<div class="admonition relative overflow-hidden rounded-lg border-l-4 my-3 px-4 py-3 shadow-sm" data-type="important">
<div class="flex items-center gap-2 font-semibold text-inherit">
<div class="flex shrink-0 h-5 w-5 items-center justify-center text-lg"><span class="relative block icon"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512"><path fill="currentColor" d="M287.9 0C297.1 0 305.5 5.25 309.5 13.52L378.1 154.8L531.4 177.5C540.4 178.8 547.8 185.1 550.7 193.7C553.5 202.4 551.2 211.9 544.8 218.2L433.6 328.4L459.9 483.9C461.4 492.9 457.7 502.1 450.2 507.4C442.8 512.7 432.1 513.4 424.9 509.1L287.9 435.9L150.1 509.1C142.9 513.4 133.1 512.7 125.6 507.4C118.2 502.1 114.5 492.9 115.1 483.9L142.2 328.4L31.11 218.2C24.65 211.9 22.36 202.4 25.2 193.7C28.03 185.1 35.5 178.8 44.49 177.5L197.7 154.8L266.3 13.52C270.4 5.249 278.7 0 287.9 0L287.9 0zM287.9 78.95L235.4 187.2C231.9 194.3 225.1 199.3 217.3 200.5L98.98 217.9L184.9 303C190.4 308.5 192.9 316.4 191.6 324.1L171.4 443.7L276.6 387.5C283.7 383.7 292.2 383.7 299.2 387.5L404.4 443.7L384.2 324.1C382.9 316.4 385.5 308.5 391 303L476.9 217.9L358.6 200.5C350.7 199.3 343.9 194.3 340.5 187.2L287.9 78.95z"/></svg></span></div>
<div class="grow">
<strong>Важно:</strong> <code>Dev</code> для экспериментов, <code>main</code> для проверенного контента. Всегда тестируй перед публикацией.
</div>
</div></div>
@ -3282,6 +3292,34 @@
<footer class="pt-8 max-w-prose print:hidden">
<div class="pt-8">
<hr class="border-dotted border-neutral-300 dark:border-neutral-600">
<div class="flex justify-between pt-3">
<span class="flex flex-col">
</span>
<span class="flex flex-col items-end">
<a
class="flex text-right text-neutral-700 hover:text-primary-600 dark:text-neutral dark:hover:text-primary-400"
href="/cheatsheets/shortcodes/">
<span class="leading-6">
Shortcodes&ensp;<span class="inline-block rtl:rotate-180">&rarr;</span>
</span>
</a>
<span class="me-6 mt-1 text-xs text-neutral-500 dark:text-neutral-400">
<time datetime="0001-01-01T00:00:00&#43;00:00">1 января 0001</time>
</span>
</span>
</div>
</div>

View File

@ -1020,6 +1020,285 @@
<article class="article-link--simple flex flex-col md:flex-row relative">
<div class="flex-none relative overflow-hidden thumbnail-shadow md:mr-7 thumbnail">
<img
src="/img/background_hu_7658a5e11b3ad5f2.png"
role="presentation"
loading="lazy"
decoding="async"
class="not-prose absolute inset-0 w-full h-full object-cover">
</div>
<div class=" mt-3 md:mt-0">
<header class="items-center text-start text-xl font-semibold">
<a
href="/cheatsheets/shortcodes/"
class="not-prose before:absolute before:inset-0 decoration-primary-500 dark:text-neutral text-xl font-bold text-neutral-800 hover:underline hover:underline-offset-2">
<h2>
Shortcodes
</h2>
</a>
<div class="ms-2"><span class="flex cursor-pointer">
<span
class="rounded-md border border-primary-400 px-1 py-[1px] text-xs font-normal text-primary-700 dark:border-primary-600 dark:text-primary-400">
Черновик
</span>
</span>
</div>
</header>
<div class="text-sm text-neutral-500 dark:text-neutral-400">
<div class="flex flex-row flex-wrap items-center">
<time datetime="0001-01-01T00:00:00&#43;00:00">1 января 0001</time><span class="px-2 text-primary-500">&middot;</span><span title="Время чтения">17 минут</span><span class="px-2 text-primary-500">&middot;</span><span>
<span
id="views_cheatsheets/blowfish-shortcodes/index.md"
class="animate-pulse inline-block text-transparent max-h-3 rounded-full -mt-[2px] align-middle bg-neutral-300 dark:bg-neutral-400"
title="views"
>loading</span
>
<span class="inline-block align-text-bottom"><span class="relative block icon"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512">
<path fill="currentColor" d="M288 32c-80.8 0-145.5 36.8-192.6 80.6C48.6 156 17.3 208 2.5 243.7c-3.3 7.9-3.3 16.7 0 24.6C17.3 304 48.6 356 95.4 399.4C142.5 443.2 207.2 480 288 480s145.5-36.8 192.6-80.6c46.8-43.5 78.1-95.4 93-131.1c3.3-7.9 3.3-16.7 0-24.6c-14.9-35.7-46.2-87.7-93-131.1C433.5 68.8 368.8 32 288 32zM432 256c0 79.5-64.5 144-144 144s-144-64.5-144-144s64.5-144 144-144s144 64.5 144 144zM288 192c0 35.3-28.7 64-64 64c-11.5 0-22.3-3-31.6-8.4c-.2 2.8-.4 5.5-.4 8.4c0 53 43 96 96 96s96-43 96-96s-43-96-96-96c-2.8 0-5.6 .1-8.4 .4c5.3 9.3 8.4 20.1 8.4 31.6z"/></svg></span></span>
</span>
<span class="px-2 text-primary-500">&middot;</span><span>
<span
id="likes_cheatsheets/blowfish-shortcodes/index.md"
class="animate-pulse inline-block text-transparent max-h-3 rounded-full -mt-[2px] align-middle bg-neutral-300 dark:bg-neutral-400"
title="likes"
>loading</span
>
<span class="inline-block align-text-bottom"><span class="relative block icon"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512">
<path fill="currentColor" d="M47.6 300.4L228.3 469.1c7.5 7 17.4 10.9 27.7 10.9s20.2-3.9 27.7-10.9L464.4 300.4c30.4-28.3 47.6-68 47.6-109.5v-5.8c0-69.9-50.5-129.5-119.4-141C347 36.5 300.6 51.4 268 84L256 96 244 84c-32.6-32.6-79-47.5-124.6-39.9C50.5 55.6 0 115.2 0 185.1v5.8c0 41.5 17.2 81.2 47.6 109.5z"/></svg></span></span>
</span>
</div>
<div class="flex flex-row flex-wrap items-center">
<a class="relative mt-[0.5rem] me-2" href="/tags/shortcodes/">
<span class="flex cursor-pointer">
<span
class="rounded-md border border-primary-400 px-1 py-[1px] text-xs font-normal text-primary-700 dark:border-primary-600 dark:text-primary-400">
Shortcodes
</span>
</span>
</a>
<a class="relative mt-[0.5rem] me-2" href="/tags/mermaid/">
<span class="flex cursor-pointer">
<span
class="rounded-md border border-primary-400 px-1 py-[1px] text-xs font-normal text-primary-700 dark:border-primary-600 dark:text-primary-400">
Mermaid
</span>
</span>
</a>
<a class="relative mt-[0.5rem] me-2" href="/tags/icon/">
<span class="flex cursor-pointer">
<span
class="rounded-md border border-primary-400 px-1 py-[1px] text-xs font-normal text-primary-700 dark:border-primary-600 dark:text-primary-400">
Icon
</span>
</span>
</a>
<a class="relative mt-[0.5rem] me-2" href="/tags/lead/">
<span class="flex cursor-pointer">
<span
class="rounded-md border border-primary-400 px-1 py-[1px] text-xs font-normal text-primary-700 dark:border-primary-600 dark:text-primary-400">
Lead
</span>
</span>
</a>
<a class="relative mt-[0.5rem] me-2" href="/tags/docs/">
<span class="flex cursor-pointer">
<span
class="rounded-md border border-primary-400 px-1 py-[1px] text-xs font-normal text-primary-700 dark:border-primary-600 dark:text-primary-400">
Docs
</span>
</span>
</a>
</div>
</div>
</div>
<div class="px-6 pt-4 pb-2"></div>
</article>
</section>

View File

@ -11,6 +11,16 @@
<copyright>© 2026 Олег Казанин</copyright>
<lastBuildDate>Mon, 23 Feb 2026 00:00:00 +0000</lastBuildDate><atom:link href="http://192.168.11.190:1313/cheatsheets/index.xml" rel="self" type="application/rss+xml" />
<item>
<title>Shortcodes</title>
<link>http://192.168.11.190:1313/cheatsheets/shortcodes/</link>
<pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
<author>oakazanin@ya.ru (Олег Казанин)</author>
<guid>http://192.168.11.190:1313/cheatsheets/shortcodes/</guid>
<description></description>
</item>
<item>
<title>Git Workflow для Hugo блога</title>
<link>http://192.168.11.190:1313/cheatsheets/git-workflow/</link>

Binary file not shown.

After

Width:  |  Height:  |  Size: 46 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 127 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 59 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 48 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 109 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 55 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 71 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 125 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 66 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 88 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 76 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 167 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 56 KiB

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,65 @@
/* Carousel Specific Styles */
.ratio-16-9 {
padding-top: 56.25%;
}
.ratio-21-9 {
padding-top: 42.85%;
}
.ratio-32-9 {
padding-top: 28.125%;
}
@media (width >= 640px) {
.sm\:ratio-16-9 {
padding-top: 56.25%;
}
.sm\:ratio-21-9 {
padding-top: 42.85%;
}
.sm\:ratio-32-9 {
padding-top: 28.125%;
}
}
@media (width >= 853px) {
.md\:ratio-16-9 {
padding-top: 56.25%;
}
.md\:ratio-21-9 {
padding-top: 42.85%;
}
.md\:ratio-32-9 {
padding-top: 28.125%;
}
}
@media (width >= 1024px) {
.lg\:ratio-16-9 {
padding-top: 56.25%;
}
.lg\:ratio-21-9 {
padding-top: 42.85%;
}
.lg\:ratio-32-9 {
padding-top: 28.125%;
}
}
@media (width >= 1280px) {
.xl\:ratio-16-9 {
padding-top: 56.25%;
}
.xl\:ratio-21-9 {
padding-top: 42.85%;
}
.xl\:ratio-32-9 {
padding-top: 28.125%;
}
}
@media (width >= 1536px) {
.\32xl\:ratio-16-9 {
padding-top: 56.25%;
}
.\32xl\:ratio-21-9 {
padding-top: 42.85%;
}
.\32xl\:ratio-32-9 {
padding-top: 28.125%;
}
}

View File

@ -0,0 +1,595 @@
/* Gallery Specific Styles */
.grid-w10 {
width: calc(10% - 5px);
margin: 0px !important;
}
.grid-w15 {
width: calc(15% - 5px);
margin: 0px !important;
}
.grid-w20 {
width: calc(20% - 5px);
margin: 0px !important;
}
.grid-w25 {
width: calc(25% - 5px);
margin: 0px !important;
}
.grid-w30 {
width: calc(30% - 5px);
margin: 0px !important;
}
.grid-w33 {
width: calc(33% - 5px);
margin: 0px !important;
}
.grid-w35 {
width: calc(35% - 5px);
margin: 0px !important;
}
.grid-w40 {
width: calc(40% - 5px);
margin: 0px !important;
}
.grid-w45 {
width: calc(45% - 5px);
margin: 0px !important;
}
.grid-w50 {
width: calc(50% - 5px);
margin: 0px !important;
}
.grid-w55 {
width: calc(55% - 5px);
margin: 0px !important;
}
.grid-w60 {
width: calc(60% - 5px);
margin: 0px !important;
}
.grid-w65 {
width: calc(65% - 5px);
margin: 0px !important;
}
.grid-w66 {
width: calc(66% - 5px);
margin: 0px !important;
}
.grid-w70 {
width: calc(70% - 5px);
margin: 0px !important;
}
.grid-w75 {
width: calc(75% - 5px);
margin: 0px !important;
}
.grid-w80 {
width: calc(80% - 5px);
margin: 0px !important;
}
.grid-w85 {
width: calc(85% - 5px);
margin: 0px !important;
}
.grid-w90 {
width: calc(90% - 5px);
margin: 0px !important;
}
.grid-w95 {
width: calc(95% - 5px);
margin: 0px !important;
}
.grid-w100 {
width: calc(100% - 5px);
margin: 0px !important;
}
.gallery figure {
display: inline-block;
margin: 0;
}
.gallery figcaption {
margin-top: 0.25rem;
font-size: 0.875rem;
line-height: 1.25rem;
color: rgb(var(--color-neutral-600));
}
.dark .gallery figcaption {
color: rgb(var(--color-neutral-400));
}
@media (width >= 640px) {
.sm\:grid-w10 {
width: calc(10% - 5px);
margin: 0px !important;
}
.sm\:grid-w15 {
width: calc(15% - 5px);
margin: 0px !important;
}
.sm\:grid-w20 {
width: calc(20% - 5px);
margin: 0px !important;
}
.sm\:grid-w25 {
width: calc(25% - 5px);
margin: 0px !important;
}
.sm\:grid-w30 {
width: calc(30% - 5px);
margin: 0px !important;
}
.sm\:grid-w33 {
width: calc(33% - 5px);
margin: 0px !important;
}
.sm\:grid-w35 {
width: calc(35% - 5px);
margin: 0px !important;
}
.sm\:grid-w40 {
width: calc(40% - 5px);
margin: 0px !important;
}
.sm\:grid-w45 {
width: calc(45% - 5px);
margin: 0px !important;
}
.sm\:grid-w50 {
width: calc(50% - 5px);
margin: 0px !important;
}
.sm\:grid-w55 {
width: calc(55% - 5px);
margin: 0px !important;
}
.sm\:grid-w60 {
width: calc(60% - 5px);
margin: 0px !important;
}
.sm\:grid-w65 {
width: calc(65% - 5px);
margin: 0px !important;
}
.sm\:grid-w66 {
width: calc(66% - 5px);
margin: 0px !important;
}
.sm\:grid-w70 {
width: calc(70% - 5px);
margin: 0px !important;
}
.sm\:grid-w75 {
width: calc(75% - 5px);
margin: 0px !important;
}
.sm\:grid-w80 {
width: calc(80% - 5px);
margin: 0px !important;
}
.sm\:grid-w85 {
width: calc(85% - 5px);
margin: 0px !important;
}
.sm\:grid-w90 {
width: calc(90% - 5px);
margin: 0px !important;
}
.sm\:grid-w95 {
width: calc(95% - 5px);
margin: 0px !important;
}
.sm\:grid-w100 {
width: calc(100% - 5px);
margin: 0px !important;
}
}
@media (width >= 853px) {
.md\:grid-w10 {
width: calc(10% - 5px);
margin: 0px !important;
}
.md\:grid-w15 {
width: calc(15% - 5px);
margin: 0px !important;
}
.md\:grid-w20 {
width: calc(20% - 5px);
margin: 0px !important;
}
.md\:grid-w25 {
width: calc(25% - 5px);
margin: 0px !important;
}
.md\:grid-w30 {
width: calc(30% - 5px);
margin: 0px !important;
}
.md\:grid-w33 {
width: calc(33% - 5px);
margin: 0px !important;
}
.md\:grid-w35 {
width: calc(35% - 5px);
margin: 0px !important;
}
.md\:grid-w40 {
width: calc(40% - 5px);
margin: 0px !important;
}
.md\:grid-w45 {
width: calc(45% - 5px);
margin: 0px !important;
}
.md\:grid-w50 {
width: calc(50% - 5px);
margin: 0px !important;
}
.md\:grid-w55 {
width: calc(55% - 5px);
margin: 0px !important;
}
.md\:grid-w60 {
width: calc(60% - 5px);
margin: 0px !important;
}
.md\:grid-w65 {
width: calc(65% - 5px);
margin: 0px !important;
}
.md\:grid-w66 {
width: calc(66% - 5px);
margin: 0px !important;
}
.md\:grid-w70 {
width: calc(70% - 5px);
margin: 0px !important;
}
.md\:grid-w75 {
width: calc(75% - 5px);
margin: 0px !important;
}
.md\:grid-w80 {
width: calc(80% - 5px);
margin: 0px !important;
}
.md\:grid-w85 {
width: calc(85% - 5px);
margin: 0px !important;
}
.md\:grid-w90 {
width: calc(90% - 5px);
margin: 0px !important;
}
.md\:grid-w95 {
width: calc(95% - 5px);
margin: 0px !important;
}
.md\:grid-w100 {
width: calc(100% - 5px);
margin: 0px !important;
}
}
@media (width >= 1024px) {
.lg\:grid-w10 {
width: calc(10% - 5px);
margin: 0px !important;
}
.lg\:grid-w15 {
width: calc(15% - 5px);
margin: 0px !important;
}
.lg\:grid-w20 {
width: calc(20% - 5px);
margin: 0px !important;
}
.lg\:grid-w25 {
width: calc(25% - 5px);
margin: 0px !important;
}
.lg\:grid-w30 {
width: calc(30% - 5px);
margin: 0px !important;
}
.lg\:grid-w33 {
width: calc(33% - 5px);
margin: 0px !important;
}
.lg\:grid-w35 {
width: calc(35% - 5px);
margin: 0px !important;
}
.lg\:grid-w40 {
width: calc(40% - 5px);
margin: 0px !important;
}
.lg\:grid-w45 {
width: calc(45% - 5px);
margin: 0px !important;
}
.lg\:grid-w50 {
width: calc(50% - 5px);
margin: 0px !important;
}
.lg\:grid-w55 {
width: calc(55% - 5px);
margin: 0px !important;
}
.lg\:grid-w60 {
width: calc(60% - 5px);
margin: 0px !important;
}
.lg\:grid-w65 {
width: calc(65% - 5px);
margin: 0px !important;
}
.lg\:grid-w66 {
width: calc(66% - 5px);
margin: 0px !important;
}
.lg\:grid-w70 {
width: calc(70% - 5px);
margin: 0px !important;
}
.lg\:grid-w75 {
width: calc(75% - 5px);
margin: 0px !important;
}
.lg\:grid-w80 {
width: calc(80% - 5px);
margin: 0px !important;
}
.lg\:grid-w85 {
width: calc(85% - 5px);
margin: 0px !important;
}
.lg\:grid-w90 {
width: calc(90% - 5px);
margin: 0px !important;
}
.lg\:grid-w95 {
width: calc(95% - 5px);
margin: 0px !important;
}
.lg\:grid-w100 {
width: calc(100% - 5px);
margin: 0px !important;
}
}
@media (width >= 1280px) {
.xl\:grid-w10 {
width: calc(10% - 5px);
margin: 0px !important;
}
.xl\:grid-w15 {
width: calc(15% - 5px);
margin: 0px !important;
}
.xl\:grid-w20 {
width: calc(20% - 5px);
margin: 0px !important;
}
.xl\:grid-w25 {
width: calc(25% - 5px);
margin: 0px !important;
}
.xl\:grid-w30 {
width: calc(30% - 5px);
margin: 0px !important;
}
.xl\:grid-w33 {
width: calc(33% - 5px);
margin: 0px !important;
}
.xl\:grid-w35 {
width: calc(35% - 5px);
margin: 0px !important;
}
.xl\:grid-w40 {
width: calc(40% - 5px);
margin: 0px !important;
}
.xl\:grid-w45 {
width: calc(45% - 5px);
margin: 0px !important;
}
.xl\:grid-w50 {
width: calc(50% - 5px);
margin: 0px !important;
}
.xl\:grid-w55 {
width: calc(55% - 5px);
margin: 0px !important;
}
.xl\:grid-w60 {
width: calc(60% - 5px);
margin: 0px !important;
}
.xl\:grid-w65 {
width: calc(65% - 5px);
margin: 0px !important;
}
.xl\:grid-w66 {
width: calc(66% - 5px);
margin: 0px !important;
}
.xl\:grid-w70 {
width: calc(70% - 5px);
margin: 0px !important;
}
.xl\:grid-w75 {
width: calc(75% - 5px);
margin: 0px !important;
}
.xl\:grid-w80 {
width: calc(80% - 5px);
margin: 0px !important;
}
.xl\:grid-w85 {
width: calc(85% - 5px);
margin: 0px !important;
}
.xl\:grid-w90 {
width: calc(90% - 5px);
margin: 0px !important;
}
.xl\:grid-w95 {
width: calc(95% - 5px);
margin: 0px !important;
}
.xl\:grid-w100 {
width: calc(100% - 5px);
margin: 0px !important;
}
}
@media (width >= 1536px) {
.\32xl\:grid-w10 {
width: calc(10% - 5px);
margin: 0px !important;
}
.\32xl\:grid-w15 {
width: calc(15% - 5px);
margin: 0px !important;
}
.\32xl\:grid-w20 {
width: calc(20% - 5px);
margin: 0px !important;
}
.\32xl\:grid-w25 {
width: calc(25% - 5px);
margin: 0px !important;
}
.\32xl\:grid-w30 {
width: calc(30% - 5px);
margin: 0px !important;
}
.\32xl\:grid-w33 {
width: calc(33% - 5px);
margin: 0px !important;
}
.\32xl\:grid-w35 {
width: calc(35% - 5px);
margin: 0px !important;
}
.\32xl\:grid-w40 {
width: calc(40% - 5px);
margin: 0px !important;
}
.\32xl\:grid-w45 {
width: calc(45% - 5px);
margin: 0px !important;
}
.\32xl\:grid-w50 {
width: calc(50% - 5px);
margin: 0px !important;
}
.\32xl\:grid-w55 {
width: calc(55% - 5px);
margin: 0px !important;
}
.\32xl\:grid-w60 {
width: calc(60% - 5px);
margin: 0px !important;
}
.\32xl\:grid-w65 {
width: calc(65% - 5px);
margin: 0px !important;
}
.\32xl\:grid-w66 {
width: calc(66% - 5px);
margin: 0px !important;
}
.\32xl\:grid-w70 {
width: calc(70% - 5px);
margin: 0px !important;
}
.\32xl\:grid-w75 {
width: calc(75% - 5px);
margin: 0px !important;
}
.\32xl\:grid-w80 {
width: calc(80% - 5px);
margin: 0px !important;
}
.\32xl\:grid-w85 {
width: calc(85% - 5px);
margin: 0px !important;
}
.\32xl\:grid-w90 {
width: calc(90% - 5px);
margin: 0px !important;
}
.\32xl\:grid-w95 {
width: calc(95% - 5px);
margin: 0px !important;
}
.\32xl\:grid-w100 {
width: calc(100% - 5px);
margin: 0px !important;
}
}
.ratio-16-9 {
padding-top: 56.25%;
}
.ratio-21-9 {
padding-top: 42.85%;
}
.ratio-32-9 {
padding-top: 28.125%;
}
@media (width >= 640px) {
.sm\:ratio-16-9 {
padding-top: 56.25%;
}
.sm\:ratio-21-9 {
padding-top: 42.85%;
}
.sm\:ratio-32-9 {
padding-top: 28.125%;
}
}
@media (width >= 853px) {
.md\:ratio-16-9 {
padding-top: 56.25%;
}
.md\:ratio-21-9 {
padding-top: 42.85%;
}
.md\:ratio-32-9 {
padding-top: 28.125%;
}
}
@media (width >= 1024px) {
.lg\:ratio-16-9 {
padding-top: 56.25%;
}
.lg\:ratio-21-9 {
padding-top: 42.85%;
}
.lg\:ratio-32-9 {
padding-top: 28.125%;
}
}
@media (width >= 1280px) {
.xl\:ratio-16-9 {
padding-top: 56.25%;
}
.xl\:ratio-21-9 {
padding-top: 42.85%;
}
.xl\:ratio-32-9 {
padding-top: 28.125%;
}
}
@media (width >= 1536px) {
.\32xl\:ratio-16-9 {
padding-top: 56.25%;
}
.\32xl\:ratio-21-9 {
padding-top: 42.85%;
}
.\32xl\:ratio-32-9 {
padding-top: 28.125%;
}
}

File diff suppressed because one or more lines are too long

View File

@ -11,6 +11,16 @@
<copyright>© 2026 Олег Казанин</copyright>
<lastBuildDate>Mon, 23 Feb 2026 00:00:00 +0000</lastBuildDate><atom:link href="http://192.168.11.190:1313/index.xml" rel="self" type="application/rss+xml" />
<item>
<title>Shortcodes</title>
<link>http://192.168.11.190:1313/cheatsheets/shortcodes/</link>
<pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
<author>oakazanin@ya.ru (Олег Казанин)</author>
<guid>http://192.168.11.190:1313/cheatsheets/shortcodes/</guid>
<description></description>
</item>
<item>
<title>Git Workflow для Hugo блога</title>
<link>http://192.168.11.190:1313/cheatsheets/git-workflow/</link>

View File

@ -0,0 +1 @@
(async()=>{const n=document.currentScript,s=n?.getAttribute("data-repo-url"),e=n?.getAttribute("data-repo-id");if(!s||!e)return;if(e.startsWith("forgejo")){console.log("fetch-repo.js: Forgejo server blocks cross-origin requests. Live JavaScript updates are not supported.");return}const o={github:{full_name:"full_name",description:"description",stargazers_count:"stargazers",forks:"forks"},gitlab:{name_with_namespace:"name_with_namespace",description:"description",star_count:"star_count",forks_count:"forks_count"},gitea:{full_name:"full_name",description:"description",stars_count:"stars_count",forks_count:"forks_count"},codeberg:{full_name:"full_name",description:"description",stars_count:"stars_count",forks_count:"forks_count"},forgejo:{full_name:"full_name",description:"description",stars_count:"stars_count",forks_count:"forks_count"},huggingface:{description:"description",likes:"likes",downloads:"downloads"}},i={huggingface:{description:e=>e?.replace(/Dataset Card for .+?\s+Dataset Summary\s+/,"").trim()||e}},t=Object.keys(o).find(t=>e.startsWith(t))||"github",a=o[t];try{const n=await fetch(s,{headers:{"User-agent":"Mozilla/4.0 Custom User Agent"}}),o=await n.json();if(!n.ok){console.error(`fetch-repo.js: HTTP Error: ${n.status} ${n.statusText}`);return}if(!o||typeof o!="object"){console.error("fetch-repo.js: Invalid or empty data received from remote");return}Object.entries(a).forEach(([n,s])=>{const a=document.getElementById(`${e}-${s}`);if(a){let e=o[n];i[t]?.[n]&&(e=i[t][n](e)),e!=null&&e!==""&&(a.innerHTML=e)}})}catch(e){console.error(`fetch-repo.js: ${e}`)}})()

View File

@ -0,0 +1 @@
function _getDefaultPackeryOptions(){return{percentPosition:!0,gutter:5,resize:!0}}function _getPackeryOptions(e){const t=_getDefaultPackeryOptions(),{packeryGutter:n,packeryPercentPosition:s,packeryResize:o}=e.dataset;return{percentPosition:s!==0[0]?s==="true":t.percentPosition,gutter:n!==0[0]?parseInt(n,10):t.gutter,resize:o!==0[0]?o==="true":t.resize}}(function(){window.addEventListener("load",function(){let e=[],t=document.querySelectorAll(".gallery");t.forEach(t=>{let n=new Packery(t,_getPackeryOptions(t));e.push(n)})})})()

View File

@ -0,0 +1 @@
function initTabs(){tabClickHandler=e=>{const t=e.target.closest(".tab__button");if(!t)return;const n=t.closest(".tab__container"),o=parseInt(t.dataset.tabIndex),i=t.dataset.tabLabel,s=n.dataset.tabGroup;if(s){const e=document.querySelectorAll(`.tab__container[data-tab-group="${s}"]`);e.forEach(e=>{const t=Array.from(e.querySelectorAll(".tab__button")).find(e=>e.dataset.tabLabel===i);if(t){const n=parseInt(t.dataset.tabIndex);activateTab(e,n)}})}else activateTab(n,o)},document.addEventListener("click",tabClickHandler)}function activateTab(e,t){const n=e.querySelectorAll(".tab__button"),s=e.querySelectorAll(".tab__panel");n.forEach((e,n)=>{n===t?(e.classList.add("tab--active"),e.setAttribute("aria-selected","true")):(e.classList.remove("tab--active"),e.setAttribute("aria-selected","false"))}),s.forEach((e,n)=>{n===t?e.classList.add("tab--active"):e.classList.remove("tab--active")})}document.readyState==="loading"?document.addEventListener("DOMContentLoaded",initTabs):initTabs()

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1,241 @@
/**
* A lightweight youtube embed. Still should feel the same to the user, just MUCH faster to initialize and paint.
*
* Thx to these as the inspiration
* https://storage.googleapis.com/amp-vs-non-amp/youtube-lazy.html
* https://autoplay-youtube-player.glitch.me/
*
* Once built it, I also found these:
* https://github.com/ampproject/amphtml/blob/master/extensions/amp-youtube (👍👍)
* https://github.com/Daugilas/lazyYT
* https://github.com/vb/lazyframe
*/
class LiteYTEmbed extends HTMLElement {
connectedCallback() {
this.videoId = this.getAttribute('videoid');
let playBtnEl = this.querySelector('.lyt-playbtn,.lty-playbtn');
// A label for the button takes priority over a [playlabel] attribute on the custom-element
this.playLabel = (playBtnEl && playBtnEl.textContent.trim()) || this.getAttribute('playlabel') || 'Play';
this.dataset.title = this.getAttribute('title') || "";
/**
* Lo, the youtube poster image! (aka the thumbnail, image placeholder, etc)
*
* See https://github.com/paulirish/lite-youtube-embed/blob/master/youtube-thumbnail-urls.md
*/
if (!this.style.backgroundImage) {
this.style.backgroundImage = `url("https://i.ytimg.com/vi/${this.videoId}/hqdefault.jpg")`;
this.upgradePosterImage();
}
// Set up play button, and its visually hidden label
if (!playBtnEl) {
playBtnEl = document.createElement('button');
playBtnEl.type = 'button';
// Include the mispelled 'lty-' in case it's still being used. https://github.com/paulirish/lite-youtube-embed/issues/65
playBtnEl.classList.add('lyt-playbtn', 'lty-playbtn');
this.append(playBtnEl);
}
if (!playBtnEl.textContent) {
const playBtnLabelEl = document.createElement('span');
playBtnLabelEl.className = 'lyt-visually-hidden';
playBtnLabelEl.textContent = this.playLabel;
playBtnEl.append(playBtnLabelEl);
}
this.addNoscriptIframe();
// for the PE pattern, change anchor's semantics to button
if(playBtnEl.nodeName === 'A'){
playBtnEl.removeAttribute('href');
playBtnEl.setAttribute('tabindex', '0');
playBtnEl.setAttribute('role', 'button');
// fake button needs keyboard help
playBtnEl.addEventListener('keydown', e => {
if( e.key === 'Enter' || e.key === ' ' ){
e.preventDefault();
this.activate();
}
});
}
// On hover (or tap), warm up the TCP connections we're (likely) about to use.
this.addEventListener('pointerover', LiteYTEmbed.warmConnections, {once: true});
this.addEventListener('focusin', LiteYTEmbed.warmConnections, {once: true});
// Once the user clicks, add the real iframe and drop our play button
// TODO: In the future we could be like amp-youtube and silently swap in the iframe during idle time
// We'd want to only do this for in-viewport or near-viewport ones: https://github.com/ampproject/amphtml/pull/5003
this.addEventListener('click', this.activate);
// Chrome & Edge desktop have no problem with the basic YouTube Embed with ?autoplay=1
// However Safari desktop and most/all mobile browsers do not successfully track the user gesture of clicking through the creation/loading of the iframe,
// so they don't autoplay automatically. Instead we must load an additional 2 sequential JS files (1KB + 165KB) (un-br) for the YT Player API
// TODO: Try loading the the YT API in parallel with our iframe and then attaching/playing it. #82
this.needsYTApi = this.hasAttribute("js-api") || navigator.vendor.includes('Apple') || navigator.userAgent.includes('Mobi');
}
/**
* Add a <link rel={preload | preconnect} ...> to the head
*/
static addPrefetch(kind, url, as) {
const linkEl = document.createElement('link');
linkEl.rel = kind;
linkEl.href = url;
if (as) {
linkEl.as = as;
}
document.head.append(linkEl);
}
/**
* Begin pre-connecting to warm up the iframe load
* Since the embed's network requests load within its iframe,
* preload/prefetch'ing them outside the iframe will only cause double-downloads.
* So, the best we can do is warm up a few connections to origins that are in the critical path.
*
* Maybe `<link rel=preload as=document>` would work, but it's unsupported: http://crbug.com/593267
* But TBH, I don't think it'll happen soon with Site Isolation and split caches adding serious complexity.
*/
static warmConnections() {
if (LiteYTEmbed.preconnected) return;
// The iframe document and most of its subresources come right off youtube.com
LiteYTEmbed.addPrefetch('preconnect', 'https://www.youtube-nocookie.com');
// The botguard script is fetched off from google.com
LiteYTEmbed.addPrefetch('preconnect', 'https://www.google.com');
// Not certain if these ad related domains are in the critical path. Could verify with domain-specific throttling.
LiteYTEmbed.addPrefetch('preconnect', 'https://googleads.g.doubleclick.net');
LiteYTEmbed.addPrefetch('preconnect', 'https://static.doubleclick.net');
LiteYTEmbed.preconnected = true;
}
fetchYTPlayerApi() {
if (window.YT || (window.YT && window.YT.Player)) return;
this.ytApiPromise = new Promise((res, rej) => {
var el = document.createElement('script');
el.src = 'https://www.youtube.com/iframe_api';
el.async = true;
el.onload = _ => {
YT.ready(res);
};
el.onerror = rej;
this.append(el);
});
}
/** Return the YT Player API instance. (Public L-YT-E API) */
async getYTPlayer() {
if(!this.playerPromise) {
await this.activate();
}
return this.playerPromise;
}
async addYTPlayerIframe() {
this.fetchYTPlayerApi();
await this.ytApiPromise;
const videoPlaceholderEl = document.createElement('div')
this.append(videoPlaceholderEl);
const paramsObj = Object.fromEntries(this.getParams().entries());
this.playerPromise = new Promise(resolve => {
let player = new YT.Player(videoPlaceholderEl, {
width: '100%',
videoId: this.videoId,
playerVars: paramsObj,
events: {
'onReady': event => {
event.target.playVideo();
resolve(player);
}
}
});
});
}
// Add the iframe within <noscript> for indexability discoverability. See https://github.com/paulirish/lite-youtube-embed/issues/105
addNoscriptIframe() {
const iframeEl = this.createBasicIframe();
const noscriptEl = document.createElement('noscript');
// Appending into noscript isn't equivalant for mysterious reasons: https://html.spec.whatwg.org/multipage/scripting.html#the-noscript-element
noscriptEl.innerHTML = iframeEl.outerHTML;
this.append(noscriptEl);
}
getParams() {
const params = new URLSearchParams(this.getAttribute('params') || []);
params.append('autoplay', '1');
params.append('playsinline', '1');
return params;
}
async activate(){
if (this.classList.contains('lyt-activated')) return;
this.classList.add('lyt-activated');
if (this.needsYTApi) {
return this.addYTPlayerIframe(this.getParams());
}
const iframeEl = this.createBasicIframe();
this.append(iframeEl);
// Set focus for a11y
iframeEl.focus();
}
createBasicIframe(){
const iframeEl = document.createElement('iframe');
iframeEl.width = 560;
iframeEl.height = 315;
// No encoding necessary as [title] is safe. https://cheatsheetseries.owasp.org/cheatsheets/Cross_Site_Scripting_Prevention_Cheat_Sheet.html#:~:text=Safe%20HTML%20Attributes%20include
iframeEl.title = this.playLabel;
iframeEl.allow = 'accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture';
iframeEl.allowFullscreen = true;
// Required by Youtube to fix Error 153
iframeEl.referrerPolicy = 'strict-origin-when-cross-origin';
// AFAIK, the encoding here isn't necessary for XSS, but we'll do it only because this is a URL
// https://stackoverflow.com/q/64959723/89484
iframeEl.src = `https://www.youtube-nocookie.com/embed/${encodeURIComponent(this.videoId)}?${this.getParams().toString()}`;
return iframeEl;
}
/**
* In the spirit of the `lowsrc` attribute and progressive JPEGs, we'll upgrade the reliable
* poster image to a higher resolution one, if it's available.
* Interestingly this sddefault webp is often smaller in filesize, but we will still attempt it second
* because getting _an_ image in front of the user if our first priority.
*
* See https://github.com/paulirish/lite-youtube-embed/blob/master/youtube-thumbnail-urls.md for more details
*/
upgradePosterImage() {
// Defer to reduce network contention.
setTimeout(() => {
const webpUrl = `https://i.ytimg.com/vi_webp/${this.videoId}/sddefault.webp`;
const img = new Image();
img.fetchPriority = 'low'; // low priority to reduce network contention
img.referrerpolicy = 'origin'; // Not 100% sure it's needed, but https://github.com/ampproject/amphtml/pull/3940
img.src = webpUrl;
img.onload = e => {
// A pretty ugly hack since onerror won't fire on YouTube image 404. This is (probably) due to
// Youtube's style of returning data even with a 404 status. That data is a 120x90 placeholder image.
// … per "annoying yt 404 behavior" in the .md
const noAvailablePoster = e.target.naturalHeight == 90 && e.target.naturalWidth == 120;
if (noAvailablePoster) return;
this.style.backgroundImage = `url("${webpUrl}")`;
}
}, 100);
}
}
// Register custom element
customElements.define('lite-youtube', LiteYTEmbed);

Some files were not shown because too many files have changed in this diff Show More