1// Applications Data Array 2const appsData = [ 3 { 4 id: "dava-belgelerim", 5 title: "Dava Belgelerim", 6 category: "legal", 7 featured: true, // Asymmetric display (two columns) 8 badge: "Tüm Platformlar (Mobil & Masaüstü)", 9 icon: "fa-solid fa-scale-balanced", 10 image: "assets/dava_belgelerim_logo.png", 11 description: "UYAP formatındaki (.udf) resmi dava dosyalarını mobil cihazlarınızda ve bilgisayarınızda anında görüntüleyin. Belgeleri PDF, DOC veya TXT formatlarına dönüÅtürün, toplu iÅlem yapın ve güvenle paylaÅın.", 12 specs: [ 13 "GeliÅmiÅ .udf XML AyrıÅtırıcı & ÃevrimdıÅı Görüntüleyici", 14 "Karanlık & Kalitesiz TIFF Taramaları NetleÅtirme Algoritması", 15 "Klasör Yapısını Koruyan Akıllı Toplu PDF DönüÅtürücü", 16 "Cihaz İçi Tam Arama (İnternet/Bulut BaÄlantısı Gerekmez)" 17 ], 18 tags: ["Flutter", "Dart", "UDF Parser", "TIFF to PDF", "Toplu DönüÅtürücü", "Windows & Linux & Android & iOS"], 19 primaryLink: "dava-belgelerim.html", 20 primaryLabel: "Detaylar", 21 secondaryLink: "https://play.google.com/store/apps/details?id=com.aka.uyap_okuyucu", 22 secondaryLabel: "Google Play", 23 privacyLink: "dava-belgelerim-gizlilik-politikasi.html" 24 }, 25 { 26 id: "sozgec", 27 title: "Sözgeç", 28 category: "productivity", 29 featured: true, // Double column display 30 badge: "Mobil Uygulama ve Chrome Eklentisi", 31 icon: "fa-solid fa-filter-circle-xmark", 32 image: "assets/sozgec_logo.png", 33 description: "EkÅi Sözlük için topluluk tabanlı ve yapay zeka destekli akıllı moderasyon mobil uygulaması ve Chrome eklentisi. Kutsal bilgi kaynaÄındaki troll kirliliÄini, provokasyonları, fanatizmi ve nefret söylemini topluluÄun ve yapay zekanın gücüyle hem telefonunuzda hem de tarayıcınızda süzün.", 34 specs: [ 35 "Troll Skoru Rozetleri & Detaylı Kategori Analizi", 36 "Otomatik İçerik Gizleme & Tek Tıkla Orijinal Entry Gösterimi", 37 "KiÅiselleÅtirilebilir Duyarlılık ve Hassasiyet Ayarı", 38 "Tek Tıkla Kolay Raporlama ve Bireysel Engelleme (ð«)", 39 "Mobil Uygulamada Kanser BaÅlık Engelleme & Temiz Gündem Listeleri", 40 "IÅık Hızında Engelleme & Taptaze Güncel Liste Senkronizasyonu" 41 ], 42 tags: ["Chrome Eklentisi", "Android Uygulaması", "EkÅi Sözlük", "Yapay Zeka", "Topluluk Filtresi"], 43 primaryLink: "sozgec.html", 44 primaryLabel: "Detaylar & Kullanım", 45 secondaryLink: "https://chromewebstore.google.com/detail/s%C3%B6zge%C3%A7-ek%C5%9Fi-s%C3%B6zl%C3%BCk-modera/imdmglklbkggpncfibeibbeopecomdkk?authuser=0&hl=en", 46 secondaryLabel: "Chrome MaÄazası", 47 privacyLink: "sozgec-gizlilik-politikasi.html" 48 }, 49 { 50 id: "gazelist", 51 title: "GAZELIST", 52 category: "productivity", 53 featured: true, // Double column display 54 badge: "All Platforms (Mobile & Desktop)", 55 icon: "fa-solid fa-list-check", 56 image: "assets/gazelist_logo.png", 57 description: "A secure, hierarchical task manager and Pomodoro timer. Nest subtasks to any depth, track focus time, sync automatically with Google Drive, and analyze your productivity history with absolute privacy.", 58 specs: [ 59 "Unlimited Nested Task Hierarchy & Drag-and-Drop", 60 "Task-Bound Focus Timer with Ambient Notification Chimes", 61 "Dynamic Tagging (#tag/@person) with Autocomplete Overlays", 62 "Preserved Activity History & Google Drive Automatic Sync" 63 ], 64 tags: ["Flutter", "Dart", "Pomodoro Timer", "Google Drive Sync", "Local Database", "Windows & macOS & Android & iOS"], 65 primaryLink: "gazelist.html", 66 primaryLabel: "Details", 67 secondaryLink: null, 68 secondaryLabel: null, 69 privacyLink: "gazelist-privacy-policy.html" 70 }, 71 { 72 id: "topicraft", 73 title: "Topicraft", 74 category: "productivity", 75 featured: true, 76 badge: "AI-Powered Micro-learning", 77 icon: "fa-solid fa-graduation-cap", 78 image: "assets/topicraft_logo.png", 79 description: "An AI-powered micro-learning platform that transforms any topic into interactive, gamified lesson maps in seconds. Learn through scientific spaced retrieval and active recall quests.", 80 specs: [ 81 "AI-Powered Lesson Roadmap Generation (3-6 chapters)", 82 "Scientific Spaced Retrieval & Active Recall Quests", 83 "Multiple Card Types: Info, Multiple Choice, Match, & True/False",
84 "Gamification Engine with XP, Hearts, and Progression Bars" 85 ], 86 tags: ["Flutter", "Dart", "OpenAI API", "Micro-learning", "Gamification", "Cross-platform"], 87 primaryLink: "topicraft.html", 88 primaryLabel: "Details", 89 secondaryLink: null, 90 secondaryLabel: null, 91 privacyLink: "topicraft-privacy-policy.html" 92 }, 93 { 94 id: "uyap-cevirici", 95 title: "UYAP Ãevirici", 96 category: "legal", 97 featured: false, 98 badge: "Masaüstü Eklentisi", 99 icon: "fa-solid fa-file-word", 100 image: "assets/uyap_cevirici_logo.png", 101 description: "Google Dokümanlar⢠ve UYAP (.udf) arasında biçimlendirme, liste ve görselleri kayıpsız koruyarak çift yönlü dönüÅüm saÄlayan, sunucusuz mimarisiyle %100 güvenli Google Workspace eklentisi.", 102 tags: ["Google Apps Script", "Google Docs API", "UDF Converter"], 103 primaryLink: "https://workspace.google.com/u/0/marketplace/app/uyap_%C3%A7evirici/46494924541?flow_type=2", 104 primaryLabel: "Workspace Market", 105 secondaryLink: null, 106 secondaryLabel: null, 107 privacyLink: "https://docs.google.com/document/d/1LR-iZAjOx-KvHIVGvq_rD-ggNL-kazE313tVN0KN1-E/edit?usp=drive_link", 108 termsLink: "https://docs.google.com/document/d/1E7JcIYNrASBJGuPS7mJ1Uvtl5zlyAAe8pR7OYr_5A6M/edit?usp=drive_link" 109 }, 110 { 111 id: "uyap-indirici", 112 title: "UYAP İndirici", 113 category: "legal", 114 featured: false, 115 badge: "Tarayıcı Eklentisi", 116 icon: "fa-solid fa-cloud-arrow-down", 117 image: "assets/uyap_indirici_logo.png", 118 description: "UYAP VatandaÅ ve Avukat portallarındaki dava dosyası evraklarını otomatik olarak tarayan, filtreleyen, indiren ve mahkeme/esas numarasına göre klasörleyen akıllı tarayıcı eklentisi.", 119 tags: ["Chrome Extension", "JavaScript", "UYAP Automation", "File Downloader", "Local Archive"], 120 primaryLink: "uyap-indirici.html", 121 primaryLabel: "Detaylar", 122 secondaryLink: "https://chromewebstore.google.com/detail/uyap-i%CC%87ndirici/lnddimcnbhiobmjicaajinebalhkkfjd?hl=tr&utm_source=ext_sidebar", 123 secondaryLabel: "Chrome MaÄazası", 124 privacyLink: "uyap-indirici-gizlilik-politikasi.html" 125 }, 126 { 127 id: "aka-manage-calendar", 128 title: "AKA Manage Calendar", 129 category: "productivity", 130 featured: false, 131 badge: "Masaüstü Eklentisi", 132 icon: "fa-solid fa-calendar-days", 133 image: "assets/aka_manage_calendar_logo.png", 134 description: "A Google Sheets add-on to manage your Google Calendar. Import calendar events to a spreadsheet, make edits directly, and sync changes back effortlessly.", 135 tags: ["Google Apps Script", "Calendar API", "Sheets API"], 136 primaryLink: "https://workspace.google.com/marketplace/app/aka_manage_calendar/189500482061?flow_type=2", 137 primaryLabel: "Workspace Market", 138 secondaryLink: "https://docs.google.com/document/d/19GNkEbijz8NM67Slep9rG_Oj47UuDeDtzXfztLE3Gg0/edit?usp=drive_link", 139 secondaryLabel: "FAQ", 140 privacyLink: "https://docs.google.com/document/d/1Jacmk31uC3ZyXc2IcHkNnZ4UR9JG1lS5_8Bk-L_2C9I/edit?usp=drive_link", 141 termsLink: "https://docs.google.com/document/d/1OTaf-fy37WqbtvKoRt9cx7RnbLNJJv7QCzUCKcof-fM/edit?usp=drive_link" 142 }, 143 { 144 id: "aka-ticked-tasks", 145 title: "AKA Ticked Tasks", 146 category: "productivity", 147 featured: false, 148 badge: "Masaüstü Eklentisi", 149 icon: "fa-solid fa-list-check", 150 image: "assets/aka_ticked_tasks_logo.png", 151 description: "A Google Sheets add-on to download and analyze completed Google Tasks. Export task details, view completion statistics, and measure adherence to due dates.", 152 tags: ["Google Apps Script", "Tasks API", "Data Analytics"], 153 primaryLink: "https://workspace.google.com/u/0/marketplace/app/aka_ticked_tasks/409148054319?flow_type=2", 154 primaryLabel: "Workspace Market", 155 secondaryLink: "#", 156 secondaryLabel: "Support", 157 privacyLink: "https://docs.google.com/document/d/1rBKscDN-bbinsbZV-ZYFpKEJMm8h4hQ3Ufb148z0KLY/edit?usp=drive_link", 158 termsLink: "https://docs.google.com/document/d/1Ynn5EepzCedaAKbN8vyH
158B3pU96Bl-vdWfDxBk2yM_G4/edit?usp=drive_link" 159 } 160]; 161 162// Inject App Cards 163const appGrid = document.getElementById('appGrid'); 164 165function renderApps(filterCategory = 'all') { 166 appGrid.innerHTML = ''; 167 168 const filteredApps = filterCategory === 'all' 169 ? appsData 170 : appsData.filter(app => app.category === filterCategory); 171 172 filteredApps.forEach(app => { 173 const card = document.createElement('div'); 174 card.className = `app-card ${app.featured ? 'featured' : ''}`; 175 card.setAttribute('data-category', app.category); 176 177 // Tags HTML 178 const tagsHTML = app.tags.map(tag => `<span class="tech-tag">${tag}</span>`).join(''); 179 180 // Footer Buttons HTML 181 let footerButtonsHTML = ''; 182 if (app.primaryLink) { 183 footerButtonsHTML += `<a href="${app.primaryLink}" class="app-link app-link-primary"><i class="fa-solid fa-download"></i> ${app.primaryLabel}</a>`; 184 } 185 if (app.secondaryLink) { 186 let iconClass = 'fa-solid fa-circle-info'; 187 if (app.secondaryLink.includes('play.google.com')) { 188 iconClass = 'fa-brands fa-google-play'; 189 } else if (app.secondaryLink.includes('chromewebstore.google.com')) { 190 iconClass = 'fa-brands fa-chrome'; 191 } 192 footerButtonsHTML += `<a href="${app.secondaryLink}" target="_blank" class="app-link app-link-secondary"><i class="${iconClass}"></i> ${app.secondaryLabel}</a>`; 193 } 194 195 // Get category label 196 const categoryLabel = app.badge || 'Masaüstü Uygulaması'; 197 198 // Legal Links HTML 199 let legalLinksHTML = ''; 200 if (app.privacyLink || app.termsLink) { 201 legalLinksHTML = ` 202 <div class="app-legal-links">
203 ${app.privacyLink ? `<a href="${app.privacyLink}" target="_blank" class="legal-link"><i class="fa-solid fa-shield-halved"></i> Privacy Policy</a>` : ''} 204 ${app.termsLink ? `<a href="${app.termsLink}" target="_blank" class="legal-link"><i class="fa-solid fa-scale-balanced"></i> Terms</a>` : ''} 205 </div> 206 `; 207 } 208 209 // Specs List HTML (only for featured/asymmetric layout) 210 let specsHTML = ''; 211 if (app.featured && app.specs) { 212 const listItems = app.specs.map(spec => `<li class="spec-item"><i class="fa-solid fa-square-check"></i> <span>${spec}</span></li>`).join(''); 213 specsHTML = ` 214 <div class="app-specs-panel"> 215 <span class="spec-title">[ Yetenekler & Ãzellikler ]</span> 216 <ul class="spec-list"> 217 ${listItems} 218 </ul> 219 </div> 220 `; 221 } 222 223 // Inside card html depends on featured or not 224 if (app.featured) { 225 card.innerHTML = ` 226 <div class="app-card-layout"> 227 <div class="app-featured-split"> 228 <div> 229 ${app.image ? `<div class="app-preview-container"><img class="app-preview" src="${app.image}" alt="${app.title} preview"></div>` : ''} 230 <div class="app-header"> 231 <div class="app-icon"> 232 <i class="${app.icon}"></i> 233 </div> 234 <div class="app-title-group"> 235 <h3>${app.title}</h3> 236 <span class="app-category">${categoryLabel}</span> 237 </div> 238 </div> 239 <div class="app-body"> 240 <p>${app.description}</p> 241 <div class="tech-tags"> 242 ${tagsHTML} 243 </div> 244 ${legalLinksHTML} 245 </div> 246 </div> 247 ${specsHTML} 248 </div> 249 <div class="app-footer"> 250 ${footerButtonsHTML} 251 </div> 252 </div> 253 `; 254 } else { 255 card.innerHTML = ` 256 <div class="app-card-layout"> 257 <div> 258 ${app.image ? `<div class="app-preview-container"><img class="app-preview" src="${app.image}" alt="${app.title} preview"></div>` : ''} 259 <div class="app-header"> 260 <div class="app-icon"> 261 <i class="${app.icon}"></i> 262 </div> 263 <div class="app-title-group"> 264 <h3>${app.title}</h3> 265 <span class="app-category">${categoryLabel}</span> 266 </div> 267 </div> 268 <div class="app-body"> 269 <p>${app.description}</p> 270 <div class="tech-tags"> 271 ${tagsHTML} 272 </div> 273 ${legalLinksHTML} 274 </div> 275 </div> 276 <div class="app-footer"> 277 ${footerButtonsHTML} 278 </div> 279 </div> 280 `; 281 } 282 appGrid.appendChild(card); 283 }); 284} 285 286// Sliding Indicator Logic for Filter Buttons 287const filterIndicator = document.getElementById('filterIndicator'); 288const filterControls = document.getElementById('filterControls'); 289const filterButtons = document.querySelectorAll('.filter-btn'); 290 291function updateFilterIndicator(activeBtn) { 292 if (!filterIndicator || !activeBtn) return; 293
294 // Offset relative to the parent (.filter-controls) 295 const leftOffset = activeBtn.offsetLeft; 296 const buttonWidth = activeBtn.offsetWidth; 297 298 filterIndicator.style.left = `${leftOffset}px`; 299 filterIndicator.style.width = `${buttonWidth}px`; 300} 301 302// Attach filter button actions 303filterButtons.forEach(btn => { 304 btn.addEventListener('click', () => { 305 filterButtons.forEach(b => b.classList.remove('active')); 306 btn.classList.add('active'); 307 updateFilterIndicator(btn); 308 309 const filter = btn.getAttribute('data-filter'); 310 renderApps(filter); 311 }); 312}); 313 314// Window resize listener to keep sliding indicator positioned correctly 315window.addEventListener('resize', () => { 316 const activeBtn = document.querySelector('.filter-btn.active'); 317 updateFilterIndicator(activeBtn); 318}); 319 320// Live Terminal Typing Simulation Ticker in Hero 321const terminalBody = document.getElementById('terminalBody'); 322const terminalLogs = [ 323 { type: 'command', text: 'parse-udf --file="karar_tutanak_2026.udf"' }, 324 { type: 'status', text: 'Reading binary UDF header structure...' }, 325 { type: 'success', text: '[OK] Header verified. XML payload found (Size: 312KB).' }, 326 { type: 'status', text: 'Decrypting embedded electronic signature...' }, 327 { type: 'success', text: '[OK] E-Signature: Valid (Adalet Bakanligi Sertifikasi).' }, 328 { type: 'command', text: 'convert-tiff-to-pdf --input="tarama_ek_03.tiff"' }, 329 { type: 'status', text: 'Enhancing scan contrast & reducing backgrounds...' }, 330 { type: 'success', text: '[OK] Contrast calibrated. Compression ratio: 4.8x.' }, 331 { type: 'success', text: '[OK] PDF generated: tarama_ek_03.pdf (824 KB).' }, 332 { type: 'command', text: 'sync-google-calendar --sheet="AKA Court Hearings"' }, 333 { type: 'status', text: 'Authenticating with Google Workspace API...' }, 334 { type: 'success', text: '[OK] Retrieved 8 events. Synchronized with spreadsheet.' }, 335 { type: 'command', text: 'gazelist-sync --account="[email protected]"' }, 336 { type: 'status', text: 'Verifying database checksums & syncing with Drive...' }, 337 { type: 'success', text: '[OK] Merged 42 local and 12 remote tasks. 0 conflicts.' }, 338 { type: 'command', text: 'sozgec-scan --target="eksi_yazarlar"' }, 339 { type: 'status', text: 'Yazar troll skorları yerel veritabanından taranıyor...' }, 340 { type: 'success', text: '[TAMAM] Yazar troll skoru: %82. Rahatsız edici içerik gizlendi.' }, 341 { type: 'command', text: 'sozgec-report --author="troll_yazar_99"' }, 342 { type: 'status', text: 'Yazar girdileri analiz ediliyor & Yap
342ay Zekaya iletiliyor...' }, 343 { type: 'success', text: '[TAMAM] Yapay Zeka analiz puanı hesaplandı. Liste güncellendi.' } 344]; 345 346let logIndex = 0; 347let terminalLineNumber = 6; 348 349function appendTerminalLog() { 350 if (!terminalBody) return; 351 352 const log = terminalLogs[logIndex]; 353 const logElement = document.createElement('div'); 354 logElement.className = 'terminal-line'; 355 356 let spanClass = 'muted'; 357 let textHTML = log.text; 358 359 if (log.type === 'command') { 360 textHTML = `$ <span class="accent">${log.text}</span>`; 361 } else if (log.type === 'status') { 362 textHTML = `<span class="muted">[status]</span> ${log.text}`; 363 } else if (log.type === 'success') { 364 textHTML = `<span class="success">[ok]</span> ${log.text}`; 365 } 366 367 logElement.innerHTML = `<span class="muted">${terminalLineNumber} </span>${textHTML}`; 368 terminalBody.appendChild(logElement); 369 370 // Auto-scroll to show latest logs 371 terminalBody.scrollTop = terminalBody.scrollHeight; 372 373 // Prune top logs if too many lines to keep widget clean 374 const lines = terminalBody.querySelectorAll('.terminal-line'); 375 if (lines.length > 9) { 376 lines[0].remove(); 377 } 378 379 // Increment log settings 380 logIndex = (logIndex + 1) % terminalLogs.length; 381 terminalLineNumber++; 382} 383 384// Initialize Render & Animations 385document.addEventListener('DOMContentLoaded', () => { 386 renderApps('all'); 387 388 // Initialize filter capsule 389 const activeBtn = document.querySelector('.filter-btn.active'); 390 setTimeout(() => { 391 updateFilterIndicator(activeBtn); 392 }, 100); 393 394 // Start terminal logs ticker 395 setInterval(appendTerminalLog, 2500); 396}); 397 398// Dynamic Header Styling on Scroll 399window.addEventListener('scroll', () => { 400 const header = document.querySelector('header'); 401 if (window.scrollY > 50) { 402 header.style.padding = '0.3rem 0'; 403 header.style.backgroundColor = 'rgba(12, 12, 11, 0.95)'; 404 } else { 405 header.style.padding = '0'; 406 header.style.backgroundColor = 'rgba(12, 12, 11, 0.85)'; 407 } 408});
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.