From baebc1fc80afce59a48cb8bbcf799b342bb8886e Mon Sep 17 00:00:00 2001 From: bilalgursen Date: Sat, 8 Aug 2026 01:27:53 +0300 Subject: [PATCH] =?UTF-8?q?refactor:=20pazarlama=20feature'=C4=B1=20?= =?UTF-8?q?=E2=80=94=20landing=20+=20merakl=C4=B1s=C4=B1na=20ta=C5=9F?= =?UTF-8?q?=C4=B1nd=C4=B1=20(Faz=205)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - landing/{sosyal-kanit,sosyal-kanit-govde,reveal} + hero-baslik + hero-focus-button + turkey-pixel-map features/pazarlama/components/ altına - app/page.tsx'teki inline ComparisonCell landing-parcalari.tsx'e çıkarıldı - /meraklisina içeriği MeraklisinaIcerik'e (okumayı pazarlama-queries'in meraklisinaDemoVerisi'nden alıyor); sayfa senkron + Suspense; demo.tsx → meraklisina-demo.tsx, huni-semasi.tsx feature'a taşındı - AGENTS.md'deki huni-semasi ve anlatım metni yol referansları aynı commit'te güncellendi; SEMA içeriği değişmedi - Davranış değişikliği yok Co-Authored-By: Claude Fable 5 --- AGENTS.md | 2 +- src/app/api/sosyal-kanit/route.ts | 2 +- src/app/meraklisina/page.tsx | 187 +++--------------- src/app/page.tsx | 24 +-- .../pazarlama}/components/hero-baslik.tsx | 0 .../components/hero-focus-button.tsx | 0 .../pazarlama/components}/huni-semasi.tsx | 0 .../components/landing-parcalari.tsx | 14 ++ .../components/meraklisina-demo.tsx} | 0 .../components/meraklisina-icerik.tsx | 158 +++++++++++++++ .../pazarlama/components}/reveal.tsx | 0 .../components}/sosyal-kanit-govde.tsx | 0 .../pazarlama/components}/sosyal-kanit.tsx | 4 +- .../components/turkey-pixel-map.tsx | 0 src/features/pazarlama/pazarlama-queries.ts | 22 +++ 15 files changed, 228 insertions(+), 185 deletions(-) rename src/{ => features/pazarlama}/components/hero-baslik.tsx (100%) rename src/{ => features/pazarlama}/components/hero-focus-button.tsx (100%) rename src/{app/meraklisina => features/pazarlama/components}/huni-semasi.tsx (100%) create mode 100644 src/features/pazarlama/components/landing-parcalari.tsx rename src/{app/meraklisina/demo.tsx => features/pazarlama/components/meraklisina-demo.tsx} (100%) create mode 100644 src/features/pazarlama/components/meraklisina-icerik.tsx rename src/{components/landing => features/pazarlama/components}/reveal.tsx (100%) rename src/{components/landing => features/pazarlama/components}/sosyal-kanit-govde.tsx (100%) rename src/{components/landing => features/pazarlama/components}/sosyal-kanit.tsx (82%) rename src/{ => features/pazarlama}/components/turkey-pixel-map.tsx (100%) create mode 100644 src/features/pazarlama/pazarlama-queries.ts diff --git a/AGENTS.md b/AGENTS.md index 41258a7..26f5106 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -25,5 +25,5 @@ Funnel CTA butonlarında ("Listemi oluştur", "Tercihlerimi belirle", giriş/öd # Meraklısına'daki mermaid şeması mimariyle senkron kalmalı -`/meraklisina` sayfasındaki sihirbaz akış şeması (`src/app/meraklisina/huni-semasi.tsx` içindeki `SEMA` sabiti) ürünün gerçek davranışının belgesidir, dekor değildir. Sihirbaz/listeleme mimarisinde davranış değiştiren her değişiklikte bu şema da aynı PR/commit içinde güncellenmeli: sihirbaz adımlarının sayısı-sırası-içeriği (alan → il → devlet/vakıf), aday havuzu kuralları, 24'lük liste iskeleti (hayal/dengeli/garanti dağılımı), havuz 24'ün altına düşünce filtre gevşetme sırası ve yapay zekânın havuz-dışına-çıkamama kuralı. Şemayı güncellerken çevresindeki unsurları da eşitle: bölümdeki anlatım metni (`src/app/meraklisina/page.tsx`, 4. bölüm), kabın `aria-label`'ı ve figcaption. Şema öğrenci diliyle kalmalı (SQL/prompt/teknik detay yok) ve ürünün risk renk dilini korumalı — kırmızı/sarı/yeşil her zaman metin etiketiyle birlikte, renk tek başına anlam taşımaz. +`/meraklisina` sayfasındaki sihirbaz akış şeması (`src/features/pazarlama/components/huni-semasi.tsx` içindeki `SEMA` sabiti) ürünün gerçek davranışının belgesidir, dekor değildir. Sihirbaz/listeleme mimarisinde davranış değiştiren her değişiklikte bu şema da aynı PR/commit içinde güncellenmeli: sihirbaz adımlarının sayısı-sırası-içeriği (alan → il → devlet/vakıf), aday havuzu kuralları, 24'lük liste iskeleti (hayal/dengeli/garanti dağılımı), havuz 24'ün altına düşünce filtre gevşetme sırası ve yapay zekânın havuz-dışına-çıkamama kuralı. Şemayı güncellerken çevresindeki unsurları da eşitle: bölümdeki anlatım metni (`src/features/pazarlama/components/meraklisina-icerik.tsx`, 4. bölüm), kabın `aria-label`'ı ve figcaption. Şema öğrenci diliyle kalmalı (SQL/prompt/teknik detay yok) ve ürünün risk renk dilini korumalı — kırmızı/sarı/yeşil her zaman metin etiketiyle birlikte, renk tek başına anlam taşımaz. diff --git a/src/app/api/sosyal-kanit/route.ts b/src/app/api/sosyal-kanit/route.ts index 5dac81d..3510f74 100644 --- a/src/app/api/sosyal-kanit/route.ts +++ b/src/app/api/sosyal-kanit/route.ts @@ -2,7 +2,7 @@ import { NextResponse } from "next/server"; import { sosyalKanitVerisi } from "@/lib/sosyal-kanit"; // Fiyat bölümündeki şeridin canlı sayıyı tazelemek için yokladığı uç. -// İlk değer sunucudan HTML ile geliyor (bkz. components/landing/sosyal-kanit.tsx); +// İlk değer sunucudan HTML ile geliyor (bkz. features/pazarlama/components/sosyal-kanit.tsx); // burası yalnızca sayfa açık kaldıkça gelen güncellemeler için. // Sayılar sosyal kanıt, gizli veri değil — kimlik doğrulaması yok. // Yük: sosyalKanitVerisi kendi içinde TTL önbelleğine sahip, yoklama diff --git a/src/app/meraklisina/page.tsx b/src/app/meraklisina/page.tsx index 1d149c8..d121b62 100644 --- a/src/app/meraklisina/page.tsx +++ b/src/app/meraklisina/page.tsx @@ -1,17 +1,12 @@ +import { Suspense } from "react"; import type { Metadata } from "next"; import { Parallax } from "@/components/parallax"; import { PagePixelDivider, SectionEyebrow } from "@/components/pixel-decor"; import { SiteFooter } from "@/components/site-footer"; -import { dilimAra, rankWindowFacets } from "@/lib/db"; -import type { DilimKey } from "@/types/yokatlas"; import { - DemoKapanisCta, - DemoKumanda, - DilimSeridiCanli, - SiralamaDemo, - type DemoVeri, -} from "./demo"; -import { HuniSemasi } from "./huni-semasi"; + MeraklisinaIcerik, + MeraklisinaIcerikSkeleton, +} from "@/features/pazarlama/components/meraklisina-icerik"; export const metadata: Metadata = { title: "Meraklısına: KolayTercih nasıl çalışır?", @@ -20,164 +15,30 @@ export const metadata: Metadata = { "Sıralamanı girdiğinde arka planda ne oluyor? Dilimler, risk renkleri ve sihirbazın adım adım daralan filtreleri — öğrenci diliyle, sıralamana göre hesaplanan canlı görsellerle.", }; -/** - * Algoritmanın öğrenci diline çevrilmiş anlatımı. Teknik detay (SQL, çarpan - * mutfağı) bilerek verilmez; amaç güven: veri gerçek, kurallar şeffaf. - * Dilim şeridi canlıdır: kullanıcının kayıtlı tercih profilindeki sıralama - * okunur, şerit o sıralamanın gerçek sayılarıyla güncellenir (bkz. demo.tsx); - * profil yoksa örnek sıralama gösterilir. Sihirbaz hunisi ise statik - * bir mermaid şemasıyla anlatılır (bkz. huni-semasi.tsx). - * Diyagramlar ürünün risk renk dilini kullanır (yeşil/sarı/kırmızı) ve her - * bölge metinle de etiketlenir — renk tek başına anlam taşımaz. - */ - -// Profili olmayan ziyaretçi bu örnek sıralamayı görür; SSR'da gerçek veriyle -// render edilir ki profil olmadan da sayfa anlamlı olsun. -const VARSAYILAN_SIRA = 100_000; - export default function MeraklisinaPage() { - const dilimToplam = Object.fromEntries( - (["hayal", "dengeli", "garanti"] as DilimKey[]).map((d) => [ - d, - dilimAra(VARSAYILAN_SIRA, "say", d, { limit: 0 }).toplam, - ]), - ) as Record; - const baslangicVeri: DemoVeri = { - facetler: rankWindowFacets(VARSAYILAN_SIRA, "say"), - dilimToplam, - }; - return ( <> -
- - Meraklısına -

- Sıralamanı girince arka planda ne oluyor? -

-

- Sihir yok, kara kutu yok: KolayTercih'in önerdiği her satır resmî - YÖK Atlas verisinden gelir ve hangi kurala göre önüne geldiği bellidir. - Bu sayfa o kuralları öğrenci diliyle anlatır — üstelik görseller - canlı: sıralamanı girdiysen sayılar sana göre hesaplanır. -

-
- - - - - -
-

- 1. Her şey taban sıralamasıyla başlar -

-

- Bir bölümün taban sıralaması, geçen yıl o bölüme - yerleşen son{" "} - öğrencinin Türkiye sıralamasıdır. Senin sıralaman bu sayıdan - küçükse (yani daha iyiysen), geçen yılın koşullarında o bölüme - yerleşebilirdin demektir. Sistemde her programın en güncel taban - sıralaması kayıtlıdır; bir bölümün 2025 verisi henüz oluşmamışsa - bir önceki yılınki kullanılır. -

-
- - - -
-

- 2. Programlar üç dilime ayrılır -

-

- Sıralamanı girdiğinde tüm programlar senin konumuna göre üç kümeye - ayrılır: tabanı senden daha iyi olanlar{" "} - Hayal (şansını - denediğin satırlar), tabanı sıralamana{" "} - yakın olanlar{" "} - Dengeli{" "} - (listenin bel kemiği — sıralamanın yaklaşık yüzde kırk fazlasına - kadar pay bırakılır), tabanı{" "} - belirgin şekilde altında kalan her şey ise{" "} - Garanti{" "} - dilimidir. -

- -

- Garanti diliminin bir sonu yok: 87. sıradaki bir adayın da 500 - bininci sıradaki bir adayın da ulaşabildiği bütün{" "} - programlar listededir. Liste sana en yakın tabandan başlar; aşağı - indikçe ve “Daha fazla göster”e bastıkça senden - uzaklaşan seçenekler gelir. Böylece ilk gördüklerin her zaman en - isabetli adaylardır ama hiçbir seçenek senden saklanmaz. -

-
- -
-

- 3. Risk renkleri her yerde aynı dili konuşur -

-

- Tabloda, haritada ve yapay zekâ listesinde gördüğün nokta ve - renkler tek bir kurala bağlıdır:{" "} - yeşil{" "} - tabanı sıralamanın belirgin altında (güvenli),{" "} - sarı{" "} - sıralamana yakın (az riskli),{" "} - kırmızı{" "} - tabanı senden iyi (riskli). Renk hangi sayfada olursa olsun aynı - hesaptan çıkar; bir satır sekme değiştirdi diye renk değiştirmez. -

-
- -
-

- 4. Sihirbaz süzer, yapay zekâ kurar -

-

- “Yapay Zeka listemi kur” sihirbazındaki üç adım birbirinden - bağımsız değildir. İlk adımda yalnızca{" "} - sıralamanla ulaşabildiğin{" "} - alanlar listelenir; ikinci adımdaki iller, seçtiğin alanlardaki - program sayısına göre yeniden hesaplanır; üçüncü adımdaki - devlet/vakıf sayıları da hem alan hem il seçimini hesaba katar. - Adımlar bitince elde kalan gerçek programlar bir{" "} - aday havuzu{" "} - olur ve yapay zekâya öyle gider: ona boş bir sayfa değil, bu havuz - verilir. Aşağıdaki şema akışın tamamını gösterir — havuz - 24'ün altına düşerse filtrelerin nasıl gevşetildiği, yine de - yetmezse listenin eldeki programlarla, sana açıkça belirtilerek - nasıl kurulduğu da dahil. -

- -
- -
-

- 5. Dürüst olalım: bu bir tahmin aracıdır -

-

- Tüm bu hesaplar geçen yılların{" "} - yerleştirme sonuçlarına dayanır. Kontenjanlar, tercih davranışları - ve puanlar her yıl değişir; geçen yıl “garanti” - görünen bir bölüm bu yıl dolabilir. Bu yüzden satırlarda son beş - yılın taban seyrini de gösteririz — çizgi yukarı tırmanıyorsa - bölüm zorlaşıyor demektir. KolayTercih karar destek{" "} - aracıdır; listenin son hâli ve sorumluluğu her zaman sana aittir. -

-
- - +
+ + Meraklısına +

+ Sıralamanı girince arka planda ne oluyor? +

+

+ Sihir yok, kara kutu yok: KolayTercih'in önerdiği her satır resmî + YÖK Atlas verisinden gelir ve hangi kurala göre önüne geldiği bellidir. + Bu sayfa o kuralları öğrenci diliyle anlatır — üstelik görseller + canlı: sıralamanı girdiysen sayılar sana göre hesaplanır. +

- -
- + + + + }> + + +
+ ); } diff --git a/src/app/page.tsx b/src/app/page.tsx index 802c830..3981de2 100644 --- a/src/app/page.tsx +++ b/src/app/page.tsx @@ -2,7 +2,6 @@ import { ArrowRight, ArrowUpRight, BarChart3, - CheckCircle2, Coins, Compass, FileText, @@ -12,18 +11,18 @@ import { ShieldCheck, TrendingUp, Wallet, - X, } from "lucide-react"; import Image from "next/image"; import Link from "next/link"; import { Suspense } from "react"; -import { HeroBaslik } from "@/components/hero-baslik"; -import { KapanisCta } from "@/components/hero-focus-button"; +import { ComparisonCell } from "@/features/pazarlama/components/landing-parcalari"; +import { HeroBaslik } from "@/features/pazarlama/components/hero-baslik"; +import { KapanisCta } from "@/features/pazarlama/components/hero-focus-button"; import { HeroForm } from "@/components/hero-form"; import { Parallax } from "@/components/parallax"; -import { Reveal } from "@/components/landing/reveal"; -import { SosyalKanitBandi } from "@/components/landing/sosyal-kanit"; -import { TurkeyPixelMap } from "@/components/turkey-pixel-map"; +import { Reveal } from "@/features/pazarlama/components/reveal"; +import { SosyalKanitBandi } from "@/features/pazarlama/components/sosyal-kanit"; +import { TurkeyPixelMap } from "@/features/pazarlama/components/turkey-pixel-map"; import { PixelCorner, PixelDivider, @@ -188,17 +187,6 @@ const paketOzellikleri = [ }, ] as const; -function ComparisonCell({ value }: { value: boolean | string }) { - if (typeof value === "string") { - return {value}; - } - return value ? ( - - ) : ( - - ); -} - export default function Home() { return (
{value}; + } + return value ? ( + + ) : ( + + ); +} diff --git a/src/app/meraklisina/demo.tsx b/src/features/pazarlama/components/meraklisina-demo.tsx similarity index 100% rename from src/app/meraklisina/demo.tsx rename to src/features/pazarlama/components/meraklisina-demo.tsx diff --git a/src/features/pazarlama/components/meraklisina-icerik.tsx b/src/features/pazarlama/components/meraklisina-icerik.tsx new file mode 100644 index 0000000..362039e --- /dev/null +++ b/src/features/pazarlama/components/meraklisina-icerik.tsx @@ -0,0 +1,158 @@ +import { Parallax } from "@/components/parallax"; +import { Skeleton } from "@/components/ui/skeleton"; +import { meraklisinaDemoVerisi } from "../pazarlama-queries"; +import { + DemoKapanisCta, + DemoKumanda, + DilimSeridiCanli, + SiralamaDemo, +} from "./meraklisina-demo"; +import { HuniSemasi } from "./huni-semasi"; + +/** + * Algoritmanın öğrenci diline çevrilmiş anlatımı. Teknik detay (SQL, çarpan + * mutfağı) bilerek verilmez; amaç güven: veri gerçek, kurallar şeffaf. + * Dilim şeridi canlıdır: kullanıcının kayıtlı tercih profilindeki sıralama + * okunur, şerit o sıralamanın gerçek sayılarıyla güncellenir (bkz. + * meraklisina-demo.tsx); profil yoksa örnek sıralama gösterilir. Sihirbaz + * hunisi ise statik bir mermaid şemasıyla anlatılır (bkz. huni-semasi.tsx). + * Diyagramlar ürünün risk renk dilini kullanır (yeşil/sarı/kırmızı) ve her + * bölge metinle de etiketlenir — renk tek başına anlam taşımaz. + */ + +// Profili olmayan ziyaretçi bu örnek sıralamayı görür; SSR'da gerçek veriyle +// render edilir ki profil olmadan da sayfa anlamlı olsun. +const VARSAYILAN_SIRA = 100_000; + +export function MeraklisinaIcerik() { + const baslangicVeri = meraklisinaDemoVerisi(VARSAYILAN_SIRA); + + return ( + + +
+

+ 1. Her şey taban sıralamasıyla başlar +

+

+ Bir bölümün taban sıralaması, geçen yıl o bölüme + yerleşen son{" "} + öğrencinin Türkiye sıralamasıdır. Senin sıralaman bu sayıdan + küçükse (yani daha iyiysen), geçen yılın koşullarında o bölüme + yerleşebilirdin demektir. Sistemde her programın en güncel taban + sıralaması kayıtlıdır; bir bölümün 2025 verisi henüz oluşmamışsa + bir önceki yılınki kullanılır. +

+
+ + + +
+

+ 2. Programlar üç dilime ayrılır +

+

+ Sıralamanı girdiğinde tüm programlar senin konumuna göre üç kümeye + ayrılır: tabanı senden daha iyi olanlar{" "} + Hayal (şansını + denediğin satırlar), tabanı sıralamana{" "} + yakın olanlar{" "} + Dengeli{" "} + (listenin bel kemiği — sıralamanın yaklaşık yüzde kırk fazlasına + kadar pay bırakılır), tabanı{" "} + belirgin şekilde altında kalan her şey ise{" "} + Garanti{" "} + dilimidir. +

+ +

+ Garanti diliminin bir sonu yok: 87. sıradaki bir adayın da 500 + bininci sıradaki bir adayın da ulaşabildiği bütün{" "} + programlar listededir. Liste sana en yakın tabandan başlar; aşağı + indikçe ve “Daha fazla göster”e bastıkça senden + uzaklaşan seçenekler gelir. Böylece ilk gördüklerin her zaman en + isabetli adaylardır ama hiçbir seçenek senden saklanmaz. +

+
+ +
+

+ 3. Risk renkleri her yerde aynı dili konuşur +

+

+ Tabloda, haritada ve yapay zekâ listesinde gördüğün nokta ve + renkler tek bir kurala bağlıdır:{" "} + yeşil{" "} + tabanı sıralamanın belirgin altında (güvenli),{" "} + sarı{" "} + sıralamana yakın (az riskli),{" "} + kırmızı{" "} + tabanı senden iyi (riskli). Renk hangi sayfada olursa olsun aynı + hesaptan çıkar; bir satır sekme değiştirdi diye renk değiştirmez. +

+
+ +
+

+ 4. Sihirbaz süzer, yapay zekâ kurar +

+

+ “Yapay Zeka listemi kur” sihirbazındaki üç adım birbirinden + bağımsız değildir. İlk adımda yalnızca{" "} + sıralamanla ulaşabildiğin{" "} + alanlar listelenir; ikinci adımdaki iller, seçtiğin alanlardaki + program sayısına göre yeniden hesaplanır; üçüncü adımdaki + devlet/vakıf sayıları da hem alan hem il seçimini hesaba katar. + Adımlar bitince elde kalan gerçek programlar bir{" "} + aday havuzu{" "} + olur ve yapay zekâya öyle gider: ona boş bir sayfa değil, bu havuz + verilir. Aşağıdaki şema akışın tamamını gösterir — havuz + 24'ün altına düşerse filtrelerin nasıl gevşetildiği, yine de + yetmezse listenin eldeki programlarla, sana açıkça belirtilerek + nasıl kurulduğu da dahil. +

+ +
+ +
+

+ 5. Dürüst olalım: bu bir tahmin aracıdır +

+

+ Tüm bu hesaplar geçen yılların{" "} + yerleştirme sonuçlarına dayanır. Kontenjanlar, tercih davranışları + ve puanlar her yıl değişir; geçen yıl “garanti” + görünen bir bölüm bu yıl dolabilir. Bu yüzden satırlarda son beş + yılın taban seyrini de gösteririz — çizgi yukarı tırmanıyorsa + bölüm zorlaşıyor demektir. KolayTercih karar destek{" "} + aracıdır; listenin son hâli ve sorumluluğu her zaman sana aittir. +

+
+ + +
+
+ ); +} + +export function MeraklisinaIcerikSkeleton() { + return ( +
+ {Array.from({ length: 3 }, (_, i) => ( +
+ + + + +
+ ))} +
+ ); +} diff --git a/src/components/landing/reveal.tsx b/src/features/pazarlama/components/reveal.tsx similarity index 100% rename from src/components/landing/reveal.tsx rename to src/features/pazarlama/components/reveal.tsx diff --git a/src/components/landing/sosyal-kanit-govde.tsx b/src/features/pazarlama/components/sosyal-kanit-govde.tsx similarity index 100% rename from src/components/landing/sosyal-kanit-govde.tsx rename to src/features/pazarlama/components/sosyal-kanit-govde.tsx diff --git a/src/components/landing/sosyal-kanit.tsx b/src/features/pazarlama/components/sosyal-kanit.tsx similarity index 82% rename from src/components/landing/sosyal-kanit.tsx rename to src/features/pazarlama/components/sosyal-kanit.tsx index f31d382..24bc3ea 100644 --- a/src/components/landing/sosyal-kanit.tsx +++ b/src/features/pazarlama/components/sosyal-kanit.tsx @@ -1,6 +1,6 @@ -import { SosyalKanitGovde } from "@/components/landing/sosyal-kanit-govde"; +import { SosyalKanitGovde } from "./sosyal-kanit-govde"; import { LISTE_ESIGI, esikGecti } from "@/lib/sosyal-kanit-sabitler"; -import { sosyalKanitVerisi } from "@/lib/sosyal-kanit"; +import { sosyalKanitVerisi } from "../pazarlama-queries"; /** * Fiyat bölümünün üstündeki sosyal kanıt şeridi: kaç öğrenci listesini diff --git a/src/components/turkey-pixel-map.tsx b/src/features/pazarlama/components/turkey-pixel-map.tsx similarity index 100% rename from src/components/turkey-pixel-map.tsx rename to src/features/pazarlama/components/turkey-pixel-map.tsx diff --git a/src/features/pazarlama/pazarlama-queries.ts b/src/features/pazarlama/pazarlama-queries.ts new file mode 100644 index 0000000..d83ff54 --- /dev/null +++ b/src/features/pazarlama/pazarlama-queries.ts @@ -0,0 +1,22 @@ +import "server-only"; +import { dilimAra, rankWindowFacets } from "@/lib/db"; +import type { DilimKey } from "@/types/yokatlas"; +import type { DemoVeri } from "./components/meraklisina-demo"; + +// Fiyat bölümü üstündeki sosyal kanıt şeridinin okuma kapısı. +export { sosyalKanitVerisi } from "@/lib/sosyal-kanit"; + +// /meraklisina'nın SSR başlangıç verisi: örnek sıralamanın gerçek dilim +// sayıları ve facetleri (puan türü anlatı gereği hep "say"). +export function meraklisinaDemoVerisi(sira: number): DemoVeri { + const dilimToplam = Object.fromEntries( + (["hayal", "dengeli", "garanti"] as DilimKey[]).map((d) => [ + d, + dilimAra(sira, "say", d, { limit: 0 }).toplam, + ]), + ) as Record; + return { + facetler: rankWindowFacets(sira, "say"), + dilimToplam, + }; +}