diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml new file mode 100644 index 0000000..89567ff --- /dev/null +++ b/.github/workflows/deploy.yml @@ -0,0 +1,63 @@ +# Сборка сайта на каждый PR в main; сборка и выкладка на GitHub Pages — на каждый пуш в main. +# Выкладывать в окружение github-pages разрешено только из main (настройки окружения). +name: Build and deploy + +on: + push: + branches: [main] + pull_request: + branches: [main] + workflow_dispatch: + +# PR: новая сборка отменяет устаревшую. main: деплои идут по очереди, не прерываясь. +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: ${{ github.event_name == 'pull_request' }} + +permissions: + contents: read + +jobs: + build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v7 + + - uses: actions/setup-node@v7 + with: + node-version: 22 + cache: npm + + - run: npm ci + + - run: npm run build + env: + NEXT_TELEMETRY_DISABLED: 1 + + # Эти адреса прописаны в App Store / Google Play и в самих приложениях. + # 22.09.2026 политика Hytaý dili 1 уже пропадала вместе с перестройкой сайта. + - name: Check pages the stores depend on + run: | + for f in index.html ru/index.html en/index.html projects/index.html 404.html \ + hytay-dili-1/privacy-policy.html sitemap.xml robots.txt; do + test -s "out/$f" || { echo "::error::out/$f is missing"; exit 1; } + done + + - uses: actions/upload-pages-artifact@v5 + if: github.event_name != 'pull_request' + with: + path: out + + deploy: + if: github.event_name != 'pull_request' && github.ref == 'refs/heads/main' + needs: build + runs-on: ubuntu-latest + permissions: + pages: write + id-token: write + environment: + name: github-pages + url: ${{ steps.deployment.outputs.page_url }} + steps: + - id: deployment + uses: actions/deploy-pages@v5 diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..29c353c --- /dev/null +++ b/.gitignore @@ -0,0 +1,5 @@ +node_modules/ +.next/ +out/ +next-env.d.ts +*.tsbuildinfo diff --git a/404.html b/404.html deleted file mode 100644 index e8bb569..0000000 --- a/404.html +++ /dev/null @@ -1,33 +0,0 @@ - - - - - -404 — Şapak Apps - - - - - -
- şapak -

Sahypa tapylmady · Страница не найдена · Page not found

-

Bu salgy boýunça sahypa ýok. Baş sahypa geçiň ýa-da GitHub-daky repozitoriýalara serediň.

-

Страницы по этому адресу нет. Перейдите на главную или посмотрите репозитории на GitHub.

-

There is no page at this address. Go to the home page or look at the repositories on GitHub.

- Baş sahypa · Главная · Home → -
- - diff --git a/app/(tk)/layout.tsx b/app/(tk)/layout.tsx new file mode 100644 index 0000000..660ca9f --- /dev/null +++ b/app/(tk)/layout.tsx @@ -0,0 +1,12 @@ +import type { Metadata, Viewport } from "next"; +import type { ReactNode } from "react"; +import { Document, baseMetadata, baseViewport } from "@/lib/document"; +import "../globals.css"; + +// Туркменский — язык по умолчанию, живёт в корне сайта без префикса. +export const metadata: Metadata = baseMetadata; +export const viewport: Viewport = baseViewport; + +export default function TurkmenLayout({ children }: { children: ReactNode }) { + return {children}; +} diff --git a/app/(tk)/page.tsx b/app/(tk)/page.tsx new file mode 100644 index 0000000..cbcd3bf --- /dev/null +++ b/app/(tk)/page.tsx @@ -0,0 +1,7 @@ +import { HomePage, homeMetadata } from "@/components/HomePage"; + +export const metadata = homeMetadata("tk"); + +export default function Page() { + return ; +} diff --git a/app/(tk)/projects/page.tsx b/app/(tk)/projects/page.tsx new file mode 100644 index 0000000..f44ecca --- /dev/null +++ b/app/(tk)/projects/page.tsx @@ -0,0 +1,7 @@ +import { ProjectsPage, projectsMetadata } from "@/components/ProjectsPage"; + +export const metadata = projectsMetadata("tk"); + +export default function Page() { + return ; +} diff --git a/app/[lang]/layout.tsx b/app/[lang]/layout.tsx new file mode 100644 index 0000000..11596d2 --- /dev/null +++ b/app/[lang]/layout.tsx @@ -0,0 +1,21 @@ +import type { Metadata, Viewport } from "next"; +import type { ReactNode } from "react"; +import { notFound } from "next/navigation"; +import { Document, baseMetadata, baseViewport } from "@/lib/document"; +import { PREFIXED_LANGS, isLang } from "@/lib/i18n"; +import "../globals.css"; + +// Статический экспорт: собираются только /ru/ и /en/, других языков нет. +export const dynamicParams = false; +export function generateStaticParams() { + return PREFIXED_LANGS.map((lang) => ({ lang })); +} + +export const metadata: Metadata = baseMetadata; +export const viewport: Viewport = baseViewport; + +export default async function LangLayout({ children, params }: { children: ReactNode; params: Promise<{ lang: string }> }) { + const { lang } = await params; + if (!isLang(lang)) notFound(); + return {children}; +} diff --git a/app/[lang]/page.tsx b/app/[lang]/page.tsx new file mode 100644 index 0000000..f4293ee --- /dev/null +++ b/app/[lang]/page.tsx @@ -0,0 +1,16 @@ +import { notFound } from "next/navigation"; +import { HomePage, homeMetadata } from "@/components/HomePage"; +import { isLang } from "@/lib/i18n"; + +type Props = { params: Promise<{ lang: string }> }; + +export async function generateMetadata({ params }: Props) { + const { lang } = await params; + return isLang(lang) ? homeMetadata(lang) : {}; +} + +export default async function Page({ params }: Props) { + const { lang } = await params; + if (!isLang(lang)) notFound(); + return ; +} diff --git a/app/[lang]/projects/page.tsx b/app/[lang]/projects/page.tsx new file mode 100644 index 0000000..97235c4 --- /dev/null +++ b/app/[lang]/projects/page.tsx @@ -0,0 +1,16 @@ +import { notFound } from "next/navigation"; +import { ProjectsPage, projectsMetadata } from "@/components/ProjectsPage"; +import { isLang } from "@/lib/i18n"; + +type Props = { params: Promise<{ lang: string }> }; + +export async function generateMetadata({ params }: Props) { + const { lang } = await params; + return isLang(lang) ? projectsMetadata(lang) : {}; +} + +export default async function Page({ params }: Props) { + const { lang } = await params; + if (!isLang(lang)) notFound(); + return ; +} diff --git a/app/global-not-found.tsx b/app/global-not-found.tsx new file mode 100644 index 0000000..a913cab --- /dev/null +++ b/app/global-not-found.tsx @@ -0,0 +1,37 @@ +import type { Metadata, Viewport } from "next"; +import { baseViewport } from "@/lib/document"; +import "./globals.css"; +import "@/components/not-found.css"; + +// Одна 404 на весь сайт: у сайта две корневые раскладки, поэтому обычный +// app/not-found.tsx собрать не из чего. Язык запроса неизвестен — текст на трёх. +export const metadata: Metadata = { + title: "404 — Şapak Apps", + robots: { index: false }, + icons: { icon: "/icon.png" }, +}; +export const viewport: Viewport = baseViewport; + +export default function GlobalNotFound() { + return ( + + +
+ + şapak + +

+ Sahypa tapylmady · Страница не найдена · Page not found +

+

Bu salgy boýunça sahypa ýok. Baş sahypa geçiň ýa-da GitHub-daky repozitoriýalara serediň.

+

Страницы по этому адресу нет. Перейдите на главную или посмотрите репозитории на GitHub.

+

There is no page at this address. Go to the home page or look at the repositories on GitHub.

+ +
+ + + ); +} diff --git a/assets/site.css b/app/globals.css similarity index 82% rename from assets/site.css rename to app/globals.css index 444c11c..b0d037c 100644 --- a/assets/site.css +++ b/app/globals.css @@ -1,4 +1,4 @@ -/* Şapak Apps — общие стили всех страниц. Стили конкретной страницы — в её - - -
- -
- - şapak - - -
- - - -
-
- -
- -
-

Open Source Turkmenistan

-

- Türkmenistanda döredilýän açyk kodly programma üpjünçiligi - Open-source software built in Turkmenistan - Открытое программное обеспечение, созданное в Туркменистане -

-

- Şapak Apps — türkmen dilinde işleýän, açyk kodly we mugt programmalar döredýän jemgyýet. Kod GitHub-da, programmalar dükanlarda. - Şapak Apps is a community that builds free, open-source software in Turkmen. The code is on GitHub. The apps are in the stores. - Şapak Apps — сообщество, которое создаёт бесплатные программы с открытым кодом на туркменском языке. Код — на GitHub, приложения — в магазинах. -

- - -
- -
-

MaksadymyzMissionЦели

-
-

Türkmen dilinde programma üpjünçiligi az. Dünýä programmalary iňlis dilinden öwredýär, rus programmalary rus dilinden. Türkmen ulanyjy üçin ýazylany welin az.

-

Biz şol boşlugy doldurýarys — okuw taslamalary bilen däl-de, hakykatdan hem goýberilýän programmalar bilen. Ýazan kodyň dükandaky programma düşýär.

-

Açyk kod bu ýerde goşmaça däl, ikinji önüm: türkmen dilinde kod barlagy geçirilýän janly programmada ilkinji Pull Request etmäge başga ýer ýok.

-

There is very little software in Turkmen. Global apps teach from English, Russian apps teach from Russian. Almost nobody builds for a Turkmen speaker.

-

We fill that gap — not with tutorial projects, but with apps that are really released. The code you write ends up in an app people install.

-

Open code here is not an extra, it is the second product: there is no other place to make a first pull request into a live app with code review in Turkmen.

-

Программного обеспечения на туркменском языке почти нет. Мировые приложения учат с английского, российские — с русского. Для туркменоязычного пользователя почти никто не разрабатывает.

-

Мы заполняем этот пробел — не учебными проектами, а приложениями, которые действительно выходят. Код, который вы пишете, попадает в приложение, которое люди устанавливают.

-

Открытый код здесь не дополнение, а второй продукт: больше негде сделать первый pull request в живое приложение с ревью кода на туркменском.

-
-
- -
-

ÝörelgelerPrinciplesПринципы

-
-
-

Açyk kodOpen codeОткрытый код

-

Ähli repozitoriýalar açyk. MIT, Apache-2.0 we GPL-3.0: alyp bolýar, üýtgedip bolýar, öz işiňde ulanyp bolýar.

-

Every repository is public. MIT, Apache-2.0 and GPL-3.0: take it, change it, use it in your own work.

-

Все репозитории публичны. MIT, Apache-2.0 и GPL-3.0: берите, меняйте, используйте в своей работе.

-
-
-

InternetsizOfflineОфлайн

-

Programmalaryň hiç biri internet talap etmeýär. Türkmenistanda internet gymmat we haýal — bu tehniki karar hem, garaýyş hem.

-

None of the apps needs a network. Internet in Turkmenistan is expensive and slow — this is a technical choice and a position.

-

Ни одно из приложений не требует сети. Интернет в Туркменистане дорогой и медленный — это и техническое решение, и позиция.

-
-
-

Mahabatsyz we tölegsizNo ads, no feesБез рекламы и платежей

-

Dükandaky programmalar mugt, mahabatsyz we hiç hili maglumat ýygnamaýar. Gizlinlik syýasatlary aşakda.

-

The apps in the stores are free, without ads, and collect no data at all. Privacy policies are below.

-

Приложения в магазинах бесплатны, без рекламы и не собирают никаких данных. Политики конфиденциальности — ниже.

-
-
-

Türkmen dilindeIn TurkmenНа туркменском

-

Interfeýs türkmen dilinde. Kod barlagy türkmen we rus dillerinde geçirilýär — iňlis diliň gowşak bolsa-da päsgel däl.

-

The interface is in Turkmen. Code review is in Turkmen and Russian — weak English is not a blocker.

-

Интерфейс на туркменском языке. Ревью кода проходит на туркменском и русском — слабый английский не помеха.

-
-
-
- -
-

TaslamalarProjectsПроекты

-
-

Häzir iki ugur bar. Dil öwrediş programmalary — Ykjam Terjime, Hytaý dili 1, Iňlis dili 1 — we gurallar: Köpri, BluePlayer, Küşt. Hemmesi açyk, hemmesi GitHub-da.

-

Esasy ünsümiz dil öwrediş liniýasynda. Hereketlendiriji bir, her täze dil — diňe täze mazmun we täze nyşan, şonuň üçin her indiki programma öňküden çalt çykýar.

-

Öz açyk kodly taslamaň bar bolsa we ony türkmen jemgyýetiniň içinde ösdürmek isleseň — hat ýaz. Repozitoriý guramanyň astyna geçýär, awtorlyk seniňki bolup galýar.

-

There are two lines today. Language learning apps — Ykjam Terjime, Hytaý dili 1, Iňlis dili 1 — and tools: Köpri, BluePlayer, Küşt. All open, all on GitHub.

-

The main focus is the language line. The engine is shared; each new language is only new content and a new icon, so every next app ships faster than the one before.

-

If you have an open-source project and want to grow it inside the Turkmen community — write to us. The repository moves under the organization, the authorship stays yours.

-

Сегодня два направления. Приложения для изучения языков — Ykjam Terjime, Hytaý dili 1, Iňlis dili 1 — и инструменты: Köpri, BluePlayer, Küşt. Всё открыто, всё на GitHub.

-

Главный фокус — языковая линейка. Движок общий, каждый новый язык — только новый контент и новый значок, поэтому каждое следующее приложение выходит быстрее предыдущего.

-

Если у вас есть проект с открытым кодом и вы хотите развивать его внутри туркменского сообщества — напишите нам. Репозиторий переходит под организацию, авторство остаётся за вами.

-
- -
- -
-

AdamlarPeopleЛюди

-
-

Şapak Apps — bir adamyň studiýasy däl. Taslamalar dürli awtorlardan gelýär, hemmesi bir guramada we bir düzgün bilen: açyk kod, açyk meseleler, düşnükli dilde barlag.

-

Şapak Apps is not one person's studio. Projects come from different authors, all in one organization and under the same rules: open code, open issues, review in a language you understand.

-

Şapak Apps — не студия одного человека. Проекты приходят от разных авторов, все в одной организации и по одним правилам: открытый код, открытые задачи, ревью на понятном языке.

-
-
-
-
- -
-

Seydi Charyyev

-

Full Stack JavaScript inženeri · React NativeFull Stack JavaScript Engineer · React NativeFull Stack JavaScript-инженер · React Native

-
-
- -
-
-
- -
-

Aýnazar Sylyýew

-

Programma inženeri · Android, web, kross-platformaSoftware Engineer · Android, web, cross-platformИнженер-программист · Android, веб, кроссплатформа

-
-
- -
-
-
- -
-

Bahram Myradow

-

Fullstack JavaScript inženeri · React NativeFullstack JavaScript Engineer · React NativeFullstack JavaScript-инженер · React Native

-
-
- -
-
-
- -
-

Merdan Jumamyradow

-

Web we mobil programmaçy · JavaScript, Dart, GoWeb and mobile developer · JavaScript, Dart, GoВеб- и мобильный разработчик · JavaScript, Dart, Go

-
-
- -
-
-
- -
-

Ahmed Batyrov

-

Web programmaçy · Node.js, ReactWeb developer · Node.js, ReactВеб-разработчик · Node.js, React

-
-
- -
-
-
- -
-

Goşant goşmakContributingУчастие

-
    -
  1. - Täze gelenler üçin meseleleri aç — olar kiçi we anyk bölünen, ilkinji Pull Request üçin amatly. - Open the issues for newcomers — they are small and clearly scoped, a good place for a first pull request. - Откройте задачи для новичков — они небольшие и чётко очерчены, подходят для первого pull request. -
  2. -
  3. - Repozitoriýany klonla we onuň README-däki gurnama ädimlerini ýerine ýetir. - Clone the repository and follow the setup steps in its README. - Клонируйте репозиторий и выполните шаги установки из его README. -
  4. -
  5. - Kiçi Pull Request aç — uly üýtgetmeden gowy. - Open a small pull request — better than one big change. - Откройте небольшой pull request — это лучше одного большого изменения. -
  6. -
-
-
-

Näme wada berýärisWhat we promiseЧто мы обещаем

-
    -
  • Kod barlagy türkmen we rus dillerinde geçirilýär.Code review is in Turkmen and Russian.Ревью кода проходит на туркменском и русском.
  • -
  • Her Pull Request-e birnäçe günüň içinde jogap berilýär.Every pull request gets an answer within a few days.На каждый pull request отвечаем в течение нескольких дней.
  • -
  • Kabul edilen kod indiki goýberilişe düşýär.Accepted code ships in the next release.Принятый код попадает в следующий релиз.
  • -
-
-
-

HabarlaşmakContactКонтакты

-

shapak.apps@gmail.com — türkmen, rus ýa-da iňlis dilinde ýazyp bolýar.

-

shapak.apps@gmail.com — write in Turkmen, Russian or English.

-

shapak.apps@gmail.com — можно писать на туркменском, русском или английском.

-
-
- -
- -
- - - -
- - - diff --git a/lib/document.tsx b/lib/document.tsx new file mode 100644 index 0000000..774ba6c --- /dev/null +++ b/lib/document.tsx @@ -0,0 +1,26 @@ +import type { Metadata, Viewport } from "next"; +import type { ReactNode } from "react"; +import type { Lang } from "./i18n"; + +/** + * Общее для обеих корневых раскладок: app/(tk)/layout.tsx и app/[lang]/layout.tsx. + * Корневых раскладок две, потому что у каждого языка свой. + */ +export const baseMetadata: Metadata = { + icons: { icon: "/icon.png", apple: "/assets/apple-touch-icon.png" }, +}; + +export const baseViewport: Viewport = { + themeColor: [ + { media: "(prefers-color-scheme: light)", color: "#FBFAF8" }, + { media: "(prefers-color-scheme: dark)", color: "#131210" }, + ], +}; + +export function Document({ lang, children }: { lang: Lang; children: ReactNode }) { + return ( + + {children} + + ); +} diff --git a/lib/i18n.ts b/lib/i18n.ts new file mode 100644 index 0000000..1554cca --- /dev/null +++ b/lib/i18n.ts @@ -0,0 +1,27 @@ +export const LANGS = ["tk", "ru", "en"] as const; +export type Lang = (typeof LANGS)[number]; + +/** Туркменский живёт в корне (/), остальные — под префиксом (/ru/, /en/). */ +export const DEFAULT_LANG: Lang = "tk"; +export const PREFIXED_LANGS = LANGS.filter((l) => l !== DEFAULT_LANG); + +export const SITE_URL = "https://shapak-apps.github.io"; + +/** Строка на трёх языках. */ +export type L = Record; + +export function isLang(value: string): value is Lang { + return (LANGS as readonly string[]).includes(value); +} + +/** Адрес страницы на нужном языке: localePath("ru", "/projects/") → "/ru/projects/". */ +export function localePath(lang: Lang, path = "/"): string { + return lang === DEFAULT_LANG ? path : `/${lang}${path}`; +} + +/** hreflang-альтернативы для metadata.alternates.languages. */ +export function languageAlternates(path = "/"): Record { + return Object.fromEntries(LANGS.map((l) => [l, localePath(l, path)])); +} + +export const OG_LOCALE: L = { tk: "tk_TM", ru: "ru_RU", en: "en_US" }; diff --git a/lib/seo.ts b/lib/seo.ts new file mode 100644 index 0000000..445e1c5 --- /dev/null +++ b/lib/seo.ts @@ -0,0 +1,38 @@ +import type { Metadata } from "next"; +import { LANGS, OG_LOCALE, SITE_URL, languageAlternates, localePath, type Lang } from "./i18n"; + +const OG_IMAGE = { url: "/assets/og.png", width: 1200, height: 630 }; + +/** Метаданные страницы на одном языке: canonical, hreflang на все три версии, OG и Twitter. */ +export function pageMetadata({ + lang, + path, + title, + description, + ogTitle, +}: { + lang: Lang; + path: string; + title: string; + description: string; + ogTitle: string; +}): Metadata { + const url = localePath(lang, path); + return { + metadataBase: new URL(SITE_URL), + title, + description, + alternates: { canonical: url, languages: languageAlternates(path) }, + openGraph: { + type: "website", + siteName: "Şapak Apps", + title: ogTitle, + description, + url, + locale: OG_LOCALE[lang], + alternateLocale: LANGS.filter((l) => l !== lang).map((l) => OG_LOCALE[l]), + images: [OG_IMAGE], + }, + twitter: { card: "summary_large_image", title: ogTitle, description, images: [OG_IMAGE.url] }, + }; +} diff --git a/next.config.ts b/next.config.ts new file mode 100644 index 0000000..9f3e43b --- /dev/null +++ b/next.config.ts @@ -0,0 +1,16 @@ +import type { NextConfig } from "next"; + +const nextConfig: NextConfig = { + // GitHub Pages отдаёт только статику: собираем готовый HTML в out/. + output: "export", + // /projects/ → out/projects/index.html — адреса как у прежнего сайта. + trailingSlash: true, + // Оптимизатор картинок требует сервер; на Pages его нет. + images: { unoptimized: true }, + experimental: { + // Одна 404 на весь сайт при двух корневых раскладках (app/global-not-found.tsx). + globalNotFound: true, + }, +}; + +export default nextConfig; diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..cc651eb --- /dev/null +++ b/package-lock.json @@ -0,0 +1,1016 @@ +{ + "name": "shapak-apps-site", + "version": "0.1.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "shapak-apps-site", + "version": "0.1.0", + "dependencies": { + "next": "16.3.6", + "react": "19.3.0", + "react-dom": "19.3.0" + }, + "devDependencies": { + "@types/node": "^22", + "@types/react": "^19", + "@types/react-dom": "^19", + "typescript": "^5" + } + }, + "node_modules/@emnapi/runtime": { + "version": "1.11.3", + "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.11.3.tgz", + "integrity": "sha512-Xz4Tpyki7XyrpbUK1jR1AhdAdaXyhhY4lZ3neLodmhpuWfy2PAQN5B46sAiU4liOXGLkHypn/qU+jvfWSCYYLA==", + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@img/colour": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@img/colour/-/colour-1.1.0.tgz", + "integrity": "sha512-Td76q7j57o/tLVdgS746cYARfSyxk8iEfRxewL9h4OMzYhbW4TAcppl0mT4eyqXddh6L/jwoM75mo7ixa/pCeQ==", + "license": "MIT", + "optional": true, + "engines": { + "node": ">=18" + } + }, + "node_modules/@img/sharp-darwin-arm64": { + "version": "0.35.4", + "resolved": "https://registry.npmjs.org/@img/sharp-darwin-arm64/-/sharp-darwin-arm64-0.35.4.tgz", + "integrity": "sha512-Uhfl4V4lhP2nbUVF9+hyH1+luj86f1gUFeo8ALYxFoULoU+G87D43BfeMP8XHsk9boxAnCY/bf2EHwhA7MuGsA==", + "cpu": [ + "arm64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=20.9.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-darwin-arm64": "1.3.3" + } + }, + "node_modules/@img/sharp-darwin-x64": { + "version": "0.35.4", + "resolved": "https://registry.npmjs.org/@img/sharp-darwin-x64/-/sharp-darwin-x64-0.35.4.tgz", + "integrity": "sha512-hWniXY3bG5qKpkKrAwPe4y+VTPmf086YQAnkxWh7uA1YrlRouWGa0M0Mxj3ZjnXFkv7/TD1bTy9lGUK26vRvWw==", + "cpu": [ + "x64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=20.9.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-darwin-x64": "1.3.3" + } + }, + "node_modules/@img/sharp-freebsd-wasm32": { + "version": "0.35.4", + "resolved": "https://registry.npmjs.org/@img/sharp-freebsd-wasm32/-/sharp-freebsd-wasm32-0.35.4.tgz", + "integrity": "sha512-lIsKw/BU+kjB4eZjxrYrZmwOJYi3Ajrv66iAlBmUPyKc3HpnloevB1g3wxGD9P/5BbQ1brBGl65VRRrCvQDEqA==", + "license": "Apache-2.0", + "optional": true, + "os": [ + "freebsd" + ], + "dependencies": { + "@img/sharp-wasm32": "0.35.4" + }, + "engines": { + "node": ">=20.9.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-darwin-arm64": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-arm64/-/sharp-libvips-darwin-arm64-1.3.3.tgz", + "integrity": "sha512-suTBPTDGrI9WodccaDdwZItTSaBYASlBk1NSfElSHrUfzu3szG6lvIF58+WiFvnfzuK8ZBFS5zE00PxqxnRiPg==", + "cpu": [ + "arm64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "darwin" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-darwin-x64": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-x64/-/sharp-libvips-darwin-x64-1.3.3.tgz", + "integrity": "sha512-FVJZ5mITMobmXIz/hPDTw0EintTW5H3WfrxwLqEqjiIihlu+hVRyGrFQ60xl0Lxn7Bt3zdpevPaQi0HEzqz9fw==", + "cpu": [ + "x64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "darwin" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-arm": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm/-/sharp-libvips-linux-arm-1.3.3.tgz", + "integrity": "sha512-3rbU4vqXXc3hY/OiXdl52xZvT0F1yEngWfvqudtPJg/KkyiaQw2DRsFrNzpmLvfavbwOq3qXn36GP8obHRULQA==", + "cpu": [ + "arm" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-arm64": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm64/-/sharp-libvips-linux-arm64-1.3.3.tgz", + "integrity": "sha512-0DaL0A6Xu6sQSQFwe4iVCrKWU2cCTItnRsYsCdxAMm9NF6twAA9BKnoqy4hqz4+azQ0JHuA26qiUKsf1XJ/v5A==", + "cpu": [ + "arm64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-ppc64": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-ppc64/-/sharp-libvips-linux-ppc64-1.3.3.tgz", + "integrity": "sha512-cdn1OvUBwsXhbC0zSzJnNzf5MZ/mTrobawDvNXBTxe8VtqKAm0sRuEY2Evzovb/w9JMk4TvRxqt1mekSuJz64w==", + "cpu": [ + "ppc64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-riscv64": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-riscv64/-/sharp-libvips-linux-riscv64-1.3.3.tgz", + "integrity": "sha512-HjPVx7yKz+0lqdhDlTw1tt90wamBoxhiXpvl1XZpJLiHH4RCJ5yDTqH+VlYPv2fwFs89JFw4c1IexYOcQUi4IQ==", + "cpu": [ + "riscv64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-s390x": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-s390x/-/sharp-libvips-linux-s390x-1.3.3.tgz", + "integrity": "sha512-neWLh+3yCNThxnfy3c4BbVBeGgt9aftno+XbT56iK28RgeDs3UOFWviLWlUu0bArYVYJaFDK+RRohbicUNCm8Q==", + "cpu": [ + "s390x" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-x64": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-x64/-/sharp-libvips-linux-x64-1.3.3.tgz", + "integrity": "sha512-4vKmvAst9nrowcqquKFAyZJUDolUaIp8uRiN0mWFguJ1IplC9/pitXtlnnlU4aa/eJw3J7i67V+pwUL+wZGdsA==", + "cpu": [ + "x64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linuxmusl-arm64": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-arm64/-/sharp-libvips-linuxmusl-arm64-1.3.3.tgz", + "integrity": "sha512-Y9kQaLMuNoB0bPYOOdcZMaseNrFpPodIWWMrx+CZyydf2xn68j9WYc6sWWRrDwNkzCQjKYfc68L7jKjGlHMibw==", + "cpu": [ + "arm64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linuxmusl-x64": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-x64/-/sharp-libvips-linuxmusl-x64-1.3.3.tgz", + "integrity": "sha512-fj8Mv0HHfD1Rr+4I68+3agJynxDWtBFgicTbSOb9Bke6pIwzGcJ+RX/yHjmiEGFMCavY/dxvem7MyNaJF+wDiw==", + "cpu": [ + "x64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-linux-arm": { + "version": "0.35.4", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm/-/sharp-linux-arm-0.35.4.tgz", + "integrity": "sha512-7OAS8gI0EReKGVN2HssHlM6umJgxF5VI3xN0p9FA91p/YO+ou5hiNghLdZ5BEHztwaaK5+bLKRf8x/o2L2nk9A==", + "cpu": [ + "arm" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=20.9.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-arm": "1.3.3" + } + }, + "node_modules/@img/sharp-linux-arm64": { + "version": "0.35.4", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm64/-/sharp-linux-arm64-0.35.4.tgz", + "integrity": "sha512-De4jpEnAU8Hd5oT0j1G3uL4ZvTuipVMn7YC6vPaJhy6/7EwEae0SVAoBrUMYQbkLGDm85taVWwuPc1a44LTzCQ==", + "cpu": [ + "arm64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=20.9.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-arm64": "1.3.3" + } + }, + "node_modules/@img/sharp-linux-ppc64": { + "version": "0.35.4", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-ppc64/-/sharp-linux-ppc64-0.35.4.tgz", + "integrity": "sha512-2oYZJeIl4kCcMGk4ouZVjnkCtFrpQFlNEtJ6GbxzhHQchwH0NH/qEb9ykmOl29dqwMq+JhFdZn+1ak2FKhI9fQ==", + "cpu": [ + "ppc64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=20.9.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-ppc64": "1.3.3" + } + }, + "node_modules/@img/sharp-linux-riscv64": { + "version": "0.35.4", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-riscv64/-/sharp-linux-riscv64-0.35.4.tgz", + "integrity": "sha512-cPbNChoRURAWdebDIHSenxRpgEdy7JkPydSnUxRm9VvKD7m0/xVaR/8Fzlu81pk5nHEvHH87UZUA7cTtwnbJSA==", + "cpu": [ + "riscv64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=20.9.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-riscv64": "1.3.3" + } + }, + "node_modules/@img/sharp-linux-s390x": { + "version": "0.35.4", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-s390x/-/sharp-linux-s390x-0.35.4.tgz", + "integrity": "sha512-RY0JFY8Fd6RonCBtHz+DvadaPkXDSI1AUn6yWL9TipqkZ1vY8w8evqdgyDFnkm4/K1ve1TvZiaePP5oSd4+WVQ==", + "cpu": [ + "s390x" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=20.9.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-s390x": "1.3.3" + } + }, + "node_modules/@img/sharp-linux-x64": { + "version": "0.35.4", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-x64/-/sharp-linux-x64-0.35.4.tgz", + "integrity": "sha512-9qvvEAuk8k89TfWUoX2htWjbAMX8p+NxCppjpcg5k6xMsjhBQPTsoIh36h9Qde4WRuGpJeYnOjdosDn/cnv+OA==", + "cpu": [ + "x64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=20.9.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-x64": "1.3.3" + } + }, + "node_modules/@img/sharp-linuxmusl-arm64": { + "version": "0.35.4", + "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-arm64/-/sharp-linuxmusl-arm64-0.35.4.tgz", + "integrity": "sha512-KB5jxpfWQTr0nc3xdHtWChdbifHrBGsd2SM62Eyxrl8afikm+f5qGBU75SJIZBT/S1MC8XyacdlXBMSWq6OURA==", + "cpu": [ + "arm64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=20.9.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linuxmusl-arm64": "1.3.3" + } + }, + "node_modules/@img/sharp-linuxmusl-x64": { + "version": "0.35.4", + "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-x64/-/sharp-linuxmusl-x64-0.35.4.tgz", + "integrity": "sha512-f+eZJZIQNEEd26RPSW+76chwOf1XtA2Y/O+5ocVyLliHkeih3e+jhLVBdNTd2rS3IbNXK8+ug93Vf5ZXtF5Lxg==", + "cpu": [ + "x64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=20.9.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linuxmusl-x64": "1.3.3" + } + }, + "node_modules/@img/sharp-wasm32": { + "version": "0.35.4", + "resolved": "https://registry.npmjs.org/@img/sharp-wasm32/-/sharp-wasm32-0.35.4.tgz", + "integrity": "sha512-zQnl4Kwp7Q6NHsENtU2T/00Zi+w3AQNwz3+UaTyVBy2FpXrzXzGjndpK61onhZjRtRpQXxCTeqw19bVyXOh7jA==", + "license": "Apache-2.0 AND LGPL-3.0-or-later AND MIT", + "optional": true, + "dependencies": { + "@emnapi/runtime": "^1.11.3" + }, + "engines": { + "node": ">=20.9.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-webcontainers-wasm32": { + "version": "0.35.4", + "resolved": "https://registry.npmjs.org/@img/sharp-webcontainers-wasm32/-/sharp-webcontainers-wasm32-0.35.4.tgz", + "integrity": "sha512-ESfNkywmCfPNyaZjxooddJQiQ+l/nTpGEOGthxiLnIHXC/CmcBixnfwUleX9mCz9ovrUUvKMap/pm8RYbzfwaA==", + "cpu": [ + "wasm32" + ], + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "@img/sharp-wasm32": "0.35.4" + }, + "engines": { + "node": ">=20.9.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-win32-arm64": { + "version": "0.35.4", + "resolved": "https://registry.npmjs.org/@img/sharp-win32-arm64/-/sharp-win32-arm64-0.35.4.tgz", + "integrity": "sha512-iNdlBX9gLVvqe2I3uIJSIKTq6wckP/DYxZtcqxm09x5Gi24DnFBmPAWZmr60ZyYMG0xlzo6goG3670ar+RXvRw==", + "cpu": [ + "arm64" + ], + "license": "Apache-2.0 AND LGPL-3.0-or-later", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=20.9.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-win32-ia32": { + "version": "0.35.4", + "resolved": "https://registry.npmjs.org/@img/sharp-win32-ia32/-/sharp-win32-ia32-0.35.4.tgz", + "integrity": "sha512-kqRsbaa5CS6KHlpxnN7WhE6vAAugXyZButpRdvDWetlv6Qv4N9WTcrWzF7tXfB9T7MsoadqdI8hmwLq6UlLvtw==", + "cpu": [ + "ia32" + ], + "license": "Apache-2.0 AND LGPL-3.0-or-later", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^20.9.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-win32-x64": { + "version": "0.35.4", + "resolved": "https://registry.npmjs.org/@img/sharp-win32-x64/-/sharp-win32-x64-0.35.4.tgz", + "integrity": "sha512-XtmnYhBcrORsJ4XJngyzr/EWP0hRZLAZRFaApdKuviyqF78+ylxh2y06ZmtULAMOnObJ3ucpN0AcwSWnMowTRg==", + "cpu": [ + "x64" + ], + "license": "Apache-2.0 AND LGPL-3.0-or-later", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=20.9.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@next/env": { + "version": "16.3.6", + "resolved": "https://registry.npmjs.org/@next/env/-/env-16.3.6.tgz", + "integrity": "sha512-x9Vblze1EbtltQYnNH38xCPWU3TVfBd1eXqA3+w9+BTpedkkdNpAaltXlGQ/nsc1+E0mVTNrtcbX3GoO09zeLQ==", + "license": "MIT" + }, + "node_modules/@next/swc-darwin-arm64": { + "version": "16.3.6", + "resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-16.3.6.tgz", + "integrity": "sha512-E/7GEqaUkt8mk/T8v9lAnrhzR06kdq1ZBkC12F8tAMkdIadwNp3H1KqHynDHrpcTlGCUdq/qu6vUL2aYVyYBdw==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-darwin-x64": { + "version": "16.3.6", + "resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-16.3.6.tgz", + "integrity": "sha512-yBE893/nDWTlaiBD1p+qgt7NUen4U5R6FXyH0s67Npq1S3E0cVSef1WIXC2xBRgQvwAvJq6DnS6Y6PrY0cy4Ew==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-linux-arm64-gnu": { + "version": "16.3.6", + "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-16.3.6.tgz", + "integrity": "sha512-KJDpjBqBPYlvkivmyrp+Qys6k/7ksbqGQvRVc6ZEGfR+cjQxx+nUkJaWmNZJsmoOrqYNbaXByF8wa0lBwDhB3Q==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-linux-arm64-musl": { + "version": "16.3.6", + "resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-16.3.6.tgz", + "integrity": "sha512-mqNg2K+hvWskSRb/QM+Ix412DvBsuSF0XV+frTSw5vmoucNnIlynFwKYew8D01bfATErMOM7Bujrf0BA5DRKFA==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-linux-x64-gnu": { + "version": "16.3.6", + "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-16.3.6.tgz", + "integrity": "sha512-nFncBNGAYouRHjRVaITs9beZRfhX4ssVwpnvPIAbkZVH6LtGoAVlH4bJ8Cnf9SOo9bsXgPFer/GdHtEE3JNOkw==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-linux-x64-musl": { + "version": "16.3.6", + "resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-16.3.6.tgz", + "integrity": "sha512-5Mf3cHDGR/Iz0ng2Bj3zUR3p5QS9YK3Hn2QiAfavFmyF48zwThAjpFoiTKNIcOHLYS4zEk+gzyJ/9deQ2ZB8yQ==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-win32-arm64-msvc": { + "version": "16.3.6", + "resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-16.3.6.tgz", + "integrity": "sha512-0jkJy0C2kbrJWTk4YLa3xk80pVBpx8FCHJym7CnUfDAXe/FWv5qT7SQJbR0KuemyxaEDlEx5WT4VQJoTW+/9Qw==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@next/swc-win32-x64-msvc": { + "version": "16.3.6", + "resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-16.3.6.tgz", + "integrity": "sha512-/YXjI1e5OXcZ7YpxRwgP/1jAV/SBKTzeVKqN2mk7mLpcICsyn3Gl5+dIfDTJp70M0ccMhyMMRso4v6mPDCGepg==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@swc/helpers": { + "version": "0.5.23", + "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.23.tgz", + "integrity": "sha512-5lSsMOTXURePglDfvuAQUqkGek9Hg2kksOYay2m0+XR++b2NWYL/4sWyuvVBIs8oKnJaxkdi9whaL/sqN13afw==", + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.8.0" + } + }, + "node_modules/@types/node": { + "version": "22.20.4", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.20.4.tgz", + "integrity": "sha512-zJRE40jpHtKqE/C4fgHrAKQLJuSpzEnP9ff9Y7YtoR3Wd2pwqzlekDeEuUQXjRd+QCYnVnNwuJYmhdk9XV8gvA==", + "dev": true, + "license": "MIT", + "dependencies": { + "undici-types": "~6.21.0" + } + }, + "node_modules/@types/react": { + "version": "19.3.0", + "resolved": "https://registry.npmjs.org/@types/react/-/react-19.3.0.tgz", + "integrity": "sha512-N0rFCuH9YoxG9/m61l9MfpJKfmLOVU0em7ipIz6TRgSSkvReLB9vL85GB+yr8Bs5leqpvg96JSwF4ZS1s4viQg==", + "dev": true, + "license": "MIT", + "dependencies": { + "csstype": "^3.2.2" + } + }, + "node_modules/@types/react-dom": { + "version": "19.3.0", + "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-19.3.0.tgz", + "integrity": "sha512-ZI7bU42mZXXKHn/qNLEw2IrbiINU7X5+vfgdixBHkCNpYWXjKgfQ/P+uyGb5CjOLB9UcnTeg3rylQtV2hym44Q==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "@types/react": "^19.3.0" + } + }, + "node_modules/baseline-browser-mapping": { + "version": "2.11.25", + "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.11.25.tgz", + "integrity": "sha512-gMmEShwwq7FJqMwvfRwvCl00v4kN+KOfJqXn+f4nrufak5gNHJOksd/60Dvjuz7sI8Y5WiSFBa8FEYr+zoyqCw==", + "license": "Apache-2.0", + "bin": { + "baseline-browser-mapping": "dist/cli.cjs" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001810", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001810.tgz", + "integrity": "sha512-TITQPUkaz+aVk5GL6NhOdwk1aEaNTSDPsGFWrTuhKGtjTF70jL/Oht2W4c6rXUe5fu7Ie19VIahAXHIIiWWNeg==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "CC-BY-4.0" + }, + "node_modules/client-only": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/client-only/-/client-only-0.0.1.tgz", + "integrity": "sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==", + "license": "MIT" + }, + "node_modules/csstype": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.2.3.tgz", + "integrity": "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/detect-libc": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz", + "integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==", + "license": "Apache-2.0", + "optional": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/nanoid": { + "version": "3.3.19", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.19.tgz", + "integrity": "sha512-Y2tUNy4ouw6tq5oDSKeQYGOyhkUBhNOcGV/02KC+6kd9eDGqdZd++mjMiIDilrBYvjEnCYvVtsuHCuP+okSfug==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/next": { + "version": "16.3.6", + "resolved": "https://registry.npmjs.org/next/-/next-16.3.6.tgz", + "integrity": "sha512-L+otWM/aQbYTx98aZhgEoMb4bZAXx1YVW4UMA/vuCyCoWG5HJyZUili8QAkqzrcC+5///tsz3s0M+SlyB5bLMw==", + "license": "MIT", + "dependencies": { + "@next/env": "16.3.6", + "@swc/helpers": "0.5.23", + "baseline-browser-mapping": "^2.9.19", + "caniuse-lite": "^1.0.30001579", + "postcss": "8.5.23", + "styled-jsx": "5.1.6" + }, + "bin": { + "next": "dist/bin/next" + }, + "engines": { + "node": ">=20.9.0" + }, + "optionalDependencies": { + "@next/swc-darwin-arm64": "16.3.6", + "@next/swc-darwin-x64": "16.3.6", + "@next/swc-linux-arm64-gnu": "16.3.6", + "@next/swc-linux-arm64-musl": "16.3.6", + "@next/swc-linux-x64-gnu": "16.3.6", + "@next/swc-linux-x64-musl": "16.3.6", + "@next/swc-win32-arm64-msvc": "16.3.6", + "@next/swc-win32-x64-msvc": "16.3.6", + "sharp": "^0.35.4" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.1.0", + "@playwright/test": "^1.51.1", + "babel-plugin-react-compiler": "*", + "react": "^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0", + "react-dom": "^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0", + "sass": "^1.3.0" + }, + "peerDependenciesMeta": { + "@opentelemetry/api": { + "optional": true + }, + "@playwright/test": { + "optional": true + }, + "babel-plugin-react-compiler": { + "optional": true + }, + "sass": { + "optional": true + } + } + }, + "node_modules/picocolors": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "license": "ISC" + }, + "node_modules/postcss": { + "version": "8.5.23", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.23.tgz", + "integrity": "sha512-g50586zr4bZmwFiTlflMu8E0bDTb5I5gertgwAKmsdUlTQIhZtunzUlD1WSzwcVWPoAVpsrA6vlfCD7oXvRwgg==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "nanoid": "^3.3.16", + "picocolors": "^1.1.1", + "source-map-js": "^1.2.1" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/react": { + "version": "19.3.0", + "resolved": "https://registry.npmjs.org/react/-/react-19.3.0.tgz", + "integrity": "sha512-E8LUcbtBWt20bbl2YoHfx4ZDBdxVTfOKtCZn9cDSJ4l6/nuoApcpIBcj47t2wZoVX8g2ZHuMHbiShgCR1T5Sog==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/react-dom": { + "version": "19.3.0", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.3.0.tgz", + "integrity": "sha512-JDk8dgif51OjFoDE70+OT9ICyYr+69HlmihNwp1+Nsfbna3t5sIiCa9ZJktDmQ4/1b/rn26hIAR2uYXDMr5r0Q==", + "license": "MIT", + "dependencies": { + "scheduler": "^0.28.0" + }, + "peerDependencies": { + "react": "^19.3.0" + } + }, + "node_modules/scheduler": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.28.0.tgz", + "integrity": "sha512-juorfCmIkIw8tT+p5BXSm6PJjQF/ycEYmKyzURCIt/RaZIhL+PulbQ9Yu2z1HdOJDdqDTlxA1+xKBmHXJsczAw==", + "license": "MIT" + }, + "node_modules/semver": { + "version": "7.8.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.5.tgz", + "integrity": "sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA==", + "license": "ISC", + "optional": true, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/sharp": { + "version": "0.35.4", + "resolved": "https://registry.npmjs.org/sharp/-/sharp-0.35.4.tgz", + "integrity": "sha512-n++8XWcj+jCOr2IOl7h8LbKnGBDY4aPbmprMONBNFdn0ImXqpGVv5zliDs0V9HbmbCQLpbuo2ej9rAoOQTvMDA==", + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "@img/colour": "^1.1.0", + "detect-libc": "^2.1.2", + "semver": "^7.8.5" + }, + "engines": { + "node": ">=20.9.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-darwin-arm64": "0.35.4", + "@img/sharp-darwin-x64": "0.35.4", + "@img/sharp-freebsd-wasm32": "0.35.4", + "@img/sharp-libvips-darwin-arm64": "1.3.3", + "@img/sharp-libvips-darwin-x64": "1.3.3", + "@img/sharp-libvips-linux-arm": "1.3.3", + "@img/sharp-libvips-linux-arm64": "1.3.3", + "@img/sharp-libvips-linux-ppc64": "1.3.3", + "@img/sharp-libvips-linux-riscv64": "1.3.3", + "@img/sharp-libvips-linux-s390x": "1.3.3", + "@img/sharp-libvips-linux-x64": "1.3.3", + "@img/sharp-libvips-linuxmusl-arm64": "1.3.3", + "@img/sharp-libvips-linuxmusl-x64": "1.3.3", + "@img/sharp-linux-arm": "0.35.4", + "@img/sharp-linux-arm64": "0.35.4", + "@img/sharp-linux-ppc64": "0.35.4", + "@img/sharp-linux-riscv64": "0.35.4", + "@img/sharp-linux-s390x": "0.35.4", + "@img/sharp-linux-x64": "0.35.4", + "@img/sharp-linuxmusl-arm64": "0.35.4", + "@img/sharp-linuxmusl-x64": "0.35.4", + "@img/sharp-webcontainers-wasm32": "0.35.4", + "@img/sharp-win32-arm64": "0.35.4", + "@img/sharp-win32-ia32": "0.35.4", + "@img/sharp-win32-x64": "0.35.4" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/source-map-js": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", + "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/styled-jsx": { + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/styled-jsx/-/styled-jsx-5.1.6.tgz", + "integrity": "sha512-qSVyDTeMotdvQYoHWLNGwRFJHC+i+ZvdBRYosOFgC+Wg1vx4frN2/RG/NA7SYqqvKNLf39P2LSRA2pu6n0XYZA==", + "license": "MIT", + "dependencies": { + "client-only": "0.0.1" + }, + "engines": { + "node": ">= 12.0.0" + }, + "peerDependencies": { + "react": ">= 16.8.0 || 17.x.x || ^18.0.0-0 || ^19.0.0-0" + }, + "peerDependenciesMeta": { + "@babel/core": { + "optional": true + }, + "babel-plugin-macros": { + "optional": true + } + } + }, + "node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "license": "0BSD" + }, + "node_modules/typescript": { + "version": "5.9.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz", + "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/undici-types": { + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz", + "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==", + "dev": true, + "license": "MIT" + } + } +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..f77d4da --- /dev/null +++ b/package.json @@ -0,0 +1,20 @@ +{ + "name": "shapak-apps-site", + "version": "0.1.0", + "private": true, + "scripts": { + "dev": "next dev", + "build": "next build" + }, + "dependencies": { + "next": "16.3.6", + "react": "19.3.0", + "react-dom": "19.3.0" + }, + "devDependencies": { + "@types/node": "^22", + "@types/react": "^19", + "@types/react-dom": "^19", + "typescript": "^5" + } +} diff --git a/projects/index.html b/projects/index.html deleted file mode 100644 index 1996efc..0000000 --- a/projects/index.html +++ /dev/null @@ -1,350 +0,0 @@ - - - - - -Taslamalar — Şapak Apps - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
- - şapak - - -
- - - -
-
- -
- -
-

Open Source Turkmenistan

-

TaslamalarProjectsПроекты

-

- Alty açyk taslama, iki ugur. Ikisi dükanlarda, hemmesi GitHub-da. Her biriniň öz awtory, ygtyýarnamasy we açyk meseleleri bar. - Six open projects in two lines. Two are in the stores, all are on GitHub. Each has its own author, license and open issues. - Шесть открытых проектов в двух направлениях. Два — в магазинах, все — на GitHub. У каждого свой автор, лицензия и открытые задачи. -

-
- -
-

Dil öwrenmekLanguage learningИзучение языков

-
- -
-
- -
-

Ykjam Terjime

- DükanlardaIn the storesВ магазинах -
-
-

- Türkmen gepleşik kitaby we terjimeçi. Hakyky ýagdaýlar üçin taýýar sözlemler, türkmen harplary klawiaturasyz. Web wersiýasy brauzerde açylýar. - Turkmen phrasebook and translator. Ready phrases for real situations, Turkmen letters without a special keyboard. The web version opens in the browser. - Туркменский разговорник и переводчик. Готовые фразы для реальных ситуаций, туркменские буквы без специальной клавиатуры. Веб-версия открывается в браузере. -

-
- 31 dil31 languages31 язык - internetsizofflineофлайн - MIT -
-
React Native · Expo · TypeScript
@TheSeydiCharyyev
- -
- -
-
- -
-

Hytaý dili 1

- App Store-da · Google Play ýakyndaOn the App Store · Google Play soonВ App Store · скоро в Google Play -
-
-

- Türkmen dilinden hytaý dili. Her bapda teoriýa, gönükmeler we synag; indiki bap synagdan soň açylýar. Doly oflaýn. - Chinese from Turkmen. Every chapter has theory, exercises and an exam; the next chapter opens after the exam. Fully offline. - Китайский с туркменского. В каждой главе теория, упражнения и экзамен; следующая глава открывается после экзамена. Полностью офлайн. -

-
- 31 bap31 chapters31 глава - 600 gönükme600 exercises600 упражнений - MIT -
-
React Native · Expo · TypeScript
@TheSeydiCharyyev
- -
- -
-
- -
-

Iňlis dili 1

- TaýýarlanýarIn developmentВ разработке -
-
-

- Türkmen dilinden iňlis dili, A1 derejesi. Hytaý dili 1 bilen bir hereketlendirijide: şol bir baplar, synaglar we ösüş. - English from Turkmen, level A1. Same engine as Hytaý dili 1: the same chapters, exams and progress. - Английский с туркменского, уровень A1. Тот же движок, что у Hytaý dili 1: те же главы, экзамены и прогресс. -

-
- A1 - 20 bap20 chapters20 глав - MIT -
-
React Native · Expo · TypeScript
@TheSeydiCharyyev
- -
- -
-
- -
-

GurallarToolsИнструменты

-
- -
-
- -
-

Köpri

- TaýýarlanýarIn developmentВ разработке -
-
-

- Android üçin oflaýn terjimeçi: rus we iňlis dillerinden türkmen diline oflaýn sözlük, beýleki jübütler üçin onlaýn hyzmatlar, uly köpdilli gepleşik kitaby. Kamera arkaly terjime taýýarlanýar. - Offline translator for Android: an offline dictionary from Russian and English to Turkmen, online services for other pairs, a large multilingual phrasebook. Camera translation is coming. - Офлайн-переводчик для Android: офлайн-словарь с русского и английского на туркменский, онлайн-сервисы для остальных пар, большой многоязычный разговорник. Готовится перевод через камеру. -

-
- 50+ dil50+ languages50+ языков - Apache-2.0 -
-
Flutter · Dart
@aynazar-sylyyew-dev
- -
- -
-
- -
-

BluePlayer

- TaýýarlanýarIn developmentВ разработке -
-
-

- Android üçin döwrebap aýdym pleýeri. Kotlin we natiw C++. - Modern music player for Android. Kotlin and native C++. - Современный музыкальный плеер для Android. Kotlin и нативный C++. -

-
- Kotlin - C++ - Apache-2.0 -
- - -
- -
-
- -
-

Küşt

- TaýýarlanýarIn developmentВ разработке -
-
-

- Küşt öwrenmek, türgenleşmek we oýnamak üçin programma. Stockfish botlaryna garşy oýun, oýundan soň derňew: her göçüm bahalandyrylýar we düşündirilýär. - A chess app to learn, practice and play. Games against Stockfish bots, and post-game analysis: every move is classified and explained. - Шахматное приложение: учиться, тренироваться, играть. Партии против ботов на Stockfish и разбор после игры: каждый ход оценивается и объясняется. -

-
- Stockfish - GPL-3.0 -
-
Flutter · Dart
@fihdeveloper
- -
- -
-
- -
-

- Öz açyk kodly taslamaň bar bolsa we ony türkmen jemgyýetiniň içinde ösdürmek isleseň — hat ýaz. Repozitoriý guramanyň astyna geçýär, awtorlyk seniňki bolup galýar. - If you have an open-source project and want to grow it inside the Turkmen community — write to us. The repository moves under the organization, the authorship stays yours. - Если у вас есть проект с открытым кодом и вы хотите развивать его внутри туркменского сообщества — напишите нам. Репозиторий переходит под организацию, авторство остаётся за вами. -

- -
- -
- - - -
- - - diff --git a/public/.nojekyll b/public/.nojekyll new file mode 100644 index 0000000..e69de29 diff --git a/assets/apple-touch-icon.png b/public/assets/apple-touch-icon.png similarity index 100% rename from assets/apple-touch-icon.png rename to public/assets/apple-touch-icon.png diff --git a/assets/blueplayer.png b/public/assets/blueplayer.png similarity index 100% rename from assets/blueplayer.png rename to public/assets/blueplayer.png diff --git a/assets/hytay-dili-1.png b/public/assets/hytay-dili-1.png similarity index 100% rename from assets/hytay-dili-1.png rename to public/assets/hytay-dili-1.png diff --git a/assets/inlis-dili-1.png b/public/assets/inlis-dili-1.png similarity index 100% rename from assets/inlis-dili-1.png rename to public/assets/inlis-dili-1.png diff --git a/assets/kopri.png b/public/assets/kopri.png similarity index 100% rename from assets/kopri.png rename to public/assets/kopri.png diff --git a/assets/kust.png b/public/assets/kust.png similarity index 100% rename from assets/kust.png rename to public/assets/kust.png diff --git a/assets/og.png b/public/assets/og.png similarity index 100% rename from assets/og.png rename to public/assets/og.png diff --git a/assets/ykjam-terjime.png b/public/assets/ykjam-terjime.png similarity index 100% rename from assets/ykjam-terjime.png rename to public/assets/ykjam-terjime.png diff --git a/hytay-dili-1/privacy-policy.html b/public/hytay-dili-1/privacy-policy.html similarity index 100% rename from hytay-dili-1/privacy-policy.html rename to public/hytay-dili-1/privacy-policy.html diff --git a/icon.png b/public/icon.png similarity index 100% rename from icon.png rename to public/icon.png diff --git a/logo.png b/public/logo.png similarity index 100% rename from logo.png rename to public/logo.png diff --git a/logo.svg b/public/logo.svg similarity index 100% rename from logo.svg rename to public/logo.svg diff --git a/robots.txt b/public/robots.txt similarity index 100% rename from robots.txt rename to public/robots.txt diff --git a/make_logo_svg.py b/scripts/make_logo_svg.py similarity index 100% rename from make_logo_svg.py rename to scripts/make_logo_svg.py diff --git a/sitemap.xml b/sitemap.xml deleted file mode 100644 index e1f4bcb..0000000 --- a/sitemap.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - https://shapak-apps.github.io/2026-09-11 - https://shapak-apps.github.io/projects/2026-09-11 - https://shapak-apps.github.io/hytay-dili-1/privacy-policy.html2026-08-13 - diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..e7ff3a2 --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,41 @@ +{ + "compilerOptions": { + "target": "ES2017", + "lib": [ + "dom", + "dom.iterable", + "esnext" + ], + "allowJs": true, + "skipLibCheck": true, + "strict": true, + "noEmit": true, + "esModuleInterop": true, + "module": "esnext", + "moduleResolution": "bundler", + "resolveJsonModule": true, + "isolatedModules": true, + "jsx": "react-jsx", + "incremental": true, + "plugins": [ + { + "name": "next" + } + ], + "paths": { + "@/*": [ + "./*" + ] + } + }, + "include": [ + "next-env.d.ts", + "**/*.ts", + "**/*.tsx", + ".next/types/**/*.ts", + ".next/dev/types/**/*.ts" + ], + "exclude": [ + "node_modules" + ] +} diff --git a/ykjam-terjime/privacy-policy.html b/ykjam-terjime/privacy-policy.html deleted file mode 100644 index 7ef0186..0000000 --- a/ykjam-terjime/privacy-policy.html +++ /dev/null @@ -1,36 +0,0 @@ - - - - - - Privacy Policy — Ykjam Terjime - - - -

Privacy Policy — Ykjam Terjime

-

Effective date: 13 August 2026 · Developer: Seydi Charyyev (Şapak Apps)

- -

Summary

-

Ykjam Terjime does not collect any data. The app has no accounts, - no registration, no analytics and no advertising.

- -

Data collection

-

We do not collect, store or share any personal information. Your settings and - favorites are stored only on your device and never leave it.

- -

Türkmençe gysgaça

-

Ykjam Terjime hiç hili maglumat ýygnamaýar. Hasap açmak talap edilmeýär, mahabat - we analitika ýok. Sazlamalaryňyz diňe öz enjamyňyzda saklanýar.

- -

Contact

-

Questions about this policy: shapak.apps@gmail.com

-

← Şapak Apps

- -