Montag, 25 August 2025

Top 5 diese Woche

Ähnliche Tutorials

Generator Dashboard

Das Generator-Dashboard ist eine multifunktionale Webanwendung, die verschiedene Online-Tools in einem modernen, agenturähnlichen Design bündelt. Nutzer können direkt im Browser Generatoren verwenden, die sonst oft auf vielen unterschiedlichen Webseiten verteilt sind.

Enthaltene Generatoren

  • Passwort-Generator: Erstellt sichere, starke und zufällige Passwörter.
  • Meta-Tag-Generator: Hilft bei der Erstellung von SEO-relevanten Tags wie Title, Description oder OpenGraph.
  • Sitemap-Generator: Erstellt XML-Sitemaps für Google und andere Suchmaschinen.
  • Robots.txt-Generator: Einfaches Tool zum Erzeugen einer passenden robots.txt für jede Webseite.
  • Backlink-Checker (Hinweis: eingeschränkt, da echte Backlink-Analysen externe APIs benötigen).
  • Domain-Name-Generator: Liefert kreative Ideen für neue Webseiten und Projekte.
  • Name-Generator: Vorschläge für Firmen, Künstler oder Gaming-Namen.
  • Username-Generator: Findet passende Benutzernamen für Social Media wie Instagram, TikTok oder YouTube.
  • Hashtag-Generator: Empfiehlt passende Hashtags für Social Media Posts.
  • Meme-Generator: Erstellt witzige Memes mit Bild und Text.
  • Text-Generator: Erstellt Lorem Ipsum, Blindtexte oder Zitate.
  • Spruch-Generator: Vorschläge für Geburtstage, Glückwünsche und besondere Anlässe.

Vorteile

  • Alles in einer Datei: Kein Setup notwendig, direkt lauffähig auf jedem PHP-Server.
  • Agentur-Design: Modernes Dashboard mit kartenbasiertem Layout und professioneller Anmutung.
  • Schnell & übersichtlich: Alle Generatoren sind per Tabs oder Boxen erreichbar.
  • Erweiterbar: Neue Generatoren lassen sich leicht hinzufügen.

Hinweis

Einige Funktionen wie Backlink-Checker oder SEO-Daten benötigen externe APIs oder Scraping, die rechtlich problematisch oder technisch limitiert sein können. In diesem Dashboard sind sie daher nur als Grundversion enthalten.

<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Dreamcodes Generator Dashboard</title>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;800&display=swap" rel="stylesheet">
<style>
:root{
  --bg:#0b1020;
  --panel:#0f1530;
  --muted:#8ea0c0;
  --accent:#6c8cff;
  --accent2:#1ee0a1;
  --card:#121a3a;
  --card2:#101632;
  --stroke:rgba(255,255,255,.08);
  --white:#e8eeff;
}
*{box-sizing:border-box}
html,body{height:100%}
body{
  margin:0;
  font-family:Inter,system-ui,-apple-system,Segoe UI,Roboto,Helvetica,Arial;
  background:
    radial-gradient(1200px 800px at 10% -10%, rgba(108,140,255,.15), transparent 60%),
    radial-gradient(900px 700px at 110% 10%, rgba(30,224,161,.12), transparent 55%),
    var(--bg);
  color:var(--white);
}
.container{max-width:1200px;margin:0 auto;padding:28px}
.header{display:flex;align-items:center;gap:18px;justify-content:space-between;margin-bottom:22px}
.brand{display:flex;align-items:center;gap:14px}
.logo{
  width:42px;height:42px;border-radius:12px;
  background:linear-gradient(135deg,var(--accent),#9aaeff);
  box-shadow:0 8px 24px rgba(108,140,255,.35), inset 0 0 24px rgba(255,255,255,.25)
}
.brand h1{font-size:20px;margin:0;font-weight:800;letter-spacing:.2px}
.search{
  display:flex;gap:10px;align-items:center;width:420px;max-width:60%;
  background:linear-gradient(180deg, rgba(255,255,255,.06), rgba(255,255,255,.02));
  border:1px solid var(--stroke);
  border-radius:14px;padding:10px 12px
}
.search input{width:100%;background:transparent;border:0;outline:0;color:var(--white);font-size:14px}
.kpis{display:grid;grid-template-columns:repeat(4,1fr);gap:14px;margin:18px 0 10px}
.kpi{
  background:linear-gradient(180deg, rgba(255,255,255,.06), rgba(255,255,255,.02));
  border:1px solid var(--stroke);border-radius:16px;padding:16px
}
.kpi small{display:block;color:var(--muted);margin-bottom:8px}
.kpi strong{font-size:20px}
.tools{display:grid;grid-template-columns:repeat(3,1fr);gap:16px;margin-top:12px}
.card{
  background:linear-gradient(180deg, rgba(255,255,255,.06), rgba(255,255,255,.02));
  border:1px solid var(--stroke);border-radius:16px;padding:16px;min-height:260px;display:flex;flex-direction:column
}
.card h3{margin:0 0 12px 0;font-size:16px}
.row{display:flex;gap:10px;flex-wrap:wrap}
.input, textarea, select{
  width:100%;background:rgba(255,255,255,.04);border:1px solid var(--stroke);
  border-radius:12px;color:var(--white);padding:10px 12px;font-size:14px
}
textarea{min-height:92px;resize:vertical}
.btn{
  display:inline-flex;align-items:center;justify-content:center;gap:8px;padding:10px 12px;border-radius:12px;
  background:linear-gradient(180deg, var(--accent), #4f6bff);color:white;border:0;cursor:pointer;font-weight:600
}
.btn.ghost{background:transparent;border:1px solid var(--stroke);color:var(--white)}
.btn.flat{background:linear-gradient(180deg, var(--accent2), #11c087)}
.btn:active{transform:translateY(1px)}
.stack{display:flex;gap:8px;flex-wrap:wrap;margin-top:10px}
.badge{padding:6px 10px;border-radius:999px;background:rgba(255,255,255,.06);border:1px solid var(--stroke);font-size:12px}
.output{
  background:rgba(0,0,0,.25);border:1px dashed var(--stroke);border-radius:12px;padding:12px;margin-top:10px;
  font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;white-space:pre-wrap;word-break:break-word
}
.footer{
  margin:28px auto 12px;max-width:1200px;padding:16px;border-top:1px solid var(--stroke);
  display:flex;align-items:center;justify-content:space-between
}
a{color:#a7b9ff;text-decoration:none}
.grid-two{display:grid;grid-template-columns:1fr 1fr;gap:12px}
.helper{color:var(--muted);font-size:12px;margin-top:6px}
.small{font-size:12px;color:var(--muted)}
canvas{width:100%;height:auto;background:rgba(255,255,255,.03);border:1px solid var(--stroke);border-radius:12px}
.hidden{display:none}
@media(max-width:1080px){.tools{grid-template-columns:repeat(2,1fr)}}
@media(max-width:740px){.tools{grid-template-columns:1fr}.kpis{grid-template-columns:repeat(2,1fr)}.search{max-width:100%}}
</style>
</head>
<body>
<div class="container">
  <div class="header">
    <div class="brand">
      <div class="logo" aria-hidden="true"></div>
      <h1>Generator Dashboard</h1>
    </div>
    <div class="search">
      <svg width="18" height="18" viewBox="0 0 24 24" fill="none" aria-hidden="true"><path d="M21 21l-3.5-3.5" stroke="#a9b6dd" stroke-width="2" stroke-linecap="round"/><circle cx="11" cy="11" r="7" stroke="#a9b6dd" stroke-width="2"/></svg>
      <input id="search" placeholder="Werkzeug suchen" aria-label="Werkzeug suchen">
    </div>
  </div>

  <div class="kpis">
    <div class="kpi"><small>Werkzeuge</small><strong id="kpi-tools">12</strong></div>
    <div class="kpi"><small>Generierte Inhalte</small><strong id="kpi-count">0</strong></div>
    <div class="kpi"><small>Sitemap URLs</small><strong id="kpi-sitemap">0</strong></div>
    <div class="kpi"><small>Letzte Aktion</small><strong id="kpi-last">bereit</strong></div>
  </div>

  <div id="tools" class="tools">

    <!-- Passwort Generator -->
    <section class="card" data-title="Passwort Generator">
      <h3>Passwort Generator</h3>
      <div class="row">
        <div class="grid-two" style="width:100%">
          <label class="small">Länge
            <input id="pw-length" class="input" type="number" min="6" max="128" value="16">
          </label>
          <label class="small">Anzahl
            <input id="pw-count" class="input" type="number" min="1" max="20" value="5">
          </label>
        </div>
        <div class="stack" role="group" aria-label="Optionen">
          <label class="badge"><input id="pw-upper" type="checkbox" checked> Großbuchstaben</label>
          <label class="badge"><input id="pw-lower" type="checkbox" checked> Kleinbuchstaben</label>
          <label class="badge"><input id="pw-num" type="checkbox" checked> Zahlen</label>
          <label class="badge"><input id="pw-symbol" type="checkbox" checked> Sonderzeichen</label>
          <label class="badge"><input id="pw-amb" type="checkbox"> Ähnliche Zeichen meiden</label>
        </div>
        <div>
          <button class="btn" onclick="generatePasswords()">Erzeugen</button>
          <button class="btn ghost" onclick="copyOut('pw-out')">Kopieren</button>
        </div>
      </div>
      <div id="pw-out" class="output" aria-live="polite"></div>
    </section>

    <!-- Meta Tag Generator -->
    <section class="card" data-title="Meta Tag Generator">
      <h3>Meta Tag Generator</h3>
      <div class="row">
        <input id="meta-title" class="input" placeholder="Seitentitel">
        <textarea id="meta-desc" placeholder="Beschreibung"></textarea>
        <input id="meta-url" class="input" placeholder="URL">
        <input id="meta-image" class="input" placeholder="Bild URL für OpenGraph">
        <div>
          <button class="btn" onclick="generateMeta()">Erzeugen</button>
          <button class="btn ghost" onclick="downloadText('meta-out','meta-tags.html')">Download</button>
          <span class="helper">OpenGraph und Twitter enthalten</span>
        </div>
      </div>
      <div id="meta-out" class="output"></div>
    </section>

    <!-- Sitemap Generator -->
    <section class="card" data-title="Sitemap Generator">
      <h3>Sitemap Generator</h3>
      <div class="row">
        <textarea id="sm-urls" placeholder="Eine URL pro Zeile"></textarea>
        <div class="grid-two" style="width:100%">
          <label class="small">Änderungshäufigkeit
            <select id="sm-change" class="input">
              <option>daily</option><option>weekly</option><option>monthly</option><option>yearly</option><option>never</option>
            </select>
          </label>
          <label class="small">Priorität
            <input id="sm-prio" class="input" type="number" min="0" max="1" step="0.1" value="0.7">
          </label>
        </div>
        <div>
          <button class="btn" onclick="generateSitemap()">Erzeugen</button>
          <button class="btn ghost" onclick="downloadText('sm-out','sitemap.xml')">Download</button>
        </div>
      </div>
      <div id="sm-out" class="output"></div>
    </section>

    <!-- robots.txt Generator -->
    <section class="card" data-title="Robots.txt Generator">
      <h3>Robots.txt Generator</h3>
      <div class="row">
        <textarea id="rb-disallow" placeholder="Disallow Pfade. Eine Zeile pro Pfad"></textarea>
        <textarea id="rb-allow" placeholder="Allow Pfade. Eine Zeile pro Pfad"></textarea>
        <input id="rb-sitemap" class="input" placeholder="Sitemap URL optional">
        <div>
          <button class="btn" onclick="generateRobots()">Erzeugen</button>
          <button class="btn ghost" onclick="downloadText('rb-out','robots.txt')">Download</button>
        </div>
      </div>
      <div id="rb-out" class="output"></div>
    </section>

    <!-- Backlink Checker Offline -->
    <section class="card" data-title="Backlink Checker">
      <h3>Backlink Checker lokal</h3>
      <div class="row">
        <textarea id="bl-input" placeholder="Liste mit Backlink URLs und optionalen Ankern. Beispiel
https://example.com/page Eine Anchor
https://another.com Artikel"></textarea>
        <div>
          <button class="btn" onclick="analyzeBacklinks()">Analysieren</button>
          <button class="btn ghost" onclick="downloadText('bl-out','backlink-auswertung.txt')">Download</button>
          <p class="helper">Offline Analyse. Kein Live Crawl. Für Live Daten sind APIs notwendig</p>
        </div>
      </div>
      <div id="bl-out" class="output"></div>
    </section>

    <!-- Domain Name Generator -->
    <section class="card" data-title="Domain Name Generator">
      <h3>Domain Name Generator</h3>
      <div class="row">
        <input id="dn-keywords" class="input" placeholder="Themen und Begriffe">
        <input id="dn-extensions" class="input" value=".de,.com,.io" placeholder="Endungen durch Komma getrennt">
        <div>
          <button class="btn" onclick="generateDomains()">Erzeugen</button>
          <button class="btn ghost" onclick="copyOut('dn-out')">Kopieren</button>
        </div>
      </div>
      <div id="dn-out" class="output"></div>
    </section>

    <!-- Name Generator -->
    <section class="card" data-title="Name Generator">
      <h3>Name Generator Firmen Künstler Gaming</h3>
      <div class="row">
        <input id="nm-theme" class="input" placeholder="Thema oder Stil">
        <select id="nm-type" class="input">
          <option value="firma">Firma</option>
          <option value="kuenstler">Künstler</option>
          <option value="gaming">Gaming</option>
        </select>
        <div>
          <button class="btn" onclick="generateNames()">Erzeugen</button>
          <button class="btn ghost" onclick="copyOut('nm-out')">Kopieren</button>
        </div>
      </div>
      <div id="nm-out" class="output"></div>
    </section>

    <!-- Username Generator -->
    <section class="card" data-title="Username Generator">
      <h3>Username Generator</h3>
      <div class="row">
        <input id="us-base" class="input" placeholder="Basiswort">
        <select id="us-platform" class="input">
          <option>neutral</option><option>TikTok</option><option>Instagram</option><option>YouTube</option><option>Twitch</option>
        </select>
        <div>
          <button class="btn" onclick="generateUsernames()">Erzeugen</button>
          <button class="btn ghost" onclick="copyOut('us-out')">Kopieren</button>
        </div>
      </div>
      <div id="us-out" class="output"></div>
    </section>

    <!-- Hashtag Generator -->
    <section class="card" data-title="Hashtag Generator">
      <h3>Hashtag Generator</h3>
      <div class="row">
        <input id="ht-topic" class="input" placeholder="Thema">
        <select id="ht-size" class="input">
          <option value="15">15</option><option value="30">30</option><option value="50">50</option>
        </select>
        <div>
          <button class="btn" onclick="generateHashtags()">Erzeugen</button>
          <button class="btn ghost" onclick="copyOut('ht-out')">Kopieren</button>
        </div>
      </div>
      <div id="ht-out" class="output"></div>
    </section>

    <!-- Meme Generator -->
    <section class="card" data-title="Meme Generator">
      <h3>Meme Generator</h3>
      <div class="row">
        <input id="meme-file" class="input" type="file" accept="image/*">
        <input id="meme-top" class="input" placeholder="Text oben">
        <input id="meme-bottom" class="input" placeholder="Text unten">
        <div>
          <button class="btn" onclick="renderMeme()">Vorschau</button>
          <button class="btn ghost" onclick="downloadMeme()">Download</button>
        </div>
      </div>
      <canvas id="meme-canvas" width="800" height="800" class="hidden" aria-label="Meme Vorschau"></canvas>
      <div id="meme-msg" class="helper"></div>
    </section>

    <!-- Text Generator -->
    <section class="card" data-title="Text Generator">
      <h3>Text Generator Lorem Zitate Blindtext</h3>
      <div class="row">
        <select id="tx-type" class="input">
          <option value="lorem">Lorem Ipsum</option>
          <option value="zitat">Zitate</option>
          <option value="blind">Blindtext Deutsch</option>
        </select>
        <label class="small">Absätze
          <input id="tx-paras" class="input" type="number" min="1" max="20" value="3">
        </label>
        <div>
          <button class="btn" onclick="generateText()">Erzeugen</button>
          <button class="btn ghost" onclick="copyOut('tx-out')">Kopieren</button>
        </div>
      </div>
      <div id="tx-out" class="output"></div>
    </section>

    <!-- Spruch Generator -->
    <section class="card" data-title="Spruch Generator">
      <h3>Spruch Generator</h3>
      <div class="row">
        <select id="sp-type" class="input">
          <option>Geburtstag</option>
          <option>Glück</option>
          <option>Motivation</option>
          <option>Liebe</option>
          <option>Dank</option>
        </select>
        <label class="small">Anzahl
          <input id="sp-count" class="input" type="number" min="1" max="30" value="6">
        </label>
        <div>
          <button class="btn" onclick="generateSprueche()">Erzeugen</button>
          <button class="btn ghost" onclick="copyOut('sp-out')">Kopieren</button>
        </div>
      </div>
      <div id="sp-out" class="output"></div>
    </section>

  </div>
</div>

<div class="footer">
  <div class="small">© <span id="year"></span> <a href="https://dreamcodes.net" target="_blank" rel="noopener">Dreamcodes.net</a>, Alle Rechte vorbehalten</div>
  <div class="small">Hinweis zu Backlinks ohne Live Datenquellen nur Offline Auswertung</div>
</div>

<script>
// KPI Hilfen
const incKpi = (id, by=1)=>{ const el=document.getElementById(id); el.textContent = (+el.textContent)+by }
document.getElementById('year').textContent = new Date().getFullYear()

// Suche filtert Karten
document.getElementById('search').addEventListener('input', e=>{
  const q = e.target.value.toLowerCase()
  document.querySelectorAll('.card').forEach(c=>{
    const title = c.dataset.title.toLowerCase()
    c.style.display = title.includes(q) ? '' : 'none'
  })
})

// Kopieren und Download
function copyOut(id){
  const txt = document.getElementById(id).innerText.trim()
  if(!txt){toast('Nichts zum Kopieren');return}
  navigator.clipboard.writeText(txt).then(()=>toast('Inhalt kopiert'))
}
function downloadText(outId, fileName){
  const txt = document.getElementById(outId).innerText
  const blob = new Blob([txt], {type:'text/plain;charset=utf-8'})
  const a = document.createElement('a')
  a.href = URL.createObjectURL(blob)
  a.download = fileName
  document.body.appendChild(a); a.click(); a.remove()
  toast('Datei gespeichert')
}
function toast(msg){ document.getElementById('kpi-last').textContent = msg }

// Zufall
function randInt(n){ return Math.floor(Math.random()*n) }
function pick(arr){ return arr[randInt(arr.length)] }
function slugify(s){ return s.toLowerCase().replace(/[^a-z0-9]+/g,'').substring(0,20) }

// Passwort Generator
function generatePasswords(){
  const len= +document.getElementById('pw-length').value
  const count= +document.getElementById('pw-count').value
  const useU=document.getElementById('pw-upper').checked
  const useL=document.getElementById('pw-lower').checked
  const useN=document.getElementById('pw-num').checked
  const useS=document.getElementById('pw-symbol').checked
  const amb=document.getElementById('pw-amb').checked

  if(!(useU||useL||useN||useS)) return toast('Mindestens ein Zeichensatz wählen')

  let U="ABCDEFGHIJKLMNOPQRSTUVWXYZ"
  let L="abcdefghijklmnopqrstuvwxyz"
  let N="0123456789"
  let S="!@#$%^&*()_+[]{}|;:,.<>?~"
  if(amb){
    U=U.replace(/[OIL]/g,''); L=L.replace(/[oil]/g,''); N=N.replace(/[01]/g,''); S=S.replace(/[-]/g,'')
  }

  const sets=[]
  if(useU) sets.push(U)
  if(useL) sets.push(L)
  if(useN) sets.push(N)
  if(useS) sets.push(S)
  const all=sets.join('')

  const ensureOne = (pw)=>{
    const req=[useU,useL,useN,useS]
    const pools=[U,L,N,S]
    let arr=pw.split('')
    req.forEach((need,i)=>{
      if(!need) return
      if(!arr.some(ch=>pools[i].includes(ch))){
        arr[randInt(arr.length)] = pools[i][randInt(pools[i].length)]
      }
    })
    return arr.join('')
  }

  const list=[]
  for(let i=0;i<count;i++){
    let pw=''
    for(let j=0;j<len;j++){ pw += all[randInt(all.length)] }
    pw = ensureOne(pw)
    list.push(pw)
  }
  document.getElementById('pw-out').textContent = list.join('\n')
  incKpi('kpi-count', list.length)
  toast('Passwörter erzeugt')
}

// Meta Tag Generator
function esc(s){ return s.replace(/&/g,'&amp;').replace(/</g,'&lt;').replace(/>/g,'&gt;').replace(/"/g,'&quot;') }
function generateMeta(){
  const t=document.getElementById('meta-title').value.trim()
  const d=document.getElementById('meta-desc').value.trim()
  const u=document.getElementById('meta-url').value.trim()
  const i=document.getElementById('meta-image').value.trim()
  const html=`<!-- Basis -->
<title>${esc(t)}</title>
<meta name="description" content="${esc(d)}">

<!-- Open Graph -->
<meta property="og:title" content="${esc(t)}">
<meta property="og:description" content="${esc(d)}">
<meta property="og:type" content="website">
<meta property="og:url" content="${esc(u)}">
<meta property="og:image" content="${esc(i)}">

<!-- Twitter -->
<meta name="twitter:card" content="summary_large_image">
<meta name="twitter:title" content="${esc(t)}">
<meta name="twitter:description" content="${esc(d)}">
<meta name="twitter:image" content="${esc(i)}">`
  document.getElementById('meta-out').textContent=html
  incKpi('kpi-count')
  toast('Meta Tags bereit')
}

// Sitemap Generator
function generateSitemap(){
  const urls = document.getElementById('sm-urls').value.split('\n').map(s=>s.trim()).filter(Boolean)
  const change = document.getElementById('sm-change').value
  const prio = document.getElementById('sm-prio').value
  const now = new Date().toISOString().substring(0,10)
  const xml = `<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
${urls.map(u=>`  <url>
    <loc>${u}</loc>
    <lastmod>${now}</lastmod>
    <changefreq>${change}</changefreq>
    <priority>${prio}</priority>
  </url>`).join('\n')}
</urlset>`
  document.getElementById('sm-out').textContent = xml
  document.getElementById('kpi-sitemap').textContent = urls.length
  incKpi('kpi-count')
  toast('Sitemap erstellt')
}

// Robots.txt Generator
function generateRobots(){
  const dis = document.getElementById('rb-disallow').value.split('\n').map(s=>s.trim()).filter(Boolean)
  const alw = document.getElementById('rb-allow').value.split('\n').map(s=>s.trim()).filter(Boolean)
  const sm = document.getElementById('rb-sitemap').value.trim()
  let txt = `User-agent: *\n`
  dis.forEach(p=>txt+=`Disallow: ${p}\n`)
  alw.forEach(p=>txt+=`Allow: ${p}\n`)
  if(sm) txt+=`Sitemap: ${sm}\n`
  document.getElementById('rb-out').textContent = txt
  incKpi('kpi-count')
  toast('robots.txt erstellt')
}

// Backlink Checker offline
function analyzeBacklinks(){
  const lines = document.getElementById('bl-input').value.split('\n').map(s=>s.trim()).filter(Boolean)
  if(!lines.length){toast('Keine Daten');return}
  const items = lines.map(l=>{
    const parts=l.split(/\s+/)
    const url=parts.shift() || ''
    const anchor=parts.join(' ')
    let host=''
    try{ host=new URL(url).host }catch(e){}
    return {url,anchor,host}
  })
  const domains = [...new Set(items.map(i=>i.host).filter(Boolean))]
  const anchors = {}
  items.forEach(i=>{
    const a=i.anchor||'(leer)'
    anchors[a]=(anchors[a]||0)+1
  })
  const topAnchors = Object.entries(anchors).sort((a,b)=>b[1]-a[1]).slice(0,10)
  const txt = [
    `Backlinks insgesamt: ${items.length}`,
    `Einzigartige Domains: ${domains.length}`,
    `Top Anker:`,
    ...topAnchors.map(([a,c])=>` - ${a}: ${c}`),
    ``,
    ...items.map(i=>`${i.url} | Anchor: ${i.anchor||'(leer)'} | Host: ${i.host}`)
  ].join('\n')
  document.getElementById('bl-out').textContent = txt
  incKpi('kpi-count')
  toast('Backlinks ausgewertet')
}

// Domain Name Generator
function generateDomains(){
  const kw = document.getElementById('dn-keywords').value.trim()
  const exts = document.getElementById('dn-extensions').value.split(',').map(s=>s.trim()).filter(Boolean)
  if(!kw){toast('Bitte Begriffe angeben');return}
  const words = kw.split(/[\s,;]+/).map(w=>w.toLowerCase()).filter(Boolean)
  const prefixes=['get','go','try','my','your','super','hyper','neo','prime','first','bright','blue','nova']
  const suffixes=['ly','ify','hub','lab','base','spot','flow','stack','forge','grid','cloud','studio','works','craft']
  const core=[]
  words.forEach(w=>{
    core.push(w)
    core.push(w+pick(suffixes))
    core.push(pick(prefixes)+w)
    if(w.length>4) core.push(w.slice(0,4)+pick(['io','ly','fy']))
  })
  const uniq=[...new Set(core.map(slugify).filter(Boolean))]
  const out=[]
  uniq.slice(0,40).forEach(name=>{
    exts.forEach(e=> out.push(name+e))
  })
  document.getElementById('dn-out').textContent = out.join('\n')
  incKpi('kpi-count')
  toast('Domains vorgeschlagen')
}

// Name Generator
function generateNames(){
  const theme = document.getElementById('nm-theme').value.trim()
  const type = document.getElementById('nm-type').value
  const base = theme ? theme.split(/[\s,;]+/).map(w=>w.charAt(0).toUpperCase()+w.slice(1).toLowerCase()) : ['Nova','Blue','Prime','Echo','Alpha','Pixel','Rocket','Bold','Lumen','Astra']
  const endFirma=['Labs','Media','Digital','Studio','Works','Systems','Solutions','Group','Partners','Foundry']
  const endKunst=['Art','Design','Collective','Vision','Colors','Motion','Frame','Canvas','Gallery','Wave']
  const endGaming=['Esports','Clan','Squad','Force','Legends','Arena','Ops','Storm','Core','Rift']
  let endings = type==='firma'?endFirma : type==='kuenstler'?endKunst : endGaming
  const names=[]
  for(let i=0;i<16;i++){
    const a=pick(base)
    const b=pick(endings)
    names.push(`${a} ${b}`)
    names.push(`${pick(base)}${pick(['ly','ify','io','ix'])}`)
  }
  document.getElementById('nm-out').textContent = [...new Set(names)].slice(0,24).join('\n')
  incKpi('kpi-count')
  toast('Namen generiert')
}

// Username Generator
function generateUsernames(){
  const base = slugify(document.getElementById('us-base').value || 'creator')
  const platform = document.getElementById('us-platform').value
  const nums = ()=> String(Math.floor(10+Math.random()*89))
  const rnd = ()=> Math.random().toString(36).slice(2,5)
  const list=[]
  const core=[base, base+'x', base+'pro', 'the'+base, 'its'+base, base+'hq', base+'tv', base+'official']
  core.forEach(c=>{
    list.push(c+nums())
    list.push(c+'_'+rnd())
    list.push(c+'.'+nums())
  })
  if(platform==='TikTok'){ core.forEach(c=> list.push('iam'+c), list.push(c+'_tt')) }
  if(platform==='Instagram'){ core.forEach(c=> list.push(c+'.ig'), list.push('real'+c)) }
  if(platform==='YouTube'){ core.forEach(c=> list.push(c+'YT'), list.push(c+'Channel')) }
  if(platform==='Twitch'){ core.forEach(c=> list.push(c+'Live'), list.push('x'+c+'x')) }
  document.getElementById('us-out').textContent = [...new Set(list)].slice(0,40).join('\n')
  incKpi('kpi-count')
  toast('Usernames erstellt')
}

// Hashtag Generator
function camel(s){ return s.split(/[\s\-_.]+/).map((w,i)=> i? w.charAt(0).toUpperCase()+w.slice(1) : w.toLowerCase()).join('') }
function generateHashtags(){
  const topic = document.getElementById('ht-topic').value.trim()
  const size = +document.getElementById('ht-size').value
  if(!topic){toast('Thema angeben');return}
  const base = topic.toLowerCase().split(/[\s,;]+/).filter(Boolean)
  const extras=['tips','life','daily','guide','love','goals','hacks','news','update','ideas','creative','vibes','trend','2025','pro','now','today','de']
  const tags=new Set()
  base.forEach(b=>{
    tags.add('#'+b)
    tags.add('#'+b+'de')
    tags.add('#'+camel(b)+'Tips')
    tags.add('#'+b+'Guide')
  })
  while(tags.size < size){
    const a = pick(base)
    const b = pick(extras)
    tags.add('#'+camel(a+b))
  }
  const out=[...tags].slice(0,size)
  document.getElementById('ht-out').textContent = out.join(' ')
  incKpi('kpi-count')
  toast('Hashtags generiert')
}

// Meme Generator
let memeImage=null
document.getElementById('meme-file').addEventListener('change', e=>{
  const f=e.target.files[0]; if(!f){memeImage=null;return}
  const img=new Image()
  img.onload=()=>{ memeImage=img; document.getElementById('meme-msg').textContent='Bild geladen' }
  img.onerror=()=>{ memeImage=null; document.getElementById('meme-msg').textContent='Bild konnte nicht geladen werden' }
  img.src=URL.createObjectURL(f)
})
function renderMeme(){
  const top=document.getElementById('meme-top').value.toUpperCase()
  const bottom=document.getElementById('meme-bottom').value.toUpperCase()
  const canvas=document.getElementById('meme-canvas'); const ctx=canvas.getContext('2d')
  if(!memeImage){toast('Bitte ein Bild wählen');return}
  const maxW=900
  const ratio=memeImage.width/memeImage.height
  canvas.width = Math.min(maxW, memeImage.width)
  canvas.height = Math.round(canvas.width/ratio)

  ctx.drawImage(memeImage,0,0,canvas.width,canvas.height)
  const fit = w=> Math.max(28, Math.min(64, Math.round(w/12)))
  ctx.textAlign='center'
  ctx.fillStyle='white'
  ctx.strokeStyle='black'
  ctx.lineWidth=fit(canvas.width)/6
  ctx.font=`${fit(canvas.width)}px Impact, Arial Black, Arial, sans-serif`

  function drawText(txt,y){
    const lines=wrapText(ctx, txt, canvas.width*0.9)
    lines.forEach((line,i)=>{
      const yy=y + i*(fit(canvas.width)+6)
      ctx.strokeText(line, canvas.width/2, yy)
      ctx.fillText(line, canvas.width/2, yy)
    })
  }
  if(top) drawText(top, fit(canvas.width)+10)
  if(bottom){
    const lines=wrapText(ctx, bottom, canvas.width*0.9)
    const totalH = lines.length*(fit(canvas.width)+6)
    lines.forEach((line,i)=>{
      const yy=canvas.height - totalH + (i*(fit(canvas.width)+6)) - 10
      ctx.strokeText(line, canvas.width/2, yy)
      ctx.fillText(line, canvas.width/2, yy)
    })
  }
  canvas.classList.remove('hidden')
  incKpi('kpi-count')
  toast('Meme gerendert')
}
function wrapText(ctx, text, maxWidth){
  const words=text.split(' ')
  const lines=[]
  let line=''
  for(let n=0;n<words.length;n++){
    const test=line? line+' '+words[n] : words[n]
    if(ctx.measureText(test).width > maxWidth){
      lines.push(line||words[n]); line=words[n]
    } else line=test
  }
  if(line) lines.push(line)
  return lines
}
function downloadMeme(){
  const canvas=document.getElementById('meme-canvas')
  if(canvas.classList.contains('hidden')){toast('Erst Vorschau rendern');return}
  const a=document.createElement('a')
  a.href=canvas.toDataURL('image/png')
  a.download='meme.png'
  document.body.appendChild(a); a.click(); a.remove()
  toast('Meme gespeichert')
}

// Text Generator
function generateText(){
  const type=document.getElementById('tx-type').value
  const paras=+document.getElementById('tx-paras').value
  const out=[]
  const loremP=`Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer at sapien sed elit vehicula vulputate. Fusce auctor, nibh id accumsan mollis, urna justo tempus sem, vitae mattis lectus arcu et neque.`
  const blindP=`Dies ist ein Blindtext auf Deutsch. Er dient zur Demonstration von Layout und Typografie. Inhalt und Bedeutung stehen nicht im Vordergrund. Bitte ignorieren Sie die Aussage und achten Sie auf die Form.`
  const quotes=[`Der Weg ist das Ziel.`,`Wer aufhört besser zu werden, hat aufgehört gut zu sein.`,`Erfolg hat drei Buchstaben: Tun.`,`In der Ruhe liegt die Kraft.`,`Gib jedem Tag die Chance, der schönste deines Lebens zu werden.`]
  for(let i=0;i<paras;i++){
    if(type==='lorem') out.push(loremP)
    else if(type==='blind') out.push(blindP)
    else out.push('Zitat: '+pick(quotes))
  }
  document.getElementById('tx-out').textContent = out.join('\n\n')
  incKpi('kpi-count')
  toast('Text generiert')
}

// Spruch Generator
function generateSprueche(){
  const type=document.getElementById('sp-type').value
  const count=+document.getElementById('sp-count').value
  const pool={
    Geburtstag:[
      'Alles Gute zum Geburtstag. Möge dein neues Jahr voller Freude sein.',
      'Herzlichen Glückwunsch. Bleib gesund und glücklich.',
      'Feier schön und lass dich feiern.'
    ],
    Glück:[
      'Viel Glück auf all deinen Wegen.',
      'Das Glück ist mit den Mutigen.',
      'Heute ist ein guter Tag für gute Nachrichten.'
    ],
    Motivation:[
      'Du schaffst das. Schritt für Schritt.',
      'Erfolg beginnt mit der Entscheidung es zu versuchen.',
      'Fokus, Geduld, Dranbleiben.'
    ],
    Liebe:[
      'Liebe ist das Einzige, was sich verdoppelt, wenn man es teilt.',
      'Du bist mein Heute und alle meine Morger.',
      'Mit dir fühlt sich alles leicht an.'
    ],
    Dank:[
      'Danke für deine Unterstützung.',
      'Ich schätze deine Hilfe sehr.',
      'Danke, dass es dich gibt.'
    ]
  }
  const arr = pool[type] || pool.Geburtstag
  const out=[]
  for(let i=0;i<count;i++){ out.push(pick(arr)) }
  document.getElementById('sp-out').textContent = out.join('\n')
  incKpi('kpi-count')
  toast('Sprüche generiert')
}
</script>
</body>
</html>
Vorheriges Tutorial
Nächstes Tutorial

Hier etwas für dich dabei?