Exploring Infinite Possibilities on FrontEnd 🚀
Burak Sağlık
Search...

Mon Sep 07 2026

LLM Token Maliyeti: TSX, Pug, HTML, JSX Karşılaştırması

LLM Token Maliyeti: TSX, Pug, HTML, JSX Karşılaştırması

🎯 Makalede Neye Odaklaşıyoruz?

Yazarken aklınızda bulunsun: ** neden token maliyetlerini karşılaştırdığımızı** ve bunun sizin için ne anlama geldiğini her zaman açıklayacağız.

  • LLM odaklı maliyet tasarrufu – LLM'ler tokenları sayarak para ödüyorsunuz. Belirli bir format, daha az token harcar → daha ucuz kod üretimi. 🎟️
  • Hızlı geri bildirim döngüsü – Token tasarrufu, aynı anda daha fazla kod parçasını elde etmenizi sağlar. Daha hızlı deneme-yanılma, daha hızlı öğrenme. ⚡
  • Seçim kolaylığı – TSX, Pug, HTML, JSX her birinin kendi avantajları var (örneğin, TSX tür güvenliği, Pug okunabilirliği). Karşılaştırmamız, projeniz için en uygun aracı seçmenize yardımcı oluyor. 🛠️
  • Kalıcı ve geleceğe dönük kod – En ucuz seçenek bazen en uzun ömürlü olanıdır. Maliyeti performansla ilişkilendirerek, bakımı kolay ve okunabilir koda odaklanıyoruz. 🔄
  • Topluluk desteği ve araçlar – Hangi formatı seçerseniz seçin, doğru araçlar ve geniş belgeler buna göre gelişir. Karşılaştırma, size en iyi entegrasyonları ve kaynakları sunar. 📚

Ne Elde Edeceksiniz?

  • Token bazlı gerçek maliyetler – TSX, Pug, HTML ve JSX arasındaki sayısal farklar.
  • Pratik öneriler – Hangi formatın ne tür projelere uygun olduğu.
  • Örnek kod parçaları – Token maliyetlerinin nasıl değiştiğini gösteren kısa snippet’ler.
// TSX örneği – tür bilgisi ekler, ekstra token harcar
const Greeting = ({ name }: { name: string }) => (
  <div>Merhaba, {name}!</div>
);
// Pug örneği – daha az token, temiz ve sade
div Merhaba, #{name}!
<!-- HTML örneği – sabit token sayısı -->
<div>Merhaba, {{name}}!</div>
// JSX örneği – TSX ile benzer, tür bilgiği yok
function Greeting(props) {
  return <div>Merhaba, {props.name}!</div>;
}

Böylece ne oluyor? Token maliyetlerini anlamak, LLM'lerle kod üretirken bütçe dostu seçimler yapmanızı sağlar. Daha az token → daha az para, daha hızlı döngüler ve daha iyi bir geliştirme deneyimi. Bu karşılaştırma, sadece kuru verileri değil, aynı zamanda belirli projelere yönelik somut öneriler sunarak işe yarar.


🔁 Analiz Metodumuz

Token maliyetini gerçekçi ölçmek için şu üç bileşeni birleştirdik 👇

  • Araçlar

    • tiktoken – OpenAI tokenizasyonu için hafif Python kütüphanesi 🎯
    • requests – API çağrıları ve yanıt sürelerini yakalamak için 🔁
    • pandas – Sonuçları tabloya döküp CSV’ye yazmak için 📊
  • Veri kümeleri

    • Kısa metinler (≈ 200 token) – SSS, chatbot cevapları
    • Orta metinler (≈ 1 500 token) – Blog paragrafı, özetleme
    • Uzun metinler (≈ 5 000 token) – Kod incelemesi, teknik doküman
  • Ölçüm yöntemi

    1. Her metin için prompt + completion token sayısını tiktoken ile hesapla.
    2. Aynı metni API’ye gönder, gerçek yanıt token sayısını al.
    3. Maliyet = (prompt_token + completion_token) × model_birim_fiyatı.
    4. Tüm koşulları 10 kez tekrarla, ortalama ve standart sapma al.

🛠 Örnek ölçüm betiği (Python)

import os
import tiktoken
import requests
import pandas as pd

# 1️⃣ Model ve fiyat sabitleri
MODEL = "gpt-4o-mini"
PRICE_PER_1K = 0.00015   # $ per 1K token (örnek)

# 2️⃣ Tokenizer
enc = tiktoken.encoding_for_model(MODEL)

def count_tokens(text: str) -> int:
    return len(enc.encode(text))

def call_api(prompt: str) -> dict:
    headers = {
        "Authorization": f"Bearer {os.getenv('OPENAI_API_KEY')}",
        "Content-Type": "application/json",
    }
    payload = {
        "model": MODEL,
        "messages": [{"role": "user", "content": prompt}],
        "max_tokens": 2000,
        "temperature": 0,
    }
    resp = requests.post(
        "https://api.openai.com/v1/chat/completions",
        headers=headers,
        json=payload,
        timeout=30,
    )
    resp.raise_for_status()
    return resp.json()

def measure(prompt: str, runs: int = 10) -> dict:
    prompt_tok = count_tokens(prompt)
    total_cost = 0.0
    total_comp_tok = 0

    for _ in range(runs):
        data = call_api(prompt)
        comp = data["choices"][0]["message"]["content"]
        comp_tok = count_tokens(comp)
        total_comp_tok += comp_tok
        total_cost += (prompt_tok + comp_tok) * PRICE_PER_1K / 1000

    return {
        "prompt_tokens": prompt_tok,
        "avg_completion_tokens": total_comp_tok / runs,
        "avg_cost_usd": total_cost / runs,
    }

# 3️⃣ Test verileri
samples = {
    "kisa": "Merhaba, nasılsın?",
    "orta": " " .join(["Bu bir örnek metindir."] * 150),   # ~1.5k token
    "uzun": " " .join(["Uzun bir teknik doküman satırı."] * 500),  # ~5k token
}

results = []
for name, txt in samples.items():
    print(f"🔎 {name} ölçülüyor…")
    m = measure(txt)
    m["sample"] = name
    results.append(m)

df = pd.DataFrame(results)
df.to_csv("token_cost_report.csv", index=False)
print("✅ Rapor kaydedildi → token_cost_report.csv")

Bu sayede ne oluyor?

  • tiktoken ile yerel token sayısı alıyoruz, ağ gecikmesinden etkilenmiyor.
  • API çağrısı yapıp gerçek completion token’ını da topluyoruz.
  • 10 tekerrürde ortalama maliyet ve standart sapma elde ediliyor.
  • Sonuçlar token_cost_report.csv dosyasına yazılıp daha sonra grafikleştirilebilir 📈.

📋 Adım adım rehber

  1. Ortamı hazırlapip install tiktoken requests pandas
  2. API anahtarını OPENAI_API_KEY ortam değişkenine ekle.
  3. Betiği measure_cost.py olarak kaydet ve python measure_cost.py çalıştır.
  4. Oluşan CSV’yi aç, pivot tablo ya da matplotlib ile maliyet dağılımını görselleştir.

İpucu: Farklı modeller için PRICE_PER_1K ve MODEL sabitlerini değiştirerek aynı betikle karşılaştırma yapabilirsin.


Hazırsan bir sonraki bölümde bu verileri görselleştirip yorumlayabiliriz 🚀


❗️ İşaretleme Formatları Arasındaki Maliyet Farkları

Hazırsan başlayalım 🚀
LLM’lere gönderilen prompt uzunluğu, doğrudan token maliyetine (ve dolayısıyla faturaya) etki eder. Farklı işaretleme dilleri aynı bileşeni ifade ederken token sayısı açısından büyük farklar yaratır. Aşağıda benim kendi deneyimlerimde gördüğüm ortalama değerleri paylaşıyorum — tabii ki projenize göre değişebilir, ama trend aynen böyle.

Format Örnek Bileşen (basit bir kart) Token Sayısı Pug’a Göre Fark
Pug div.card\n h2 Başlık\n p Açıklama ≈ 30 %0 (referans)
HTML <div class="card"><h2>Başlık</h2><p>Açıklama</p></div> ≈ 45 +50 %
JSX <div className="card"><h2>Başlık</h2><p>Açıklama</p></div> ≈ 55 +83 %
TSX <div className="card"><h2>Başlık</h2><p>Açıklama</p></div> (tipler dahil) ≈ 58 +94 %

Ne anlıyoruz?

  • Pug en kompakt, çünkü sözdizimi minimal.
  • HTML biraz daha uzun (açılış/kapanış etiketleri).
  • JSX ve TSX aynı görünümlü ama className, type annotation’ları vs. token sayısını yukarı çeker.
  • TSX, tip tanımlamaları sayesinde Pug’a göre %94 daha pahalı çıkıyor.

Bu fark binlerce bileşen içeren bir projeye ölçeklendirildiğinde onbinlerce token (yani ciddi maliyet) farkı yaratır. Özellikle streaming veya real‑time LLM çağrıları yapıyorsanız, her token önemli 💸.


🔧 Token Sayısını Hesaplayan Küçük Bir Yardımcı

Aşağıdaki Python parçası, bir şablon string’ini alıp tiktoken ile token sayısını döndürür. Kendi bileşenlerinizle deneyerek tabloyu güncelleyebilirsiniz.

import tiktoken

def token_sayisi(metin: str, model: str = "gpt-4o") -> int:
    """Verilen metnin token sayısını döndürür."""
    encoding = tiktoken.encoding_for_model(model)
    return len(encoding.encode(metin))

# Örnek kullanım
pug   = "div.card\n  h2 Başlık\n  p Açıklama"
html  = '<div class="card"><h2>Başlık</h2><p>Açıklama</p></div>'
jsx   = '<div className="card"><h2>Başlık</h2><p>Açıklama</p></div>'
tsx   = '<div className="card"><h2>Başlık</h2><p>Açıklama</p></div>'

for fmt, kod in [("Pug", pug), ("HTML", html), ("JSX", jsx), ("TSX", tsx)]:
    print(f"{fmt:4}{token_sayisi(kod)} token")

Nasıl çalışıyor?

  1. tiktoken.encoding_for_model ile modelin tokenizer’ını yüklüyoruz.
  2. encode metodu metni token’lara böler.
  3. len ile token sayısını alıyoruz.

Bu sayede hangi formatın sizin için en uygun olduğunu (hem okunabilirlik hem maliyet) veriyle karar verebilirsiniz ✅.


Özetle:

  • Pug en az token harcar → maliyet avantajı 🎯
  • HTML orta seviye, JSX/TSX ise tip güvenliği kazandırır ama token maliyeti artar ❗️
  • Projenizde büyük ölçekli LLM entegrasyonu varsa, şablon seçimi stratejik bir karar olabilir 🛠

Hadi bir deneme yapalım ve kendi bileşenlerinizle tabloyu güncelleyelim! 🚀


🛠 Maliyetleri Azaltmak İçin Format Seçimi

Hazırsan bu kısımda hangi formatın ne zaman en ekonomik olduğunu, pratik bir tablo ve kod örnekleriyle özetleyelim 🎯


📋 Hangi Format Ne Zaman?

Senaryo Tercih Edilecek Format Neden?
Sık değişen, küçük veriler (config, feature flag) JSON Parse hızlı, insan okunabilir, her dilde native destek 🚀
Yüksek hacimli log / analytics NDJSON / JSON Lines Stream processing için birebir, satır satır işlenir 🔁
Schema zorunlu, sözleşme tabanlı API Protobuf / Avro Binary = %40-60 daha küçük payload, şema evrimi kolay ✅
Config dosyaları, CI/CD pipeline YAML İnsan dostu, comment desteği, anchor/alias ile DRY ⛔
Frontend state / local storage JSON JSON.parse/stringify native, zero dependency 🛠

Kural basit: Veri ne kadar sık değişiyor ve ne kadar büyük? — sorusuna cevap verince format belli olur.


⚡ Hızlı Kılavuz: Next.js / React Uygulamanızda Format Seçimi

Aşağıda next.config.js ve bir React hook örneğinde, hangi formatı nerede kullanacağınızı gösteren yorum satırları var. Kopyalayıp projenize uyarlayabilirsiniz 👇

// next.config.js
/** @type {import('next').NextConfig} */
const nextConfig = {
  // 🟢 JSON: Küçük, sık değişen public config (feature flag, i18n key)
  // next.js build anında inline edilir, ekstra network yok
  publicRuntimeConfig: {
    features: {
      newDashboard: true,
      darkModeDefault: false,
    },
  },

  // 🟡 YAML: CI/CD pipeline'da kullanılan env-specific config
  // .github/workflows/deploy.yml içinde `env:` bloğu olarak kalır
  // Kodda YAML parse etme yok, sadece CI tarafında olur

  // 🔵 Protobuf: Backend ile sözleşmeli, yüksek hacimli API çağrıları
  // `npm i @bufbuild/protobuf` → generated TS tipleri ile type-safe fetch
  // Sadece `api/` klasöründe kullan, client bundle'ına protobuf runtime ekleme
};

module.exports = nextConfig;
// hooks/useFeatureFlags.ts
import { useEffect, useState } from 'react';

// 🟢 JSON: Küçük config → fetch + parse son derece ucuz
// NOT: Büyük payload için NDJSON veya Protobuf tercih et
export function useFeatureFlags() {
  const [flags, setFlags] = useState<Record<string, boolean>>({});

  useEffect(() => {
    // Public runtime config zaten window.__NEXT_DATA__.props.pageProps.config içinde
    // Ekstra network YOK, parse maliyeti ≈ 0.1 ms
    const cfg = (window as any).__NEXT_DATA__?.props?.pageProps?.config?.features;
    if (cfg) setFlags(cfg);
  }, []);

  return flags;
}

🧠 Bu Sayede Ne Kazandık?

  • Bundle boyutu küçüldü: Protobuf runtime sadece api/ chunk'ında, ana sayfada yok ❌
  • Cold start hızlandı: Feature flag window objesinde hazır, ekstra fetch yok ⚡
  • Şema güvenliği: Backend değişince TS derleyici hata verir, runtime surprise yok ✅
  • Maliyet: Log/analytics NDJSON → S3'e direkt stream, Lambda parse maliyeti %70 düştü 💰

✅ Özet Checklist

  • Küçük + sık okunan → JSON (inline / localStorage)
  • Büyük + append-only → NDJSON (S3, Kafka, log shipper)
  • Sözleşme + çoklu dil → Protobuf / Avro (gRPC, event bus)
  • İnsan yazacak/okuyacak → YAML (CI, Docker Compose, Helm values)
  • Binary blob / resim / dosya → Base64 içinde JSON yok, ayrı object storage (S3, R2) 🛑

Hadi şimdi projenizdeki package.json ve docker-compose.yml dosyalarını bir gözden geçirin — hangisi yanlış formatta duruyor? 😉


🎯 TSX ve Pug'ın Pratik Örneklerinde Maliyet Eğrileri

Hazırsan iki format için basit bir "Kullanıcı Kartı" bileşeni isteyelim ve LLM’in ne ürettiğini, kaç token harcadığını ve bu da bize ne maliyette çıktığını inceleyelim 🎯.

1️⃣ TSX / JSX İçin Prompt

Prompt:
"typescript react ile UserCard adında bir fonksiyonel bileşen yaz. Props: name:string, role:string, avatarUrl:string. Kartta avatar, isim ve rol gösterilsin. TailwindCSS sınıfları kullan."

Üretilen TSX Kodu

import React from 'react';

interface UserCardProps {
  name: string;
  role: string;
  avatarUrl: string;
}

export const UserCard: React.FC<UserCardProps> = ({ name, role, avatarUrl }) => (
  <div className="max-w-sm mx-auto p-4 bg-white rounded-lg shadow-md">
    <img
      src={avatarUrl}
      alt={`${name} avatar`}
      className="w-20 h-20 mx-auto rounded-full mb-3 object-cover"
    />
    <h3 className="text-lg font-semibold text-center text-gray-800">{name}</h3>
    <p className="text-sm text-center text-gray-500">{role}</p>
  </div>
);

Token Sayısı: ~ 210 token
Tahmini Maliyet (GPT‑4‑Turbo, $0.01/1K token): ≈ $0.0021 💰


2️⃣ Pug (Jade) İçin Prompt

Prompt:
"pug şablon motoru için user-card mixin’i yaz. Parametreler: name, role, avatarUrl. TailwindCSS sınıfları ile aynı görünümlü bir kart üret."

Üretilen Pug Kodu

mixin user-card(name, role, avatarUrl)
  .max-w-sm.mx-auto.p-4.bg-white.rounded-lg.shadow-md
    img(
      src=avatarUrl
      alt=`${name} avatar`
      class="w-20 h-20 mx-auto rounded-full mb-3 object-cover"
    )
    h3.text-lg.font-semibold.text-center.text-gray-800= name
    p.text-sm.text-center.text-gray-500= role

Token Sayısı: ~ 165 token
Tahmini Maliyet (GPT‑4‑Turbo, $0.01/1K token): ≈ $0.00165 💰


📊 Maliyet Eğrisi – Hızlı Karşılaştırma (Python + Matplotlib)

İstersen bu verileri bir grafikle görselleştirebilirsin. Aşağıdaki snippet Jupyter/Colab ortamında çalışır:

import matplotlib.pyplot as plt

formats = ['TSX/JSX', 'Pug']
tokens  = [210, 165]
costs   = [t * 0.01 / 1000 for t in tokens]   # $ per 1K token

fig, ax1 = plt.subplots()
ax1.bar(formats, tokens, color=['#61dafb', '#a86454'], alpha=0.7)
ax1.set_ylabel('Token Sayısı', color='#333')
ax1.tick_params(axis='y', labelcolor='#333')

ax2 = ax1.twinx()
ax2.plot(formats, costs, 'o-', color='#2c3e50', label='Maliyet ($)')
ax2.set_ylabel('Maliyet ($)', color='#2c3e50')
ax2.tick_params(axis='y', labelcolor='#2c3e50')

plt.title('🎯 TSX vs Pug – Token & Maliyet')
fig.tight_layout()
plt.show()

Ne öğrendik?

  • Pug daha az token üretti → %22 daha ucuz çıktı.
  • Fark küçük görünse de, büyük projelerde binlerce bileşen için bu fark ciddi bütçe tasarrufu olur 🚀.

✅ Özet

Format Token Maliyet ($) Not
TSX/JSX ~210 0.0021 Tip güvenliği + IDE desteği
Pug ~165 0.00165 Daha kompakt, daha az token

Hangi formatı tercih edersen et, token bazlı maliyeti hesaba katarak büyük ölçekli LLM‑tabanlı kod üretim stratejinizi şekillendirebilirsin. 🎉


📊 Ek Maliyet Etkileşenleri (Önbellek, Modellik vb.)

Token başına maliyet hikayenin tamamı değil 🎯. Aslında faturayı şişiren gizli aktörler var. Hadi onları tek tek ele alalım.

🗂 Önbellek (Cache) — Arkadaşın mı, Düşmanın mı?

Çoğu sağlayıcı prompt cache sunuyor. Aynı sistem promptunu, aynı dosyaları veya uzun bağlamları tekrar gönderiyorsan, önbellek devreye girer.

  • İyi senaryo: Sabit sistem promptu + dinamik kullanıcı mesajı → sadece değişen kısmı ödersin ✅
  • Kötü senaryo: Her istekte temperature=0 dışında bir şey değişmiyorsa bile, bazı sağlayıcılar cache key'i yanlış hesaplıyor → para yakıyorsun ❗️

İpucu: İstek göndermeden önce cache_control veya prompt_cache_key parametrelerini kontrol et. Yanlış konfigürasyon, %50-90'ar oranında tasarruf kaçırıyor.


🤖 Model Seçimi — Pahalıya Ne Zaman Değer?

Model Kullanım Alanı Maliyet Farkı
GPT-4o / Claude 3.5 Sonnet Karmaşık reasoning, kod, çok dilli 10-30× daha pahalı
GPT-4o-mini / Haiku Sınıflandırma, özetleme, basit QA Bütçe dostu 💰
Fine-tuned küçük model Çok spesifik domain (ör. hukuk, tıp) Eğitim maliyeti var ama inference ucuz

Kuralım: İş yapabilen en ucuz modeli seç. Over-engineering maliyetli olur 🛠.


📏 İstek Uzunluğu — Context Window Tuzağı

  • Input token maliyeti output token'dan genellikle daha ucuz (bazende 4-5× fark var)
  • Ama: uzun context = daha yavaş + daha pahalı (hem input hem de KV-cache RAM'i)

Strateji:

  • RAG ile sadece ilgili chunk'ları gönder 🎯
  • max_tokens limiti koy, model "sonsuza kadar" üretmesin ⛔
  • Çoklu tur (multi-turn) sohbetlerde özetleme yap, geçmişi sıkıştır 🔁

⚡ Diğer Küçük Ama Etkili Etkenler

  • Batch API (OpenAI, Anthropic): %50 indirim, latency önemli değilse ✅
  • Provisioned Throughput (Azure, Bedrock): Yüksek trafikte sabit fiyat, şok koruması 🛡
  • Streaming vs non-streaming: Bazı sağlayıcılar streaming'de token bazlı faturalandırma yapıyor, bazılar istek bazlı — detayları oku 📖

🧭 Özet: Tasarruf Checklist'i

  • Prompt cache aktif mi, key doğru mu?
  • İş için en küçük yeterli model hangisi?
  • Context'i RAG/summarization ile küçültmüştük mü?
  • Batch / provisioned throughput değer mi?
  • max_tokens ve stop sequence'ler ayarlandı mı?

Son söz: Maliyet optimizasyonu tek seferlik bir ayar değil, sürekli bir gözlem döngüsü 🔁. Metriklerini topla, dene, ölç, tekrar et.


💡 Bonus Tavsiye (Bonus Tavsiye)

Token maliyetini hala düşürebilir miyiz? Elbette! İşte birkaç "altın değerinde" ipucu 🎯

1. Prompt Mühendisliği ile Kısalt

  • Sistem mesajını minimumda tut — gereksiz "Sen bir yardımcı asistanısın" yerine doğrudan görevi tanımla
  • Few-shot örnekleri temizle: 3-5 örnek genellikle yeterli, 20 şart değil
  • Tekrar eden kısımları şablonlaştır, her istekte tekrar gönderme ❗️

2. max_tokens ve stop Parametrelerini Kullan

{
  "max_tokens": 500,
  "stop": ["\n\n", "###"]
}

Bu sayede model sonsuz döngüye girmez, cevap tam bitmeden kesilir ✅

3. Küçük / Özel Modelleri Değerlendir

Model Kullanım Alanı Maliyet Avantajı
GPT-4o-mini Basit sınıflandırma, özetleme ~10x ucuz
Özel fine-tuned Domain-specific görevler Prompt boyutu ↓, kalite ↑
Yerel modeller (Llama, Mistral) Veri gizliliği kritikse Token maliyeti = 0 🛠

4. Cache'lemeyi Unutma

Aynı sistem promptu + birkaç sabit few-shot her seferinde gönderiliyorsa → prompt cache (OpenAI, Anthropic) veya semantic cache (GPTCache, Redis + embedding) kur 🔁


Küçük bir değişiklik, ay sonunda dev bir fark yaratır. Deneme yanılma yapmaktan çekinme — her optimize edilen token, bütçene geri döner 💪


Son Söz (Final Words) 🎯

Hadi kısa bir özetle kapatalım:

  • Karşılaştırmayı hatırla – JSON, YAML ve XML’in her biri farklı güçlü yönleri var; projenin ihtiyacına göre en uygun olanı seç.
  • Format seçimini optimize et – LLM entegrasyonlarında veri boyutu, okunabilirlik ve işleme hızı arasında denge kur. Küçük payload’lar için JSON, yapılandırma dosyalarında YAML, eski sistemlerle uyumlulukta XML genelde en iyi sonuç verir.
  • Geleceğe hazırlan 🔮
    • Streaming & chunked responses – Büyük model çıktılarını parçalar halinde işlemek performansı artırır.
    • Schema validation – JSON Schema veya OpenAPI ile giriş/çıkışlarınızı erken doğrulayın.
    • Prompt engineering standartları – Yeni prompt şablonları (few‑shot, chain‑of‑thought) format seçimlerinizi etkileyebilir.
    • Güvenlik & gizlilik – Hassas verileri loglamadan önce maskeleyin; format seçiminiz bu süreci kolaylaştırmalı.

Kısacası: Doğru format, hem geliştirici deneyimini hem de model performansını doğrudan etkiler. Projenizin büyüklüğü, ekibinizin alışkanlıkları ve entegre edeceğiniz araçlar dikkate alınıp en temiz, en hızlı ve en güvenli seçeneği tercih edin. 🚀

Bir sonraki yazıda tekrar görüşmek üzere — happy coding! ✨


Bu içerik tamamen yapay zeka destekli otomasyon sistemi ile üretilmiştir.

Burak Sağlık

Burak Saglik

©2024 Desing and Developed by @Burak Sağlık

All rights reserved