{"id":209,"date":"2026-10-02T22:38:14","date_gmt":"2026-10-02T19:38:14","guid":{"rendered":"https:\/\/urasuzay.com\/?page_id=209"},"modified":"2026-10-31T20:47:01","modified_gmt":"2026-10-31T17:47:01","slug":"vegamedia","status":"publish","type":"page","link":"https:\/\/urasuzay.com\/index.php\/vegamedia\/","title":{"rendered":"vegamedia"},"content":{"rendered":"\t\t<div data-elementor-type=\"wp-page\" data-elementor-id=\"209\" class=\"elementor elementor-209\">\n\t\t\t\t<div class=\"elementor-element elementor-element-8511ace e-flex e-con-boxed e-con e-parent\" data-id=\"8511ace\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t\t\t\t<div class=\"e-con-inner\">\n\t\t\t\t<div class=\"elementor-element elementor-element-3270906 elementor-widget elementor-widget-html\" data-id=\"3270906\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"html.default\">\n\t\t\t\t\t<!DOCTYPE html>\n<html lang=\"tr\">\n<head>\n<meta charset=\"UTF-8\">\n<meta name=\"viewport\" content=\"width=device-width, initial-scale=1, viewport-fit=cover\">\n<meta name=\"theme-color\" content=\"#5865f2\">\n<meta name=\"mobile-web-app-capable\" content=\"yes\">\n<meta name=\"apple-mobile-web-app-capable\" content=\"yes\">\n<meta name=\"apple-mobile-web-app-status-bar-style\" content=\"black-translucent\">\n<meta name=\"apple-mobile-web-app-title\" content=\"VegaMedia\">\n<link rel=\"manifest\" href=\"\/manifest.json\">\n<link rel=\"apple-touch-icon\" href=\"\/vegamedia-icon-192.png\">\n<link rel=\"icon\" type=\"image\/png\" sizes=\"192x192\" href=\"\/vegamedia-icon-192.png\">\n<title>VegaMedia Chat<\/title>\n<script src=\"https:\/\/cdn.onesignal.com\/sdks\/web\/v16\/OneSignalSDK.page.js\" defer><\/script>\n<style>\n* { box-sizing: border-box; margin: 0; padding: 0; }\n:root {\n    --vh: 1vh;\n    --app-height: 100vh;\n    --safe-top: env(safe-area-inset-top, 0px);\n    --safe-bottom: env(safe-area-inset-bottom, 0px);\n    --safe-left: env(safe-area-inset-left, 0px);\n    --safe-right: env(safe-area-inset-right, 0px);\n    --ui-scale: 1;\n    --touch-min: 44px;\n    --msg-max: 75%;\n    --sidebar-w: 280px;\n}\nhtml {\n    height: 100%;\n    height: -webkit-fill-available;\n    -webkit-text-size-adjust: 100%;\n    text-size-adjust: 100%;\n}\nbody {\n    font-family: system-ui, -apple-system, \"Segoe UI\", Arial, Helvetica, sans-serif;\n    background: #313338;\n    color: white;\n    height: 100%;\n    height: 100dvh;\n    height: var(--app-height);\n    overflow: hidden;\n    padding: var(--safe-top) var(--safe-right) var(--safe-bottom) var(--safe-left);\n    font-size: calc(15px * var(--ui-scale));\n}\n.hidden { display: none !important; }\nbutton { cursor: pointer; font-family: inherit; }\ninput, textarea { font-family: inherit; }\n\n\/* AUTH *\/\n#authScreen {\n    width: 100%; height: 100vh;\n    display: flex; align-items: center; justify-content: center;\n    background: linear-gradient(135deg, #111827, #1e1f22, #111827);\n}\n.authBox {\n    width: 380px; max-width: calc(100% - 30px);\n    padding: 30px; border-radius: 20px;\n    background: #2b2d31;\n    box-shadow: 0 20px 60px rgba(0,0,0,.45);\n}\n.logo {\n    text-align: center; font-size: 30px; font-weight: bold;\n    letter-spacing: 2px; color: #5865f2; margin-bottom: 25px;\n}\n.authBox h2 { text-align: center; margin-bottom: 20px; }\n.inputGroup { margin-top: 13px; }\n.inputGroup label { display: block; margin-bottom: 6px; color: #b5bac1; font-size: 13px; }\n.authBox input {\n    width: 100%; padding: 13px; border: none; outline: none;\n    border-radius: 8px; background: #1e1f22; color: white; font-size: 15px;\n}\n.primaryButton {\n    width: 100%; padding: 13px; margin-top: 18px; border: none;\n    border-radius: 8px; background: #5865f2; color: white;\n    font-weight: bold; font-size: 15px;\n}\n.primaryButton:hover { background: #4752c4; }\n.switch { margin-top: 18px; text-align: center; color: #b5bac1; font-size: 14px; }\n.switch span { color: #7289da; cursor: pointer; font-weight: bold; }\n#error { margin-top: 14px; text-align: center; color: #ff7777; font-size: 14px; }\n.counterRow { margin-top: 5px; display: flex; justify-content: space-between; gap: 10px; font-size: 11px; }\n.charCounter { color: #949ba4; margin-left: auto; }\n.charCounter.limit { color: #ff7777; font-weight: bold; }\n.limitMessage { color: #ff7777; min-height: 14px; }\n\n\/* APP *\/\n#chatScreen { width: 100%; height: 100vh; display: flex; position: relative; }\n\n\/* SIDEBAR *\/\n.sidebar {\n    width: 290px; flex-shrink: 0; background: #2b2d31;\n    display: flex; flex-direction: column;\n    border-right: 1px solid #1e1f22;\n    transition: transform 0.25s ease;\n    z-index: 100;\n}\n.sidebarHeader {\n    height: 64px; display: flex; align-items: center; padding: 0 18px;\n    border-bottom: 1px solid #1e1f22; font-weight: bold; font-size: 19px; color: #5865f2;\n    justify-content: space-between;\n}\n.sidebarContent { flex: 1; overflow-y: auto; padding: 12px; }\n.navTitle { color: #949ba4; font-size: 12px; font-weight: bold; margin: 12px 8px 7px; }\n.channelButton {\n    width: 100%; border: none; border-radius: 7px; padding: 11px;\n    text-align: left; background: transparent; color: #dbdee1;\n    font-size: 15px; margin-bottom: 4px; display: flex; align-items: center; gap: 8px;\n}\n.channelButton:hover { background: #35373c; }\n.channelButton.active { background: #404249; color: white; }\n\n.privateChatItem {\n    width: 100%; border: none; border-radius: 7px; padding: 10px;\n    text-align: left; background: transparent; color: #dbdee1;\n    font-size: 14px; margin-bottom: 3px; display: flex; align-items: center; gap: 10px;\n    cursor: pointer;\n}\n.privateChatItem:hover { background: #35373c; }\n.privateChatItem.active { background: #404249; }\n.privateChatAvatar {\n    width: 32px; height: 32px; border-radius: 50%; background: #5865f2;\n    display: flex; align-items: center; justify-content: center;\n    overflow: hidden; flex-shrink: 0; font-size: 12px; font-weight: bold;\n}\n.privateChatAvatar img { width: 100%; height: 100%; object-fit: cover; }\n.privateChatInfo { min-width: 0; flex: 1; }\n.privateChatName { font-weight: bold; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }\n.privateChatLast { color: #949ba4; font-size: 11px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; margin-top: 2px; }\n\n.searchBox { margin-top: 15px; border-top: 1px solid #404249; padding-top: 15px; }\n.searchInputRow { display: flex; gap: 6px; }\n#userSearchInput {\n    min-width: 0; flex: 1; padding: 10px; border: none; outline: none;\n    border-radius: 7px; background: #1e1f22; color: white;\n}\n#userSearchButton { border: none; border-radius: 7px; background: #5865f2; color: white; padding: 0 12px; }\n#searchMessage { color: #949ba4; font-size: 12px; margin-top: 7px; }\n#searchResult { margin-top: 10px; }\n.searchUserCard {\n    padding: 10px; border-radius: 10px; background: #1e1f22;\n    display: flex; align-items: center; gap: 10px; cursor: pointer; transition: .15s;\n}\n.searchUserCard:hover { background: #35373c; }\n.searchUserInformation { min-width: 0; flex: 1; }\n.searchDisplayName { font-weight: bold; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }\n.searchUsername { color: #949ba4; font-size: 12px; margin-top: 2px; }\n.searchAbout { color: #b5bac1; font-size: 12px; margin-top: 4px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }\n\n.sidebarProfile {\n    padding: 10px; background: #232428;\n    display: flex; align-items: center; gap: 6px;\n    flex-shrink: 0;\n}\n.profileText { min-width: 0; flex: 1; overflow: hidden; }\n.sidebarProfileName { font-weight: bold; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; font-size: 14px; }\n.sidebarProfileUsername { color: #949ba4; font-size: 11px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }\n.iconButton {\n    border: none; border-radius: 7px; background: #35373c; color: white;\n    padding: 8px; font-size: 15px; flex-shrink: 0; min-width: 36px; height: 36px;\n    display: flex; align-items: center; justify-content: center;\n}\n.iconButton:hover { background: #5865f2; }\n\n.avatar {\n    width: 40px; height: 40px; border-radius: 50%; background: #5865f2;\n    display: flex; justify-content: center; align-items: center;\n    overflow: hidden; flex-shrink: 0; font-weight: bold;\n}\n.avatar.large { width: 100px; height: 100px; font-size: 34px; }\n.avatar img { width: 100%; height: 100%; object-fit: cover; }\n\n\/* MAIN CHAT *\/\n.mainChat {\n    flex: 1; min-width: 0; height: 100vh;\n    display: flex; flex-direction: column; background: #313338;\n}\n.chatHeader {\n    min-height: 64px; padding: 8px 20px;\n    display: flex; align-items: center; gap: 12px;\n    border-bottom: 1px solid #292a2e; background: #313338;\n}\n.mobileMenuBtn {\n    display: none; border: none; background: transparent; color: white;\n    font-size: 22px; padding: 6px;\n}\n.chatHeaderText { min-width: 0; flex: 1; }\n#chatTitle { font-weight: bold; font-size: 17px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }\n#chatSubtitle { margin-top: 3px; color: #949ba4; font-size: 12px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }\n\n#messages {\n    flex: 1; overflow-y: auto; display: flex; flex-direction: column;\n    gap: 14px; padding: 20px;\n}\n.emptyChat { margin: auto; text-align: center; color: #949ba4; }\n.message {\n    max-width: 75%; display: flex; gap: 9px; align-items: flex-end;\n    align-self: flex-start; position: relative;\n}\n.message.mine { align-self: flex-end; flex-direction: row-reverse; }\n.messageAvatar {\n    width: 38px; height: 38px; flex-shrink: 0; border-radius: 50%;\n    overflow: hidden; display: flex; align-items: center; justify-content: center;\n    background: #5865f2; font-size: 13px; font-weight: bold;\n}\n.messageAvatar img { width: 100%; height: 100%; object-fit: cover; }\n.messageContent { min-width: 0; }\n.message.mine .messageContent { text-align: right; }\n.messageInformation { margin-bottom: 4px; }\n.messageUsername { font-weight: bold; font-size: 12px; }\n.messageTime { font-size: 10px; color: #949ba4; margin-left: 6px; }\n.messageBubble {\n    display: inline-block; max-width: 100%; padding: 10px 14px;\n    border-radius: 5px 16px 16px 16px; background: #404249;\n    color: #f2f3f5; word-break: break-word; white-space: pre-wrap; text-align: left;\n}\n.message.mine .messageBubble { background: #5865f2; border-radius: 16px 5px 16px 16px; }\n.messageImage { max-width: 240px; border-radius: 10px; margin-top: 6px; cursor: pointer; }\n.messageActions {\n    position: absolute; top: -8px; right: 0;\n    display: none; gap: 4px; background: #2b2d31; border-radius: 6px; padding: 3px;\n}\n.message.mine:hover .messageActions { display: flex; }\n.msgActionBtn {\n    border: none; background: #404249; color: white; border-radius: 4px;\n    padding: 4px 7px; font-size: 12px;\n}\n.msgActionBtn:hover { background: #5865f2; }\n\n.composerArea { padding: 0 20px 15px; position: relative; }\n#typingIndicator { font-size: 12px; color: #949ba4; min-height: 16px; padding: 0 4px 4px; }\n.replyPreview {\n    background: #2b2d31; border-left: 3px solid #5865f2; padding: 8px 12px;\n    margin-bottom: 8px; border-radius: 0 8px 8px 0; font-size: 13px; color: #b5bac1;\n    display: none;\n}\n.replyPreview.show { display: flex; justify-content: space-between; align-items: center; gap: 8px; }\n.msgReplyRef { font-size: 11px; color: #949ba4; margin-bottom: 4px; border-left: 2px solid #5865f2; padding-left: 6px; }\n.msgReactions { display: flex; gap: 4px; flex-wrap: wrap; margin-top: 4px; }\n.reactionChip {\n    background: #2b2d31; border-radius: 12px; padding: 2px 8px; font-size: 12px;\n    cursor: pointer; border: 1px solid #404249;\n}\n.msgExtraActions { display: flex; gap: 4px; margin-top: 4px; flex-wrap: wrap; }\n.msgExtraActions button {\n    border: none; background: #2b2d31; color: #b5bac1; border-radius: 4px;\n    padding: 2px 6px; font-size: 11px; cursor: pointer;\n}\nbody.theme-light { background: #f2f3f5; color: #060607; }\nbody.theme-midnight { background: #0b141a; color: #e9edef; }\nbody.theme-grape { background: #1a1025; color: #f0e6ff; }\nbody.theme-ocean { background: #0a1f2e; color: #e0f2fe; }\nbody.theme-midnight .mainChat,\nbody.theme-grape .mainChat,\nbody.theme-ocean .mainChat { background: inherit; }\n.xpBadge { font-size: 11px; color: #faa61a; margin-top: 2px; }\n.composer {\n    min-height: 52px; border-radius: 10px; background: #383a40;\n    display: flex; align-items: stretch; overflow: hidden;\n}\n#messageInput {\n    flex: 1; min-width: 0; border: none; outline: none;\n    background: transparent; color: white; resize: none;\n    padding: 15px; height: 52px; max-height: 120px; font-size: 15px;\n}\n.composerTools {\n    display: flex; align-items: center; gap: 4px; padding: 0 6px;\n}\n.toolBtn {\n    border: none; background: transparent; color: #b5bac1;\n    font-size: 20px; padding: 6px; border-radius: 6px;\n}\n.toolBtn:hover { background: #404249; color: white; }\n#sendButton {\n    border: none; background: #5865f2; color: white;\n    padding: 0 20px; font-weight: bold;\n}\n.messageCounterRow {\n    display: flex; justify-content: flex-end; gap: 10px;\n    margin-top: 5px; min-height: 15px;\n}\n\n#emojiPanel, #stickerPanel {\n    position: absolute; bottom: 80px; left: 20px; right: 20px;\n    max-width: 340px; background: #2b2d31; border-radius: 12px;\n    padding: 12px; display: none; flex-wrap: wrap; gap: 6px;\n    box-shadow: 0 10px 30px rgba(0,0,0,.5); z-index: 50;\n    max-height: 200px; overflow-y: auto;\n}\n#emojiPanel.show, #stickerPanel.show { display: flex; }\n.emojiItem {\n    font-size: 22px; cursor: pointer; padding: 4px; border-radius: 6px;\n}\n.emojiItem:hover { background: #404249; }\n.stickerItem {\n    font-size: 34px; cursor: pointer; padding: 6px; border-radius: 8px; line-height: 1;\n}\n.stickerItem:hover { background: #404249; }\n.msgSticky { font-size: 52px; line-height: 1.15; padding: 2px 0; }\n.readTicks { font-size: 11px; margin-left: 4px; color: #949ba4; letter-spacing: -1px; }\n.readTicks.blue { color: #53bdeb; }\n\n\/* SHORTS *\/\n#shortsScreen {\n    flex: 1; height: 100vh; background: #000;\n    display: none; flex-direction: column; position: relative;\n}\n#shortsScreen.active { display: flex; }\n.shortsHeader {\n    position: absolute; top: 0; left: 0; right: 0; z-index: 20;\n    padding: 12px 16px; display: flex; align-items: center; gap: 12px;\n    background: linear-gradient(to bottom, rgba(0,0,0,.7), transparent);\n}\n.shortsHeader h2 { font-size: 18px; font-weight: bold; }\n#shortsContainer {\n    flex: 1; overflow-y: scroll; scroll-snap-type: y mandatory;\n    -webkit-overflow-scrolling: touch;\n}\n.shortItem {\n    height: 100vh; width: 100%; scroll-snap-align: start;\n    position: relative; background: #000;\n    display: flex; align-items: center; justify-content: center;\n}\n.shortItem iframe {\n    width: 100%; height: 100%; border: none; max-width: 420px;\n}\n.shortOverlay {\n    position: absolute; bottom: 80px; left: 16px; right: 16px;\n    color: white; text-shadow: 0 1px 4px rgba(0,0,0,.8);\n    pointer-events: none;\n}\n.shortTitle { font-weight: bold; font-size: 15px; margin-bottom: 4px; }\n.shortChannel { font-size: 13px; opacity: .85; }\n\n#gamesScreen {\n    flex: 1; height: 100vh; background: #313338;\n    display: none; flex-direction: column;\n}\n#gamesScreen.active { display: flex; }\n.gameCard {\n    display: flex; align-items: center; gap: 16px;\n    padding: 16px; border-radius: 12px; background: #2b2d31;\n    margin-bottom: 12px; cursor: pointer; transition: .15s;\n}\n.gameCard:hover { background: #35373c; }\n.gameIcon { font-size: 28px; }\n.gameName { font-weight: bold; font-size: 16px; }\n.gameDesc { color: #949ba4; font-size: 13px; margin-top: 3px; }\n.rpsBtns { display: flex; gap: 12px; justify-content: center; margin: 20px 0; flex-wrap: wrap; }\n.rpsBtn {\n    width: 80px; height: 80px; border: none; border-radius: 16px;\n    background: #404249; font-size: 36px; cursor: pointer;\n}\n.rpsBtn:hover { background: #5865f2; }\n.rpsBtn.selected { background: #5865f2; outline: 2px solid #fff; }\n.xoxBoard {\n    display: grid; grid-template-columns: repeat(3, 70px); gap: 8px;\n    justify-content: center; margin: 20px auto;\n}\n.xoxCell {\n    width: 70px; height: 70px; border: none; border-radius: 10px;\n    background: #404249; color: white; font-size: 28px; font-weight: bold;\n    cursor: pointer;\n}\n.xoxCell:hover { background: #5865f2; }\n.gameStatus { text-align: center; margin: 12px 0; color: #b5bac1; font-size: 15px; }\n.gameBackBtn {\n    border: none; border-radius: 8px; padding: 10px 16px;\n    background: #4e5058; color: white; margin-bottom: 12px;\n}\n\n\/* MODALS *\/\n#profileModal, #settingsModal, #shopModal {\n    position: fixed; inset: 0; z-index: 5000;\n    background: rgba(0,0,0,.72);\n    display: flex; justify-content: center; align-items: center; padding: 20px;\n}\n#profileModal.hidden, #settingsModal.hidden, #shopModal.hidden { display: none !important; }\n.profileModalCard {\n    width: 400px; max-width: 100%; max-height: 90vh; overflow-y: auto;\n    border-radius: 18px; background: #2b2d31; padding: 25px;\n}\n.profileModalCard h2 { margin-top: 0; text-align: center; }\n.profilePreviewArea { display: flex; justify-content: center; margin: 15px 0 20px; }\n.profileModalCard label { display: block; margin-top: 15px; margin-bottom: 6px; font-size: 13px; color: #b5bac1; }\n.profileModalCard input[type=\"text\"],\n.profileModalCard textarea,\n.profileModalCard input[type=\"file\"] {\n    width: 100%; border: none; outline: none; border-radius: 8px;\n    background: #1e1f22; color: white; padding: 12px;\n}\n#profileAboutInput { resize: vertical; min-height: 85px; }\n.removePhotoButton {\n    width: 100%; padding: 10px; margin-top: 10px; border: none;\n    border-radius: 7px; background: #ed4245; color: white;\n}\n.modalButtons { margin-top: 20px; display: flex; gap: 10px; }\n.modalButtons button { flex: 1; padding: 11px; border: none; border-radius: 8px; color: white; }\n#profileCancelButton, #settingsCloseBtn { background: #4e5058; }\n#profileSaveButton { background: #5865f2; }\n#profileMessage { min-height: 17px; margin-top: 10px; color: #ff7777; font-size: 13px; text-align: center; }\n\n.soundItem {\n    display: flex; align-items: center; gap: 10px;\n    padding: 10px 12px; border-radius: 8px; background: #1e1f22;\n}\n.soundItem:hover { background: #35373c; }\n.soundItem.selected { outline: 2px solid #5865f2; }\n.soundName { flex: 1; font-size: 14px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }\n.soundPlayBtn, .soundSelectBtn {\n    border: none; border-radius: 6px; padding: 6px 10px; font-size: 13px; color: white;\n}\n.soundPlayBtn { background: #4e5058; }\n.soundSelectBtn { background: #5865f2; }\n\n.sidebarOverlay {\n    display: none; position: fixed; inset: 0; background: rgba(0,0,0,.5); z-index: 90;\n}\n\n\/* ===== WHATSAPP TARZI MOB\u0130L ===== *\/\n@media (max-width: 760px) {\n    :root {\n        --ui-scale: 1.2;\n        --msg-max: 90%;\n        --sidebar-w: min(94vw, 380px);\n        --touch-min: 56px;\n        --wa-bg: #0b141a;\n        --wa-panel: #1f2c34;\n        --wa-in: #202c33;\n        --wa-out: #005c4b;\n        --wa-text: #e9edef;\n        --wa-muted: #8696a0;\n    }\n    body {\n        font-size: 17px;\n        background: var(--wa-bg);\n    }\n    html { zoom: 1; }\n    \/* Mobilde aray\u00fcz\u00fc b\u00fcy\u00fct (\u00e7ok k\u00fc\u00e7\u00fck ekran hissini giderir) *\/\n    #chatScreen, #gamesScreen, #shortsScreen {\n        font-size: 17px;\n    }\n    #chatScreen, .mainChat, #gamesScreen, #shortsScreen,\n    #liveScreen, #profileScreen, #voiceScreen, #mediaScreen {\n        height: 100dvh !important;\n        height: var(--app-height) !important;\n        max-height: 100dvh;\n        background: var(--wa-bg) !important;\n    }\n    .sidebar {\n        position: fixed; left: 0; top: 0; bottom: 0;\n        transform: translateX(-100%);\n        width: var(--sidebar-w);\n        max-width: 100%;\n        z-index: 100;\n        background: var(--wa-panel) !important;\n        padding-top: var(--safe-top);\n        padding-bottom: var(--safe-bottom);\n    }\n    .sidebar.open { transform: translateX(0); }\n    .sidebarOverlay.show { display: block; }\n    .sidebarHeader {\n        background: var(--wa-panel);\n        min-height: 60px;\n        font-size: 20px;\n        padding: 12px 16px;\n    }\n    .channelButton, .privateChatItem {\n        min-height: 64px;\n        padding: 12px 14px;\n        font-size: 16px;\n        border-radius: 0;\n        margin: 0;\n    }\n    .privateChatItem {\n        border-bottom: 1px solid rgba(255,255,255,.06);\n    }\n    .privateChatName { font-size: 16px; font-weight: 600; }\n    .privateChatLast { font-size: 13px; color: var(--wa-muted); margin-top: 4px; }\n    .navTitle { font-size: 13px; letter-spacing: .04em; padding: 12px 14px 6px; }\n\n    .mobileMenuBtn {\n        display: flex !important;\n        align-items: center;\n        justify-content: center;\n        min-width: 44px;\n        min-height: 44px;\n        font-size: 24px;\n        color: var(--wa-text);\n    }\n    .chatHeader {\n        padding: 8px 10px;\n        gap: 10px;\n        min-height: 60px;\n        background: var(--wa-panel) !important;\n        border-bottom: none;\n        box-shadow: 0 1px 0 rgba(0,0,0,.25);\n    }\n    #chatTitle { font-size: 17px; font-weight: 600; color: var(--wa-text); }\n    #chatSubtitle { font-size: 13px; color: var(--wa-muted); margin-top: 2px; }\n    #onlineCounter { font-size: 12px !important; color: #00a884 !important; }\n    #searchMsgBtn, #muteChannelBtn {\n        min-width: 40px; min-height: 40px;\n        background: transparent !important;\n        font-size: 18px;\n    }\n\n    #messages {\n        padding: 8px 8px 12px;\n        gap: 6px;\n        -webkit-overflow-scrolling: touch;\n        background:\n            radial-gradient(ellipse at top, rgba(0,168,132,.08), transparent 50%),\n            var(--wa-bg);\n    }\n    .message {\n        max-width: var(--msg-max);\n        gap: 6px;\n        margin: 2px 4px;\n    }\n    .messageAvatar {\n        width: 32px; height: 32px; font-size: 12px;\n    }\n    .messageUsername { font-size: 13px; color: #53bdeb; }\n    .messageTime { font-size: 11px; color: var(--wa-muted); }\n    .messageBubble {\n        padding: 10px 12px 12px 14px;\n        font-size: 17px !important;\n        line-height: 1.45;\n        word-break: break-word;\n        background: var(--wa-in) !important;\n        color: var(--wa-text) !important;\n        border-radius: 8px 8px 8px 2px;\n        box-shadow: 0 1px 0.5px rgba(0,0,0,.13);\n        max-width: 100%;\n    }\n    .message.mine .messageBubble {\n        background: var(--wa-out) !important;\n        border-radius: 8px 8px 2px 8px;\n    }\n    .message.mine .messageUsername { display: none; }\n    .messageImage {\n        max-width: min(100%, 78vw);\n        width: 100%;\n        height: auto;\n        border-radius: 8px;\n        margin-top: 4px;\n    }\n    .msgReactions { margin-top: 4px; }\n    .reactionChip {\n        font-size: 14px;\n        padding: 4px 8px;\n        background: var(--wa-panel);\n        border-radius: 12px;\n    }\n    .msgExtraActions button {\n        font-size: 12px;\n        padding: 6px 10px;\n        min-height: 36px;\n    }\n\n    .composerArea {\n        padding: 6px 8px calc(8px + var(--safe-bottom));\n        background: var(--wa-panel);\n        border-top: none;\n    }\n    .editorBar { display: none !important; }\n    .composer {\n        gap: 8px;\n        align-items: flex-end;\n        background: transparent;\n    }\n    .composerTools .toolBtn {\n        min-width: 44px;\n        min-height: 44px;\n        font-size: 22px;\n        background: transparent;\n        border: none;\n        color: var(--wa-muted);\n    }\n    #messageInput {\n        font-size: 16px !important;\n        min-height: 48px;\n        max-height: 140px;\n        padding: 12px 16px;\n        border-radius: 24px !important;\n        background: var(--wa-in) !important;\n        color: var(--wa-text) !important;\n        border: none !important;\n        flex: 1;\n    }\n    #sendButton {\n        min-width: 48px;\n        width: 48px;\n        height: 48px;\n        min-height: 48px;\n        padding: 0;\n        border-radius: 50% !important;\n        background: #00a884 !important;\n        color: #fff !important;\n        font-size: 0;\n        position: relative;\n        flex-shrink: 0;\n    }\n    #sendButton::after {\n        content: \"\u27a4\";\n        font-size: 20px;\n        position: absolute;\n        inset: 0;\n        display: flex;\n        align-items: center;\n        justify-content: center;\n    }\n    .messageCounterRow { display: none !important; }\n    #typingIndicator {\n        font-size: 13px;\n        color: var(--wa-muted);\n        padding: 2px 12px;\n    }\n    .replyPreview {\n        background: var(--wa-in);\n        border-radius: 10px;\n        margin: 0 4px 6px;\n        font-size: 14px;\n    }\n\n    .gameCard {\n        padding: 16px 14px;\n        gap: 14px;\n        min-height: 72px;\n        border-radius: 12px;\n        margin-bottom: 8px;\n    }\n    .gameIcon { font-size: 28px; }\n    .gameName { font-size: 17px; }\n    .gameDesc { font-size: 13px; }\n    .profileModalCard {\n        width: 100%;\n        max-width: 100%;\n        max-height: 94dvh;\n        margin: 0;\n        border-radius: 16px 16px 0 0;\n        padding: 20px 16px calc(20px + var(--safe-bottom));\n        background: var(--wa-panel);\n    }\n    #profileModal, #settingsModal, #shopModal {\n        align-items: flex-end;\n        padding: 0;\n    }\n    .xoxBoard, .c4Board, .memGrid { max-width: 100%; }\n    .shortItem {\n        height: 100dvh;\n        height: var(--app-height);\n    }\n    #gamesBody, #mediaBody, #profileBody {\n        -webkit-overflow-scrolling: touch;\n        padding: 12px;\n        background: var(--wa-bg);\n    }\n    .sidebarProfile {\n        padding: 12px;\n        padding-bottom: calc(12px + var(--safe-bottom));\n        background: var(--wa-panel);\n        min-height: 64px;\n    }\n    .sidebarProfileName { font-size: 16px; }\n    .avatar { width: 44px; height: 44px; }\n    #chatHeaderAvatar.avatar { width: 42px; height: 42px; }\n}\n\n\/* K\u00fc\u00e7\u00fck telefonlar *\/\n@media (max-width: 380px) {\n    :root { --ui-scale: 1.08; --msg-max: 90%; }\n    #chatTitle { font-size: 16px; }\n    .messageBubble { font-size: 15px !important; }\n}\n\n\/* Tablet *\/\n@media (min-width: 761px) and (max-width: 1024px) {\n    :root { --ui-scale: 1.08; --msg-max: 70%; --sidebar-w: 300px; }\n    .sidebar { width: var(--sidebar-w); }\n    .messageBubble { font-size: 15px; }\n}\n\n\/* B\u00fcy\u00fck ekran *\/\n@media (min-width: 1025px) {\n    :root { --ui-scale: 1; --msg-max: 65%; }\n    .message { max-width: var(--msg-max); }\n}\n\n\/* Yatay telefon *\/\n@media (max-width: 900px) and (orientation: landscape) {\n    .chatHeader { min-height: 44px; padding: 6px 10px; }\n    #messages { padding: 6px 10px; }\n    .composerArea { padding: 4px 10px 6px; }\n    #messageInput { min-height: 40px; padding: 8px 12px; }\n}\n\n\/* ===== YEN\u0130: CANLI YAYIN + PROF\u0130L SAYFASI + OYUN EKLER\u0130 ===== *\/\n#liveScreen, #profileScreen, #voiceScreen, #mediaScreen {\n    flex: 1; min-width: 0; height: 100vh; background: #313338;\n    display: none; flex-direction: column;\n}\n#liveScreen.active, #profileScreen.active, #voiceScreen.active, #mediaScreen.active { display: flex; }\n.mediaGrid {\n    display: grid;\n    grid-template-columns: repeat(auto-fill, minmax(160px, 1fr));\n    gap: 12px;\n    padding: 4px 0 24px;\n}\n.mediaCard {\n    background: #2b2d31;\n    border-radius: 14px;\n    padding: 14px 12px;\n    cursor: pointer;\n    text-align: center;\n    transition: background .15s, transform .15s;\n}\n.mediaCard:hover { background: #35373c; transform: translateY(-2px); }\n.mediaCard .avatar {\n    width: 72px; height: 72px; margin: 0 auto 10px; font-size: 24px;\n}\n.mediaCardName { font-weight: bold; font-size: 14px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }\n.mediaCardUser { color: #949ba4; font-size: 12px; margin-top: 3px; }\n.mediaCardAbout {\n    color: #b5bac1; font-size: 11px; margin-top: 8px;\n    display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;\n    min-height: 28px;\n}\n.mediaCardMeta { color: #faa61a; font-size: 11px; margin-top: 8px; }\n.voiceMember {\n    display: flex; align-items: center; gap: 12px; padding: 12px 14px;\n    background: #2b2d31; border-radius: 12px; margin-bottom: 8px;\n}\n.voiceMember.speaking { outline: 2px solid #23a559; }\n.voiceMember .vmName { font-weight: bold; flex: 1; }\n.voiceMember .vmMute { color: #949ba4; font-size: 12px; }\n.voiceRoomCard {\n    display: flex; align-items: center; gap: 12px; padding: 14px; border-radius: 12px;\n    background: #2b2d31; margin-bottom: 10px; cursor: pointer;\n}\n.voiceRoomCard:hover { background: #35373c; }\n.vvItem {\n    height: 100vh; width: 100%; scroll-snap-align: start; position: relative;\n    background: #000; display: flex; align-items: center; justify-content: center;\n}\n.vvItem video { width: 100%; height: 100%; max-width: 480px; object-fit: contain; background: #000; }\n.vvOverlay {\n    position: absolute; bottom: 80px; left: 16px; right: 70px; color: #fff;\n    text-shadow: 0 1px 4px rgba(0,0,0,.85); pointer-events: none;\n}\n.vvSideActions {\n    position: absolute; right: 12px; bottom: 100px; z-index: 5;\n    display: flex; flex-direction: column; gap: 12px; align-items: center;\n    pointer-events: auto;\n}\n.vvSideBtn {\n    width: 48px; height: 48px; border-radius: 50%; border: none;\n    background: rgba(0,0,0,.55); color: #fff; font-size: 20px; cursor: pointer;\n    display: flex; align-items: center; justify-content: center;\n}\n.vvSideBtn:hover { background: rgba(88,101,242,.9); }\n.vvSideBtn.liked { background: #ed4245; }\n.vvSideCount { font-size: 11px; color: #fff; text-shadow: 0 1px 3px #000; margin-top: -6px; }\n.vvCommentBox {\n    position: absolute; left: 0; right: 0; bottom: 0; max-height: 45%;\n    background: rgba(20,20,24,.96); z-index: 10; display: none; flex-direction: column;\n    border-radius: 16px 16px 0 0; padding: 12px;\n}\n.vvCommentBox.show { display: flex; }\n.vvCommentList { flex: 1; overflow-y: auto; max-height: 160px; margin-bottom: 8px; }\n.vvCommentRow { font-size: 13px; padding: 6px 4px; border-bottom: 1px solid #2b2d31; }\n.vvCommentRow b { color: #7289da; }\n.vvUploadBox {\n    background: #2b2d31; border-radius: 12px; padding: 14px; margin-top: 14px;\n}\n.profileVideoGrid {\n    display: grid; grid-template-columns: repeat(auto-fill, minmax(140px, 1fr));\n    gap: 10px; margin-top: 12px;\n}\n.profileVideoCard {\n    background: #1e1f22; border-radius: 10px; overflow: hidden; cursor: pointer;\n}\n.profileVideoCard video { width: 100%; height: 180px; object-fit: cover; display: block; }\n.profileVideoCard .pvTitle { font-size: 12px; padding: 6px 8px; color: #b5bac1; }\n.pageBody { flex: 1; overflow-y: auto; padding: 18px 20px 30px; }\n.liveCard {\n    display: flex; align-items: center; gap: 12px; padding: 12px; border-radius: 12px;\n    background: #2b2d31; margin-bottom: 10px; cursor: pointer;\n}\n.liveCard:hover { background: #35373c; }\n.liveBadge {\n    background: #ed4245; color: #fff; font-size: 11px; font-weight: bold;\n    padding: 3px 8px; border-radius: 6px; letter-spacing: 1px;\n}\n.liveCardInfo { min-width: 0; flex: 1; }\n.liveCardTitle { font-weight: bold; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }\n.liveCardSub { color: #949ba4; font-size: 12px; margin-top: 3px; }\n.liveStage { background: #000; border-radius: 12px; overflow: hidden; position: relative; margin-top: 12px; }\n.liveStage video { width: 100%; max-height: 52vh; display: block; background: #000; }\n.recBadge {\n    position: absolute; top: 10px; left: 10px; background: rgba(237,66,69,.92); color: #fff;\n    font-size: 12px; font-weight: bold; padding: 4px 10px; border-radius: 6px;\n}\n.viewerBadge {\n    position: absolute; top: 10px; right: 10px; background: rgba(0,0,0,.6); color: #fff;\n    font-size: 12px; padding: 4px 10px; border-radius: 6px;\n}\n.liveControls { display: flex; gap: 8px; flex-wrap: wrap; margin-top: 12px; }\n.liveBtn {\n    border: none; border-radius: 8px; padding: 11px 14px; color: #fff; font-weight: bold;\n    background: #5865f2;\n}\n.liveBtn.red { background: #ed4245; }\n.liveBtn.green { background: #23a559; }\n.liveBtn.gray { background: #4e5058; }\n.liveInput {\n    width: 100%; padding: 12px; border: none; border-radius: 8px;\n    background: #1e1f22; color: #fff; outline: none;\n}\n.liveChatBox { background: #2b2d31; border-radius: 12px; margin-top: 12px; display: flex; flex-direction: column; }\n.liveChatMsgs { height: 180px; overflow-y: auto; padding: 10px 12px; font-size: 14px; }\n.liveChatMsgs div { margin-bottom: 5px; word-break: break-word; }\n.liveChatMsgs b { color: #b5bac1; }\n.liveChatRow { display: flex; gap: 6px; padding: 8px; border-top: 1px solid #404249; }\n.liveChatRow input { flex: 1; min-width: 0; padding: 10px; border: none; border-radius: 8px; background: #1e1f22; color: #fff; outline: none; }\n.liveChatRow button { border: none; border-radius: 8px; background: #5865f2; color: #fff; padding: 0 14px; }\n.liveNote { color: #949ba4; font-size: 12px; margin-top: 8px; line-height: 1.5; }\n\n.profileHero { display: flex; align-items: center; gap: 18px; flex-wrap: wrap; }\n.profileHeroText { min-width: 0; flex: 1; }\n.profileHeroName { font-size: 24px; font-weight: bold; word-break: break-word; }\n.profileHeroUser { color: #949ba4; margin-top: 2px; }\n.profileHeroAbout { color: #dbdee1; margin-top: 10px; line-height: 1.5; word-break: break-word; }\n.xpBarWrap { margin-top: 18px; background: #1e1f22; border-radius: 10px; padding: 12px; }\n.xpBarTop { display: flex; justify-content: space-between; font-size: 13px; color: #b5bac1; margin-bottom: 8px; }\n.xpBar { height: 10px; border-radius: 6px; background: #404249; overflow: hidden; }\n.xpBarFill { height: 100%; background: linear-gradient(90deg, #5865f2, #eb459e); }\n.statGrid { display: grid; grid-template-columns: repeat(auto-fit, minmax(130px, 1fr)); gap: 10px; margin-top: 14px; }\n.statBox { background: #2b2d31; border-radius: 10px; padding: 12px; text-align: center; }\n.statNum { font-size: 22px; font-weight: bold; }\n.statLabel { color: #949ba4; font-size: 12px; margin-top: 4px; }\n.profileActions { display: flex; gap: 8px; flex-wrap: wrap; margin-top: 16px; }\n.friendRow { display: flex; align-items: center; gap: 10px; padding: 8px 10px; border-radius: 8px; background: #2b2d31; margin-top: 6px; cursor: pointer; }\n.friendRow:hover { background: #35373c; }\n.sectionTitle { color: #949ba4; font-size: 12px; font-weight: bold; margin: 20px 0 6px; letter-spacing: .5px; }\n\n.c4Board { display: grid; grid-template-columns: repeat(7, 1fr); gap: 5px; background: #1d4ed8; padding: 8px; border-radius: 12px; max-width: 360px; margin: 14px auto; overflow: hidden; }\n.c4Cell { aspect-ratio: 1; border-radius: 50%; background: #0f172a; border: none; padding: 0; position: relative; }\n.c4Cell.R { background: #ef4444; animation: c4Drop .35s cubic-bezier(.2,.8,.2,1); }\n.c4Cell.Y { background: #facc15; animation: c4Drop .35s cubic-bezier(.2,.8,.2,1); }\n@keyframes c4Drop {\n  from { transform: translateY(-180px); opacity: .4; }\n  to { transform: translateY(0); opacity: 1; }\n}\n.c4Cols { display: grid; grid-template-columns: repeat(7, 1fr); gap: 5px; max-width: 360px; margin: 0 auto; padding: 0 8px; }\n.c4Cols button { border: none; border-radius: 6px; background: #404249; color: #fff; padding: 6px 0; cursor: pointer; }\n.c4Cols button:hover { background: #5865f2; }\n.memGrid { display: grid; gap: 8px; justify-content: center; margin: 16px auto; }\n.memCard { width: 56px; height: 56px; border: none; border-radius: 10px; background: #5865f2; color: #fff; font-size: 24px; cursor: pointer; transition: transform .15s, background .15s; }\n.memCard:hover { transform: scale(1.05); }\n.memCard.open { background: #404249; }\n.memCard.done { background: #23a559; opacity: .75; }\n.splitWrap { display: flex; gap: 12px; flex-wrap: wrap; justify-content: center; }\n.splitPane { flex: 1; min-width: 280px; max-width: 420px; background: #2b2d31; border-radius: 12px; padding: 12px; }\n.splitPane h3 { text-align: center; margin: 0 0 8px; font-size: 15px; color: #b5bac1; }\n.modeRow { display: flex; gap: 8px; flex-wrap: wrap; justify-content: center; margin: 10px 0; }\n.modeBtn { border: none; border-radius: 8px; padding: 10px 14px; background: #404249; color: #fff; font-weight: bold; cursor: pointer; }\n.modeBtn:hover, .modeBtn.on { background: #5865f2; }\n.editorBar { display: flex; gap: 4px; padding: 4px 12px 0; flex-wrap: wrap; }\n.messageBubble.glow {\n  box-shadow: 0 0 12px rgba(88,101,242,.55), 0 0 24px rgba(235,69,158,.25);\n  animation: chatGlow 2.5s ease-in-out infinite alternate;\n}\n@keyframes chatGlow {\n  from { box-shadow: 0 0 8px rgba(88,101,242,.4); }\n  to { box-shadow: 0 0 18px rgba(235,69,158,.5); }\n}\n.messageBubble.secretLocked {\n  background: #111 !important; color: transparent !important; user-select: none;\n  position: relative; cursor: pointer; min-height: 28px;\n}\n.messageBubble.secretLocked::after {\n  content: \"\ud83e\udd2b Gizli mesaj \u2014 okumak i\u00e7in t\u0131kla (5 sn)\";\n  color: #faa61a; position: absolute; left: 10px; top: 6px; font-size: 12px;\n}\n.diceAnim {\n  display: inline-block; font-size: 28px;\n  animation: diceSpin .6s ease-out;\n}\n@keyframes diceSpin {\n  0% { transform: rotate(0) scale(.5); }\n  60% { transform: rotate(280deg) scale(1.2); }\n  100% { transform: rotate(360deg) scale(1); }\n}\n.comboFx {\n  position: fixed; inset: 0; pointer-events: none; z-index: 9999;\n  background: radial-gradient(circle, rgba(250,200,50,.15), transparent 60%);\n  animation: comboFlash 1.2s ease-out forwards;\n}\n@keyframes comboFlash {\n  0% { opacity: 1; }\n  100% { opacity: 0; }\n}\n#easterEgg {\n  position: fixed; width: 18px; height: 18px; border-radius: 4px;\n  background: #faa61a; cursor: pointer; z-index: 50; opacity: .85;\n  box-shadow: 0 0 8px #faa61a;\n}\n.petBox {\n  background: #1e1f22; border-radius: 12px; padding: 12px; margin-top: 12px; text-align: center;\n}\n.dragOverChat { outline: 3px dashed #5865f2; outline-offset: -6px; }\n.bigBtn { width: 100%; padding: 14px; border: none; border-radius: 10px; background: #5865f2; color: #fff; font-weight: bold; font-size: 16px; margin-top: 10px; }\n.reactionPad { height: 160px; border-radius: 14px; display: flex; align-items: center; justify-content: center; font-size: 20px; font-weight: bold; margin: 16px 0; cursor: pointer; user-select: none; background: #ed4245; }\n.reactionPad.go { background: #23a559; }\n.reactionPad.wait { background: #faa61a; }\n.lbRow { display: flex; justify-content: space-between; padding: 8px 12px; border-radius: 8px; background: #2b2d31; margin-top: 6px; font-size: 14px; }\n.sysMsg { align-self: center; max-width: 90%; text-align: left; background: #1e1f22; color: #b5bac1; border-radius: 10px; padding: 10px 14px; font-size: 13px; white-space: pre-wrap; border-left: 3px solid #faa61a; }\n<\/style>\n<\/head>\n<body>\n\n<!-- AUTH -->\n<div id=\"authScreen\">\n    <div class=\"authBox\">\n        <div class=\"logo\">VEGAMEDIA<\/div>\n        <div id=\"loginBox\">\n            <h2>Giri\u015f Yap<\/h2>\n            <div class=\"inputGroup\">\n                <label>Kullan\u0131c\u0131 ad\u0131<\/label>\n                <input id=\"loginUsername\" type=\"text\" maxlength=\"20\" autocomplete=\"username\" placeholder=\"Kullan\u0131c\u0131 ad\u0131n\">\n            <\/div>\n            <div class=\"inputGroup\">\n                <label>\u015eifre<\/label>\n                <input id=\"loginPassword\" type=\"password\" autocomplete=\"current-password\" placeholder=\"\u015eifren\">\n            <\/div>\n            <button class=\"primaryButton\" id=\"loginButton\">Giri\u015f Yap<\/button>\n            <div class=\"switch\">\n                Hesab\u0131n yok mu? <span id=\"showRegister\">Hesap olu\u015ftur<\/span>\n            <\/div>\n        <\/div>\n        <div id=\"registerBox\" class=\"hidden\">\n            <h2>Hesap Olu\u015ftur<\/h2>\n            <div class=\"inputGroup\">\n                <label>Kullan\u0131c\u0131 ad\u0131<\/label>\n                <input id=\"registerUsername\" type=\"text\" maxlength=\"20\" autocomplete=\"username\" placeholder=\"\u00d6rn: vega123\">\n                <div class=\"counterRow\">\n                    <span class=\"limitMessage\" id=\"registerUsernameLimit\"><\/span>\n                    <span class=\"charCounter\" id=\"registerUsernameCounter\">0 \/ 20<\/span>\n                <\/div>\n            <\/div>\n            <div class=\"inputGroup\">\n                <label>\u015eifre<\/label>\n                <input id=\"registerPassword\" type=\"password\" autocomplete=\"new-password\" placeholder=\"En az 6 karakter\">\n            <\/div>\n            <div class=\"inputGroup\">\n                <label>\u015eifre tekrar<\/label>\n                <input id=\"registerPasswordAgain\" type=\"password\" autocomplete=\"new-password\" placeholder=\"\u015eifreni tekrar yaz\">\n            <\/div>\n            <button class=\"primaryButton\" id=\"registerButton\">Hesap Olu\u015ftur<\/button>\n            <div class=\"switch\">\n                Zaten hesab\u0131n var m\u0131? <span id=\"showLogin\">Giri\u015f yap<\/span>\n            <\/div>\n        <\/div>\n        <div id=\"error\"><\/div>\n    <\/div>\n<\/div>\n\n<!-- CHAT -->\n<div id=\"chatScreen\" class=\"hidden\">\n    <div class=\"sidebarOverlay\" id=\"sidebarOverlay\"><\/div>\n\n    <aside class=\"sidebar\" id=\"sidebar\">\n        <div class=\"sidebarHeader\">\n            VEGAMEDIA\n            <button class=\"iconButton\" id=\"closeSidebarBtn\" style=\"display:none;\">\u2715<\/button>\n        <\/div>\n        <div class=\"sidebarContent\">\n            <div class=\"navTitle\">KANALLAR<\/div>\n            <button class=\"channelButton active\" data-channel=\"general\" id=\"generalChatButton\"># genel<\/button>\n            <button class=\"channelButton\" data-channel=\"oyun\" id=\"oyunChatButton\"># oyun<\/button>\n            <button class=\"channelButton\" data-channel=\"spor\" id=\"sporChatButton\"># spor<\/button>\n            <button class=\"channelButton\" data-channel=\"muzik\" id=\"muzikChatButton\"># m\u00fczik<\/button>\n            <button class=\"channelButton\" data-channel=\"teknoloji\" id=\"teknolojiChatButton\"># teknoloji<\/button>\n            <button class=\"channelButton\" data-channel=\"giyotin\" id=\"giyotinChatButton\"># giyotin \u2694\ufe0f<\/button>\n            <button class=\"channelButton\" data-channel=\"caps\" id=\"capsChatButton\"># CAPS LOCK<\/button>\n            <button class=\"channelButton\" id=\"shortsButton\">\u25b6 Shorts<\/button>\n            <button class=\"channelButton\" id=\"gamesButton\">\ud83c\udfae Oyunlar<\/button>\n            <button class=\"channelButton\" id=\"liveButton\">\ud83d\udcfa Canl\u0131 Yay\u0131n<\/button>\n            <button class=\"channelButton\" id=\"voiceButton\">\ud83c\udf99\ufe0f Sesli Sohbet<\/button>\n            <button class=\"channelButton\" id=\"mediaButton\">\ud83d\uddbc\ufe0f Medya<\/button>\n            <button class=\"channelButton\" id=\"myProfileButton\">\ud83d\udc64 Profilim<\/button>\n            <button class=\"channelButton\" id=\"shopButton\">\ud83d\uded2 D\u00fckkan<\/button>\n            <button class=\"channelButton\" id=\"dailyQuestBtn\">\ud83d\udccb G\u00fcnl\u00fck g\u00f6rev<\/button>\n            <button class=\"channelButton\" id=\"storiesBtn\">\ud83d\udcf8 Hik\u00e2yeler<\/button>\n            <button class=\"channelButton\" id=\"chanceGamesBtn\">\ud83c\udfb0 \u015eans oyunlar\u0131<\/button>\n            <button class=\"channelButton\" id=\"seasonBtn\">\ud83c\udfc5 Haftal\u0131k sezon<\/button>\n            <div class=\"navTitle\" style=\"margin-top:16px;\">GRUPLAR<\/div>\n            <button class=\"channelButton\" id=\"createGroupBtn\" style=\"color:#23a559;\">\u2795 Grup Olu\u015ftur<\/button>\n            <div id=\"groupsList\"><\/div>\n            <div class=\"navTitle\" style=\"margin-top:16px;\">KUL\u00dcPLER<\/div>\n            <button class=\"channelButton\" id=\"createClubBtn\" style=\"color:#faa61a;\">\ud83c\udfe0 Kul\u00fcp Olu\u015ftur<\/button>\n            <div id=\"clubsList\"><\/div>\n            <button class=\"channelButton\" id=\"wallpaperBtn\">\ud83d\uddbc\ufe0f Sohbet duvar ka\u011f\u0131d\u0131<\/button>\n            <button class=\"channelButton\" id=\"duelLinkBtn\">\u2694\ufe0f 1v1 d\u00fcello linki<\/button>\n            <button class=\"channelButton hidden\" id=\"pwaInstallBtn\">\ud83d\udcf2 Uygulamay\u0131 y\u00fckle<\/button>\n            <div class=\"navTitle\" style=\"margin-top:16px;\">\u00d6ZEL SOHBETLER<\/div>\n            <div id=\"privateChatsList\"><\/div>\n            <div class=\"searchBox\">\n                <div class=\"navTitle\">K\u0130\u015e\u0130 ARA \/ MESAJ<\/div>\n                <div class=\"searchInputRow\">\n                    <input id=\"userSearchInput\" maxlength=\"20\" placeholder=\"Ara (ad veya @kullan\u0131c\u0131)\">\n                    <button id=\"userSearchButton\">\ud83d\udd0e<\/button>\n                <\/div>\n                <div id=\"searchMessage\">Yazarak filtrele veya listeden se\u00e7.<\/div>\n                <div id=\"searchResult\"><\/div>\n                <div class=\"navTitle\" style=\"margin-top:12px;\">T\u00dcM HESAPLAR<\/div>\n                <div id=\"allUsersList\" style=\"max-height:220px;overflow-y:auto;\"><\/div>\n            <\/div>\n        <\/div>\n        <div class=\"sidebarProfile\">\n            <div class=\"avatar\" id=\"sidebarAvatar\">V<\/div>\n            <div class=\"profileText\">\n                <div class=\"sidebarProfileName\" id=\"sidebarDisplayName\">Kullan\u0131c\u0131<\/div>\n                <div class=\"sidebarProfileUsername\" id=\"sidebarUsername\">@kullanici<\/div>\n                <div class=\"xpBadge\" id=\"sidebarXp\">XP 0 \u00b7 Lv 1<\/div>\n            <\/div>\n            <button class=\"iconButton\" id=\"themeButton\" title=\"Tema\">\ud83c\udf13<\/button>\n            <button class=\"iconButton\" id=\"settingsButton\" title=\"Ayarlar\">\ud83d\udd14<\/button>\n            <button class=\"iconButton\" id=\"profileButton\" title=\"Profili d\u00fczenle\">\u2699\ufe0f<\/button>\n            <button class=\"iconButton\" id=\"logoutButton\" title=\"\u00c7\u0131k\u0131\u015f\">\u21aa<\/button>\n        <\/div>\n    <\/aside>\n\n    <main class=\"mainChat\" id=\"mainChatArea\">\n        <div class=\"chatHeader\">\n            <button class=\"mobileMenuBtn\" id=\"mobileMenuBtn\">\u2630<\/button>\n            <div class=\"avatar hidden\" id=\"chatHeaderAvatar\">V<\/div>\n            <div class=\"chatHeaderText\">\n                <div id=\"chatTitle\"># genel<\/div>\n                <div id=\"chatSubtitle\">VegaMedia genel sohbet<\/div>\n            <\/div>\n            <button type=\"button\" id=\"searchMsgBtn\" title=\"Mesaj ara\" style=\"border:none;background:#404249;color:#fff;border-radius:6px;padding:6px 10px;cursor:pointer;margin-right:6px;\">\ud83d\udd0e<\/button>\n            <button type=\"button\" id=\"muteChannelBtn\" title=\"Kanal\u0131 sessize al\" style=\"border:none;background:#404249;color:#fff;border-radius:6px;padding:6px 10px;cursor:pointer;margin-right:6px;\">\ud83d\udd14<\/button>\n            <div id=\"onlineCounter\" style=\"font-size:12px;color:#23a559;white-space:nowrap;padding-right:12px;\">\ud83d\udfe2 0 online<\/div>\n        <\/div>\n        <div id=\"pinnedBar\" class=\"hidden\" style=\"background:#1e1f22;border-bottom:1px solid #3f4147;padding:8px 16px;font-size:13px;color:#faa61a;display:none;\"><\/div>\n        <div id=\"msgSearchBar\" class=\"hidden\" style=\"display:none;background:#2b2d31;padding:8px 12px;gap:8px;align-items:center;border-bottom:1px solid #3f4147;\">\n            <input id=\"msgSearchInput\" type=\"search\" placeholder=\"Bu sohbette ara...\" style=\"flex:1;padding:8px 12px;border:none;border-radius:8px;background:#1e1f22;color:#fff;\">\n            <button type=\"button\" id=\"msgSearchGo\" style=\"padding:8px 12px;border:none;border-radius:8px;background:#5865f2;color:#fff;\">Ara<\/button>\n            <button type=\"button\" id=\"msgSearchClose\" style=\"padding:8px 12px;border:none;border-radius:8px;background:#404249;color:#fff;\">\u2715<\/button>\n        <\/div>\n        <div id=\"messages\"><\/div>\n        <div class=\"composerArea\">\n            <div id=\"typingIndicator\"><\/div>\n            <div class=\"replyPreview\" id=\"replyPreview\">\n                <span id=\"replyPreviewText\"><\/span>\n                <button type=\"button\" id=\"cancelReplyBtn\" style=\"border:none;background:#404249;color:#fff;border-radius:4px;padding:4px 8px;\">\u2715<\/button>\n            <\/div>\n            <div id=\"emojiPanel\"><\/div>\n            <div id=\"stickerPanel\"><\/div>\n            <div class=\"editorBar\" id=\"editorBar\">\n                <button type=\"button\" class=\"toolBtn\" data-md=\"**\" title=\"Kal\u0131n\">B<\/button>\n                <button type=\"button\" class=\"toolBtn\" data-md=\"*\" title=\"\u0130talik\">I<\/button>\n                <button type=\"button\" class=\"toolBtn\" data-md=\"~~\" title=\"\u00dcst\u00fc \u00e7izili\">S<\/button>\n                <button type=\"button\" class=\"toolBtn\" data-md=\"`\" title=\"Kod\">`<\/button>\n                <button type=\"button\" class=\"toolBtn\" id=\"quoteBtn\" title=\"Al\u0131nt\u0131\">\u201c<\/button>\n                <button type=\"button\" class=\"toolBtn\" id=\"secretBtn\" title=\"Gizli mesaj\">\ud83e\udd2b<\/button>\n            <\/div>\n            <div class=\"composer\">\n                <div class=\"composerTools\">\n                    <button class=\"toolBtn\" id=\"emojiBtn\" title=\"Emoji\">\ud83d\ude0a<\/button>\n                    <button class=\"toolBtn\" id=\"stickerBtn\" title=\"Sticker\">\ud83c\udfa8<\/button>\n                    <button class=\"toolBtn\" id=\"giftBtn\" title=\"Hediye (5 VC)\">\ud83c\udf81<\/button>\n                    <button class=\"toolBtn\" id=\"fileBtn\" title=\"Resim ekle\">\ud83d\udcce<\/button>\n                    <input type=\"file\" id=\"fileInput\" accept=\"image\/*\" hidden>\n                <\/div>\n                <textarea id=\"messageInput\" maxlength=\"500\" rows=\"1\" placeholder=\"#genel kanal\u0131na mesaj g\u00f6nder\"><\/textarea>\n                <button id=\"sendButton\">G\u00f6nder<\/button>\n            <\/div>\n            <div class=\"messageCounterRow\">\n                <span class=\"limitMessage\" id=\"messageLimitWarning\"><\/span>\n                <span class=\"charCounter\" id=\"messageCounter\">0 \/ 500<\/span>\n            <\/div>\n        <\/div>\n    <\/main>\n\n    <div id=\"shortsScreen\">\n        <div class=\"shortsHeader\">\n            <button class=\"mobileMenuBtn\" id=\"shortsMenuBtn\">\u2630<\/button>\n            <h2>\u25b6 Shorts<\/h2>\n        <\/div>\n        <div id=\"shortsContainer\"><\/div>\n    <\/div>\n\n    <div id=\"gamesScreen\">\n        <div class=\"chatHeader\">\n            <button class=\"mobileMenuBtn\" id=\"gamesMenuBtn\">\u2630<\/button>\n            <div class=\"chatHeaderText\">\n                <div id=\"gamesTitle\">\ud83c\udfae Online Oyunlar<\/div>\n                <div id=\"gamesSubtitle\" style=\"color:#949ba4;font-size:12px;margin-top:3px;\">Arkada\u015flar\u0131nla oyna<\/div>\n            <\/div>\n        <\/div>\n        <div id=\"gamesBody\" style=\"flex:1;overflow-y:auto;padding:20px;\">\n            <div id=\"activeGameArea\" class=\"hidden\" style=\"margin-bottom:16px;\"><\/div>\n            <div id=\"gamesListWrap\">\n            <div class=\"gameCard\" id=\"startRpsBtn\">\n                <div class=\"gameIcon\">\u270a\u270b\u270c\ufe0f<\/div>\n                <div>\n                    <div class=\"gameName\">Ta\u015f Ka\u011f\u0131t Makas<\/div>\n                    <div class=\"gameDesc\">2 ki\u015filik online d\u00fcello<\/div>\n                <\/div>\n            <\/div>\n            <div class=\"gameCard\" id=\"startXoxBtn\">\n                <div class=\"gameIcon\">\u274c\u2b55<\/div>\n                <div>\n                    <div class=\"gameName\">XOX (Tic-Tac-Toe)<\/div>\n                    <div class=\"gameDesc\">2 ki\u015filik online tahta<\/div>\n                <\/div>\n            <\/div>\n            <div class=\"gameCard\" id=\"startDiceBtn\">\n                <div class=\"gameIcon\">\ud83c\udfb2<\/div>\n                <div>\n                    <div class=\"gameName\">Zar At<\/div>\n                    <div class=\"gameDesc\">Sonucu sohbete g\u00f6nder<\/div>\n                <\/div>\n            <\/div>\n            <div class=\"gameCard\" id=\"startConnect4Btn\">\n                <div class=\"gameIcon\">\ud83d\udd34\ud83d\udfe1<\/div>\n                <div>\n                    <div class=\"gameName\">Connect 4<\/div>\n                    <div class=\"gameDesc\">2 ki\u015filik online 4'l\u00fc ba\u011fla<\/div>\n                <\/div>\n            <\/div>\n            <div class=\"gameCard\" id=\"startNumberBtn\">\n                <div class=\"gameIcon\">\ud83d\udd22<\/div>\n                <div>\n                    <div class=\"gameName\">Say\u0131 Tahmin D\u00fcellosu<\/div>\n                    <div class=\"gameDesc\">1-100 aras\u0131, kim daha yak\u0131n?<\/div>\n                <\/div>\n            <\/div>\n            <div class=\"gameCard\" id=\"startMemoryBtn\">\n                <div class=\"gameIcon\">\ud83c\udccf<\/div>\n                <div>\n                    <div class=\"gameName\">Haf\u0131za (Memory)<\/div>\n                    <div class=\"gameDesc\">2 ki\u015filik kart e\u015fle\u015ftirme<\/div>\n                <\/div>\n            <\/div>\n            <div class=\"gameCard\" id=\"startWordBtn\">\n                <div class=\"gameIcon\">\ud83d\udd24<\/div>\n                <div>\n                    <div class=\"gameName\">Kelime Sava\u015f\u0131<\/div>\n                    <div class=\"gameDesc\">Son harften kelime t\u00fcret (2 ki\u015fi)<\/div>\n                <\/div>\n            <\/div>\n            <div class=\"gameCard\" id=\"startReactionBtn\">\n                <div class=\"gameIcon\">\u26a1<\/div>\n                <div>\n                    <div class=\"gameName\">Reaksiyon Testi<\/div>\n                    <div class=\"gameDesc\">Ye\u015fil olunca t\u0131kla, skor tablosuna gir<\/div>\n                <\/div>\n            <\/div>\n            <div class=\"gameCard\" id=\"startClickerBtn\">\n                <div class=\"gameIcon\">\ud83d\udc46<\/div>\n                <div>\n                    <div class=\"gameName\">10 Saniye T\u0131klama<\/div>\n                    <div class=\"gameDesc\">10 saniyede en \u00e7ok t\u0131kla<\/div>\n                <\/div>\n            <\/div>\n            <div class=\"gameCard\" id=\"startHangmanBtn\">\n                <div class=\"gameIcon\">\ud83e\udea2<\/div>\n                <div>\n                    <div class=\"gameName\">Adam Asmaca<\/div>\n                    <div class=\"gameDesc\">Kelimeyi 6 hakta bul<\/div>\n                <\/div>\n            <\/div>\n            <div class=\"gameCard\" id=\"startCarRaceBtn\">\n                <div class=\"gameIcon\">\ud83c\udfce\ufe0f<\/div>\n                <div>\n                    <div class=\"gameName\">2D Araba Yar\u0131\u015f\u0131<\/div>\n                    <div class=\"gameDesc\">\u015eerit de\u011fi\u015ftir, engellerden ka\u00e7 \u00b7 skor tablosu<\/div>\n                <\/div>\n            <\/div>\n            <div class=\"gameCard\" id=\"startUnoBtn\">\n                <div class=\"gameIcon\">\ud83c\udccf<\/div>\n                <div>\n                    <div class=\"gameName\">UNO<\/div>\n                    <div class=\"gameDesc\">1\u20134 oyuncu \u00b7 bot veya arkada\u015f davet<\/div>\n                <\/div>\n            <\/div>\n            <div class=\"gameCard\" id=\"startLudoBtn\">\n                <div class=\"gameIcon\">\ud83c\udfb2<\/div>\n                <div>\n                    <div class=\"gameName\">Ludo (basit)<\/div>\n                    <div class=\"gameDesc\">2\u20134 oyuncu \u00b7 ayn\u0131 cihaz<\/div>\n                <\/div>\n            <\/div>\n            <div class=\"gameCard\" id=\"startAmongBtn\">\n                <div class=\"gameIcon\">\ud83d\ude80<\/div>\n                <div>\n                    <div class=\"gameName\">Crew Panic (Among Us tarz\u0131)<\/div>\n                    <div class=\"gameDesc\">Botlarla veya online \u00b7 g\u00f6rev \u00b7 oylama<\/div>\n                <\/div>\n            <\/div>\n            <div class=\"gameCard\" id=\"startTournamentBtn\">\n                <div class=\"gameIcon\">\ud83c\udfc6<\/div>\n                <div>\n                    <div class=\"gameName\">Turnuva<\/div>\n                    <div class=\"gameDesc\">Tarih \u00b7 oyun \u00b7 \u00f6d\u00fcl VC (kurandan d\u00fc\u015fer)<\/div>\n                <\/div>\n            <\/div>\n            <div class=\"sectionTitle\" style=\"margin:20px 0 10px;\">\ud83d\udee0\ufe0f Topluluk yap\u0131m\u0131 oyunlar<\/div>\n            <div id=\"communityGamesList\"><div class=\"liveNote\">Y\u00fckleniyor...<\/div><\/div>\n            <div class=\"gameCard\" id=\"startLeaderboardBtn\">\n                <div class=\"gameIcon\">\ud83c\udfc6<\/div>\n                <div>\n                    <div class=\"gameName\">Skor Tablolar\u0131<\/div>\n                    <div class=\"gameDesc\">Reaksiyon, t\u0131klama, asmaca ve yar\u0131\u015f liderleri<\/div>\n                <\/div>\n            <\/div>\n            <\/div>\n        <\/div>\n    <\/div>\n\n    <div id=\"liveScreen\">\n        <div class=\"chatHeader\">\n            <button class=\"mobileMenuBtn\" id=\"liveMenuBtn\">\u2630<\/button>\n            <div class=\"chatHeaderText\">\n                <div style=\"font-weight:bold;font-size:17px;\">\ud83d\udcfa Canl\u0131 Yay\u0131n<\/div>\n                <div id=\"liveSubtitle\" style=\"color:#949ba4;font-size:12px;margin-top:3px;\">Yay\u0131n a\u00e7 veya izle<\/div>\n            <\/div>\n        <\/div>\n        <div class=\"pageBody\">\n            <div id=\"liveSetup\">\n                <div class=\"sectionTitle\" style=\"margin-top:0;\">YAYIN A\u00c7<\/div>\n                <input id=\"liveTitleInput\" class=\"liveInput\" maxlength=\"60\" placeholder=\"Yay\u0131n ba\u015fl\u0131\u011f\u0131\">\n                <label style=\"display:flex;align-items:center;gap:8px;margin-top:10px;font-size:14px;color:#dbdee1;\">\n                    <input type=\"checkbox\" id=\"liveMicCheck\" checked> Mikrofonu da ekle\n                <\/label>\n                <div class=\"liveControls\">\n                    <button class=\"liveBtn red\" id=\"liveStartScreenBtn\">\ud83d\udda5\ufe0f Ekran\u0131 Payla\u015f + Kaydet<\/button>\n                    <button class=\"liveBtn green\" id=\"liveStartCamBtn\">\ud83d\udcf7 Kamerayla Yay\u0131n + Kaydet<\/button>\n                <\/div>\n                <div class=\"liveNote\">Yay\u0131n a\u00e7\u0131nca taray\u0131c\u0131 ekran payla\u015fma iznini sorar. \u0130zin verdi\u011fin anda yay\u0131n ve kay\u0131t birlikte ba\u015flar. Yay\u0131n bitince kay\u0131t (.webm) bilgisayar\u0131na otomatik iner. Telefonlarda ekran payla\u015fma \u00e7o\u011fu taray\u0131c\u0131da yoktur, kamera se\u00e7ene\u011fini kullan.<\/div>\n\n                <div class=\"sectionTitle\">AKT\u0130F YAYINLAR<\/div>\n                <div id=\"liveList\"><div class=\"liveNote\">\u015eu an yay\u0131n yok.<\/div><\/div>\n            <\/div>\n\n            <div id=\"liveStageWrap\" class=\"hidden\">\n                <div style=\"display:flex;align-items:center;gap:10px;\">\n                    <div class=\"liveCardInfo\">\n                        <div id=\"liveStageTitle\" style=\"font-weight:bold;font-size:17px;\"><\/div>\n                        <div id=\"liveStageSub\" class=\"liveCardSub\"><\/div>\n                    <\/div>\n                    <button class=\"liveBtn gray\" id=\"liveLeaveBtn\">\u00c7\u0131k<\/button>\n                    <button class=\"liveBtn red hidden\" id=\"liveStopBtn\">Yay\u0131n\u0131 Bitir<\/button>\n                <\/div>\n                <div class=\"liveStage\">\n                    <video id=\"liveVideo\" autoplay playsinline><\/video>\n                    <div class=\"recBadge hidden\" id=\"liveRecBadge\">\ud83d\udd34 REC 00:00<\/div>\n                    <div class=\"viewerBadge\" id=\"liveViewerBadge\">\ud83d\udc41 0<\/div>\n                <\/div>\n                <div id=\"liveStatus\" class=\"liveNote\"><\/div>\n                <div id=\"liveRecordLink\" class=\"liveNote\"><\/div>\n                <div class=\"liveChatBox\">\n                    <div class=\"liveChatMsgs\" id=\"liveChatMsgs\"><\/div>\n                    <div class=\"liveChatRow\">\n                        <input id=\"liveChatInput\" maxlength=\"200\" placeholder=\"Yay\u0131n sohbetine yaz\">\n                        <button id=\"liveChatSend\">G\u00f6nder<\/button>\n                    <\/div>\n                <\/div>\n            <\/div>\n        <\/div>\n    <\/div>\n\n    <div id=\"profileScreen\">\n        <div class=\"chatHeader\">\n            <button class=\"mobileMenuBtn\" id=\"profileMenuBtn\">\u2630<\/button>\n            <div class=\"chatHeaderText\">\n                <div style=\"font-weight:bold;font-size:17px;\">\ud83d\udc64 Profil<\/div>\n            <\/div>\n        <\/div>\n        <div class=\"pageBody\" id=\"profilePageBody\"><\/div>\n    <\/div>\n\n    <div id=\"voiceScreen\">\n        <div class=\"chatHeader\">\n            <button class=\"mobileMenuBtn\" id=\"voiceMenuBtn\">\u2630<\/button>\n            <div class=\"chatHeaderText\">\n                <div style=\"font-weight:bold;font-size:17px;\" id=\"voiceTitle\">\ud83c\udf99\ufe0f Sesli Sohbet<\/div>\n                <div style=\"color:#949ba4;font-size:12px;margin-top:3px;\" id=\"voiceSubtitle\">Oda se\u00e7 veya olu\u015ftur<\/div>\n            <\/div>\n        <\/div>\n        <div class=\"pageBody\" id=\"voiceBody\">\n            <div id=\"voiceLobby\">\n                <input id=\"voiceRoomName\" class=\"liveInput\" placeholder=\"Yeni oda ad\u0131 (\u00f6rn: Genel Ses)\" style=\"margin-bottom:10px;\">\n                <button class=\"liveBtn green\" id=\"voiceCreateBtn\" style=\"width:100%;margin-bottom:16px;\">\u2795 Oda Olu\u015ftur \/ Kat\u0131l<\/button>\n                <div class=\"navTitle\">AKT\u0130F ODALAR<\/div>\n                <div id=\"voiceRoomList\"><div class=\"liveNote\">Y\u00fckleniyor...<\/div><\/div>\n            <\/div>\n            <div id=\"voiceInRoom\" class=\"hidden\">\n                <div class=\"sectionTitle\">\ud83e\ude91 Sanal masa \u2014 avatar\u0131 s\u00fcr\u00fckle (3D ses y\u00f6n\u00fc)<\/div>\n                <div id=\"voiceTable\" style=\"position:relative;width:min(100%,320px);height:280px;margin:12px auto;background:radial-gradient(circle at center,#3a3c42 0%,#1e1f22 70%);border-radius:50%;border:3px solid #5865f2;touch-action:none;\"><\/div>\n                <div id=\"voiceMembers\"><\/div>\n                <div class=\"sectionTitle\" style=\"margin-top:12px;\">\ud83d\udcdd Canl\u0131 altyaz\u0131<\/div>\n                <div id=\"voiceCaptions\" style=\"max-height:120px;overflow-y:auto;background:#1e1f22;border-radius:8px;padding:8px;font-size:12px;color:#b5bac1;margin-bottom:8px;\"><\/div>\n                <button class=\"liveBtn gray\" id=\"voiceCaptionBtn\" style=\"width:100%;margin-bottom:8px;\">\ud83d\udcdd Altyaz\u0131y\u0131 a\u00e7<\/button>\n                <div class=\"liveControls\" style=\"margin-top:16px;\">\n                    <button class=\"liveBtn\" id=\"voiceMuteBtn\">\ud83d\udd07 Sustur<\/button>\n                    <button class=\"liveBtn gray\" id=\"voiceDeafBtn\">\ud83c\udfa7 Sa\u011f\u0131rla\u015ft\u0131r<\/button>\n                    <button class=\"liveBtn\" id=\"voiceFilterBtn\">\ud83c\udf9b\ufe0f Filtre: Kapal\u0131<\/button>\n                    <button class=\"liveBtn gray\" id=\"voiceAmbientBtn\">\ud83c\udf27\ufe0f Ortam<\/button>\n                    <button class=\"liveBtn red\" id=\"voiceLeaveBtn\">\ud83d\udeaa Odadan Ayr\u0131l<\/button>\n                <\/div>\n                <div style=\"margin-top:14px;\">\n                    <div class=\"sectionTitle\">\ud83d\udd0a Soundboard<\/div>\n                    <div id=\"voiceSoundboard\" style=\"display:flex;flex-wrap:wrap;gap:6px;\"><\/div>\n                <\/div>\n                <div id=\"voiceStatus\" class=\"liveNote\" style=\"margin-top:12px;\">Ba\u011flan\u0131yor...<\/div>\n            <\/div>\n        <\/div>\n    <\/div>\n\n    <div id=\"mediaScreen\">\n        <div class=\"chatHeader\">\n            <button class=\"mobileMenuBtn\" id=\"mediaMenuBtn\">\u2630<\/button>\n            <div class=\"chatHeaderText\">\n                <div style=\"font-weight:bold;font-size:17px;\">\ud83d\uddbc\ufe0f Medya<\/div>\n                <div style=\"color:#949ba4;font-size:12px;margin-top:3px;\" id=\"mediaSubtitle\">T\u00fcm profiller<\/div>\n            <\/div>\n        <\/div>\n        <div class=\"pageBody\">\n            <div style=\"display:flex;gap:8px;margin-bottom:14px;flex-wrap:wrap;\">\n                <input id=\"mediaSearchInput\" class=\"liveInput\" placeholder=\"\u0130sim veya @kullan\u0131c\u0131 ara...\" style=\"flex:1;min-width:160px;\">\n                <button class=\"liveBtn\" id=\"mediaRefreshBtn\">Yenile<\/button>\n            <\/div>\n            <div id=\"mediaGrid\" class=\"mediaGrid\"><div class=\"liveNote\">Y\u00fckleniyor...<\/div><\/div>\n        <\/div>\n    <\/div>\n<\/div>\n<div id=\"impersonateBanner\" class=\"hidden\" style=\"position:fixed;top:0;left:0;right:0;z-index:6000;background:#ed4245;color:#fff;padding:8px 12px;display:flex;align-items:center;justify-content:space-between;gap:8px;font-size:13px;\">\n    <span id=\"impersonateText\">Admin modu<\/span>\n    <button id=\"impersonateExitBtn\" style=\"border:none;border-radius:6px;padding:6px 12px;background:#fff;color:#ed4245;font-weight:bold;cursor:pointer;\">\u00c7\u0131k<\/button>\n<\/div>\n\n<div id=\"groupModal\" class=\"hidden\" style=\"position:fixed;inset:0;z-index:5000;background:rgba(0,0,0,.72);display:flex;justify-content:center;align-items:center;padding:20px;\">\n    <div class=\"profileModalCard\" style=\"width:420px;\">\n        <h2>Grup Olu\u015ftur<\/h2>\n        <label>Grup ad\u0131<\/label>\n        <input id=\"groupNameInput\" type=\"text\" maxlength=\"40\" placeholder=\"\u00d6rn: Arkada\u015flar\">\n        <label style=\"margin-top:12px;\">\u00dcyeler (listeden se\u00e7)<\/label>\n        <div id=\"groupMemberPick\" style=\"max-height:200px;overflow-y:auto;background:#1e1f22;border-radius:8px;padding:8px;margin-top:6px;\"><\/div>\n        <div id=\"groupModalMsg\" style=\"font-size:12px;color:#949ba4;margin-top:8px;min-height:16px;\"><\/div>\n        <div class=\"modalButtons\">\n            <button id=\"groupModalCancel\" style=\"background:#4e5058;\">\u0130ptal<\/button>\n            <button id=\"groupModalCreate\" style=\"background:#23a559;\">Olu\u015ftur<\/button>\n        <\/div>\n    <\/div>\n<\/div>\n\n<!-- PROFILE MODAL -->\n<div id=\"profileModal\" class=\"hidden\">\n    <div class=\"profileModalCard\">\n        <h2>Profili D\u00fczenle<\/h2>\n        <div class=\"profilePreviewArea\">\n            <div class=\"avatar large\" id=\"profilePreview\">V<\/div>\n        <\/div>\n        <label>Kullan\u0131c\u0131 ad\u0131<\/label>\n        <input id=\"profileUsernameReadonly\" type=\"text\" disabled>\n        <label>G\u00f6r\u00fcnen ad<\/label>\n        <input id=\"profileDisplayNameInput\" type=\"text\" maxlength=\"24\" placeholder=\"G\u00f6r\u00fcnen ad\">\n        <div class=\"counterRow\">\n            <span class=\"limitMessage\" id=\"displayNameLimit\"><\/span>\n            <span class=\"charCounter\" id=\"displayNameCounter\">0 \/ 24<\/span>\n        <\/div>\n        <label>Hakk\u0131mda<\/label>\n        <textarea id=\"profileAboutInput\" maxlength=\"139\" placeholder=\"Merhaba! VegaMedia kullan\u0131yorum.\"><\/textarea>\n        <div class=\"counterRow\">\n            <span class=\"limitMessage\" id=\"aboutLimit\"><\/span>\n            <span class=\"charCounter\" id=\"aboutCounter\">0 \/ 139<\/span>\n        <\/div>\n        <label>Durum<\/label>\n        <select id=\"profileStatusSelect\" style=\"width:100%;padding:12px;border:none;border-radius:8px;background:#1e1f22;color:white;margin-bottom:10px;\">\n            <option value=\"online\">\ud83d\udfe2 \u00c7evrimi\u00e7i<\/option>\n            <option value=\"idle\">\ud83c\udf19 Bo\u015fta<\/option>\n            <option value=\"dnd\">\u26d4 Rahats\u0131z Etmeyin<\/option>\n            <option value=\"playing\">\ud83c\udfae Oyun Oynuyor<\/option>\n        <\/select>\n        <label>Profil foto\u011fraf\u0131<\/label>\n        <input id=\"profilePhotoInput\" type=\"file\" accept=\"image\/*\">\n        <button class=\"removePhotoButton\" id=\"removePhotoButton\">Profil Foto\u011fraf\u0131n\u0131 Kald\u0131r<\/button>\n        <hr style=\"border:none;border-top:1px solid #404249;margin:16px 0;\">\n        <label>Topluluk oyunu (HTML yap\u0131\u015ft\u0131r)<\/label>\n        <input id=\"cgIconInput\" type=\"text\" maxlength=\"4\" autocomplete=\"off\" placeholder=\"Simge emoji (\ud83d\ude80 \ud83c\udfae \ud83c\udfce\ufe0f)\" style=\"width:100%;padding:10px;border:none;border-radius:8px;background:#1e1f22;color:#fff;margin-bottom:8px;\">\n        <input id=\"cgTitleInput\" type=\"text\" maxlength=\"80\" autocomplete=\"off\" placeholder=\"Oyun ad\u0131 (T\u00fcrk\u00e7e harf destekli)\" style=\"width:100%;padding:10px;border:none;border-radius:8px;background:#1e1f22;color:#fff;margin-bottom:8px;ime-mode:auto;\">\n        <textarea id=\"cgHtmlInput\" maxlength=\"50000\" autocomplete=\"off\" spellcheck=\"false\" placeholder=\"&lt;canvas&gt; veya HTML\/JS oyun kodu...\" style=\"width:100%;min-height:90px;padding:10px;border:none;border-radius:8px;background:#1e1f22;color:#fff;font-family:monospace;font-size:12px;\"><\/textarea>\n        <label style=\"display:flex;align-items:center;gap:8px;margin-top:8px;font-weight:normal;\">\n            <input type=\"checkbox\" id=\"cgSourceOpen\" checked> Kaynak kodu herkese a\u00e7\u0131k (sonradan de\u011fi\u015ftirebilirsin)\n        <\/label>\n        <div style=\"font-size:11px;color:#949ba4;margin-top:4px;\">Profilde ve Oyunlar \u2192 Topluluk yap\u0131m\u0131 alt\u0131nda g\u00f6r\u00fcn\u00fcr. Max ~50KB.<\/div>\n        <div id=\"profileMessage\"><\/div>\n        <div class=\"modalButtons\">\n            <button id=\"profileCancelButton\">\u0130ptal<\/button>\n            <button id=\"profileSaveButton\">Kaydet<\/button>\n        <\/div>\n    <\/div>\n<\/div>\n\n<!-- SETTINGS MODAL -->\n<div id=\"settingsModal\" class=\"hidden\">\n    <div class=\"profileModalCard\" style=\"max-width:420px;\">\n        <h2>Ayarlar<\/h2>\n\n        <label style=\"margin-top:10px;\">Bildirim Sesi (Myinstants)<\/label>\n        <input type=\"text\" id=\"soundSearchInput\" placeholder=\"Ses ara... (\u00f6rnek: vine, zil, bruh)\"\n               style=\"width:100%;padding:12px;border:none;border-radius:8px;background:#1e1f22;color:white;margin-bottom:10px;\">\n        <div id=\"soundList\" style=\"max-height:200px;overflow-y:auto;display:flex;flex-direction:column;gap:6px;\"><\/div>\n        <label style=\"margin-top:18px;\">Kendi Myinstants MP3 Linkin<\/label>\n        <input type=\"text\" id=\"customSoundUrl\" placeholder=\"https:\/\/www.myinstants.com\/media\/sounds\/....mp3\"\n               style=\"width:100%;padding:12px;border:none;border-radius:8px;background:#1e1f22;color:white;\">\n        <div style=\"display:flex;gap:8px;margin-top:10px;\">\n            <button id=\"previewCustomBtn\" style=\"flex:1;padding:10px;border:none;border-radius:8px;background:#4e5058;color:white;\">\u25b6 Dinle<\/button>\n            <button id=\"saveCustomBtn\" style=\"flex:1;padding:10px;border:none;border-radius:8px;background:#5865f2;color:white;\">Kaydet<\/button>\n        <\/div>\n        <div id=\"currentSoundInfo\" style=\"margin-top:14px;font-size:13px;color:#949ba4;text-align:center;\"><\/div>\n\n        <hr style=\"border:none;border-top:1px solid #404249;margin:20px 0;\">\n        <label>G\u00f6r\u00fcn\u00fcm<\/label>\n        <label style=\"display:flex;align-items:center;gap:8px;margin-top:8px;font-weight:normal;color:#dbdee1;\">\n            <input type=\"checkbox\" id=\"compactModeChk\"> Kompakt mesaj g\u00f6r\u00fcn\u00fcm\u00fc\n        <\/label>\n        <label style=\"margin-top:14px;\">Bu sohbet arka plan\u0131<\/label>\n        <select id=\"chatBgSelect\" style=\"width:100%;padding:10px;border:none;border-radius:8px;background:#1e1f22;color:#fff;margin-top:6px;\">\n            <option value=\"\">Varsay\u0131lan (koyu)<\/option>\n            <option value=\"#0b141a\">WhatsApp gece<\/option>\n            <option value=\"#efeae2\">WhatsApp a\u00e7\u0131k<\/option>\n            <option value=\"#1a1a2e\">Gece mor<\/option>\n            <option value=\"#0f2027\">Derin ye\u015fil<\/option>\n            <option value=\"#1b2838\">Steam koyu<\/option>\n            <option value=\"#2d132c\">Bordo<\/option>\n            <option value=\"#0d1b2a\">Okyanus<\/option>\n            <option value=\"#1c1c1c\">Siyah<\/option>\n            <option value=\"grad1\">Mor gradient<\/option>\n            <option value=\"grad2\">Ye\u015fil gradient<\/option>\n            <option value=\"url\">\u00d6zel resim URL...<\/option>\n        <\/select>\n        <input id=\"chatBgUrlInput\" type=\"url\" placeholder=\"https:\/\/... arka plan resmi\" style=\"display:none;width:100%;padding:10px;border:none;border-radius:8px;background:#1e1f22;color:#fff;margin-top:8px;\">\n        <button type=\"button\" id=\"chatBgSaveBtn\" style=\"width:100%;margin-top:8px;padding:10px;border:none;border-radius:8px;background:#5865f2;color:#fff;font-weight:bold;\">Arka plan\u0131 kaydet<\/button>\n        <hr style=\"border:none;border-top:1px solid #404249;margin:16px 0;\">\n        <button type=\"button\" id=\"deleteAccountBtn\" style=\"width:100%;padding:12px;border:none;border-radius:8px;background:#ed4245;color:#fff;font-weight:bold;\">\ud83d\uddd1 Hesab\u0131m\u0131 sil<\/button>\n        <hr style=\"border:none;border-top:1px solid #404249;margin:16px 0;\">\n        <label>Arka plan m\u00fczi\u011fi (MP3 URL)<\/label>\n        <input type=\"url\" id=\"bgMusicUrl\" placeholder=\"https:\/\/...\/muzik.mp3\"\n               style=\"width:100%;padding:12px;border:none;border-radius:8px;background:#1e1f22;color:white;margin-top:6px;\">\n        <label style=\"margin-top:10px;\">M\u00fczik sesi: <span id=\"bgMusicVolLabel\">30<\/span>%<\/label>\n        <input type=\"range\" id=\"bgMusicVol\" min=\"0\" max=\"100\" value=\"30\" style=\"width:100%;margin-top:6px;\">\n        <div style=\"display:flex;gap:8px;margin-top:8px;\">\n            <button type=\"button\" id=\"bgMusicPlayBtn\" style=\"flex:1;padding:10px;border:none;border-radius:8px;background:#23a559;color:#fff;font-weight:bold;\">\u25b6 \u00c7al<\/button>\n            <button type=\"button\" id=\"bgMusicStopBtn\" style=\"flex:1;padding:10px;border:none;border-radius:8px;background:#404249;color:#fff;\">\u23f9 Durdur<\/button>\n        <\/div>\n        <div id=\"dailyQuestBox\" style=\"margin-top:12px;background:#1e1f22;border-radius:10px;padding:12px;font-size:13px;color:#b5bac1;\"><\/div>\n        <div id=\"blockedListBox\" style=\"margin-top:12px;background:#1e1f22;border-radius:10px;padding:12px;font-size:13px;color:#b5bac1;max-height:120px;overflow-y:auto;\"><\/div>\n\n        <hr style=\"border:none;border-top:1px solid #404249;margin:20px 0;\">\n\n        <label>\u015eifre De\u011fi\u015ftir<\/label>\n        <input type=\"password\" id=\"currentPasswordInput\" placeholder=\"Mevcut \u015fifre\"\n               style=\"width:100%;padding:12px;border:none;border-radius:8px;background:#1e1f22;color:white;margin-top:6px;\">\n        <input type=\"password\" id=\"newPasswordInput\" placeholder=\"Yeni \u015fifre (en az 6 karakter)\"\n               style=\"width:100%;padding:12px;border:none;border-radius:8px;background:#1e1f22;color:white;margin-top:8px;\">\n        <input type=\"password\" id=\"newPasswordAgainInput\" placeholder=\"Yeni \u015fifre tekrar\"\n               style=\"width:100%;padding:12px;border:none;border-radius:8px;background:#1e1f22;color:white;margin-top:8px;\">\n        <button id=\"changePasswordBtn\" style=\"width:100%;padding:11px;margin-top:10px;border:none;border-radius:8px;background:#5865f2;color:white;font-weight:bold;\">\u015eifreyi De\u011fi\u015ftir<\/button>\n        <div id=\"passwordMessage\" style=\"min-height:16px;margin-top:8px;font-size:13px;text-align:center;\"><\/div>\n\n        <hr style=\"border:none;border-top:1px solid #404249;margin:18px 0;\">\n        <label>Yan Hesaplar<\/label>\n        <div id=\"sideAccountsList\" style=\"background:#1e1f22;border-radius:10px;padding:10px;margin-top:8px;max-height:140px;overflow-y:auto;font-size:13px;\"><\/div>\n        <div style=\"display:flex;gap:8px;margin-top:8px;flex-wrap:wrap;\">\n            <input id=\"sideAccUser\" placeholder=\"Kullan\u0131c\u0131 ad\u0131\" maxlength=\"20\"\n                   style=\"flex:1;min-width:100px;padding:10px;border:none;border-radius:8px;background:#1e1f22;color:white;\">\n            <input id=\"sideAccPass\" type=\"password\" placeholder=\"\u015eifre (do\u011frulama)\"\n                   style=\"flex:1;min-width:100px;padding:10px;border:none;border-radius:8px;background:#1e1f22;color:white;\">\n            <button id=\"sideAccAddBtn\" style=\"padding:10px 14px;border:none;border-radius:8px;background:#23a559;color:white;font-weight:bold;\">Ekle<\/button>\n        <\/div>\n        <div id=\"sideAccMsg\" style=\"font-size:12px;color:#949ba4;margin-top:6px;\">Admin: \u015fifresiz ge\u00e7i\u015f. Di\u011ferleri: \u015fifre zorunlu.<\/div>\n\n        <div id=\"adminCommandsBox\" class=\"hidden\" style=\"margin-top:18px;\">\n            <hr style=\"border:none;border-top:1px solid #404249;margin:0 0 14px;\">\n            <label style=\"color:#faa61a;\">\u26a1 Admin Paneli<\/label>\n            <div style=\"background:#1e1f22;border-radius:10px;padding:12px;margin-top:8px;\">\n                <div style=\"font-size:13px;margin-bottom:8px;color:#dbdee1;\">Hesaba ge\u00e7 (admin)<\/div>\n                <input id=\"adminLoginUser\" placeholder=\"Kullan\u0131c\u0131 ad\u0131\" maxlength=\"20\"\n                       style=\"width:100%;padding:10px;border:none;border-radius:8px;background:#2b2d31;color:white;\">\n                <button id=\"adminLoginBtn\" style=\"width:100%;margin-top:8px;padding:10px;border:none;border-radius:8px;background:#ed4245;color:white;font-weight:bold;\">Bu hesaba ge\u00e7 (\u015fifresiz)<\/button>\n                <div style=\"font-size:11px;color:#949ba4;margin-top:6px;\">Admin \u015fifresiz yazar; Auth sen admin kal\u0131rs\u0131n. K\u0131rm\u0131z\u0131 banttan \u00e7\u0131kars\u0131n.<\/div>\n            <\/div>\n            <div id=\"adminOnlineInfo\" style=\"background:#1e1f22;border-radius:10px;padding:12px;margin-top:8px;font-size:14px;color:#dbdee1;\">\n                Y\u00fckleniyor...\n            <\/div>\n            <div id=\"adminOnlineList\" style=\"background:#1e1f22;border-radius:10px;padding:12px;margin-top:8px;max-height:160px;overflow-y:auto;font-size:13px;color:#b5bac1;\"><\/div>\n            <div style=\"background:#1e1f22;border-radius:10px;padding:12px;margin-top:10px;font-size:13px;line-height:1.7;color:#dbdee1;\">\n                <div><code>\/giveadmin kullanici<\/code> \u2014 Admin yap<\/div>\n                <div><code>\/dontadmin kullanici<\/code> \u2014 Adminli\u011fi al<\/div>\n                <div><code>\/ban kullanici<\/code> \u2014 Banla<\/div>\n                <div><code>\/unban kullanici<\/code> \u2014 Ban kald\u0131r<\/div>\n                <div><code>\/rename kullanici YeniAd<\/code> \u2014 \u0130sim de\u011fi\u015ftir<\/div>\n                <div><code>\/sayas kullanici mesaj<\/code> \u2014 Ba\u015fkas\u0131n\u0131n a\u011fz\u0131ndan yaz<\/div>\n                <div><code>\/announce mesaj<\/code> \u2014 #genel duyuru<\/div>\n                <div><code>\/clear 10<\/code> \u2014 Son N mesaj\u0131 sil<\/div>\n                <div><code>\/mute kullanici 30<\/code> \u2014 Dk sustur<\/div>\n                <div><code>\/unmute kullanici<\/code> \u2014 Susturma kald\u0131r<\/div>\n                <div><code>\/trivia<\/code> \u2014 Bilgi yar\u0131\u015fmas\u0131 ba\u015flat<\/div>\n                <div><code>\/kick kullanici<\/code> \u2014 Uyar\u0131 mesaj\u0131<\/div>\n                <div><code>\/users<\/code> \u2014 Online listesini sohbete yaz<\/div>\n                <div><code>\/coinflip<\/code> \u2014 Yaz\u0131 tura (herkes)<\/div>\n                <div><code>\/help<\/code> \u2014 T\u00fcm komutlar (herkes)<\/div>\n                <div><code>\/roll 20<\/code>, <code>\/8ball soru<\/code>, <code>\/me<\/code>, <code>\/shrug<\/code>, <code>\/stats<\/code> (herkes)<\/div>\n                <div><code>\/bans<\/code> \u2014 Banl\u0131 listesi<\/div>\n                <div><code>\/whois kullanici<\/code> \u2014 Kullan\u0131c\u0131 bilgisi<\/div>\n                <div><code>\/xp kullanici 100<\/code> \u2014 XP ver\/al<\/div>\n                <div><code>\/slow 10<\/code> \u2014 Yava\u015f mod (0 = kapat)<\/div>\n                <div><code>\/lock<\/code>, <code>\/unlock<\/code> \u2014 Kanal\u0131 kilitle\/a\u00e7<\/div>\n                <div><code>\/poll soru<\/code> \u2014 Anket<\/div>\n                <div><code>\/warn kullanici sebep<\/code> \u2014 Resmi uyar\u0131<\/div>\n                <div><code>\/endlive kullanici<\/code> \u2014 Yay\u0131n\u0131 kapat<\/div>\n            <\/div>\n            <div style=\"font-size:11px;color:#949ba4;margin-top:6px;\">\u015eifreler g\u00f6r\u00fclemez (Firebase hash saklar, d\u00fcz metin yok).<\/div>\n            <div style=\"font-size:11px;color:#949ba4;margin-top:4px;\">Komutlar sohbete yaz\u0131l\u0131r, mesaj olarak g\u00f6r\u00fcnmez.<\/div>\n        <\/div>\n\n        <div class=\"modalButtons\" style=\"margin-top:20px;\">\n            <button id=\"settingsCloseBtn\" style=\"flex:1;padding:11px;border:none;border-radius:8px;background:#4e5058;color:white;\">Kapat<\/button>\n        <\/div>\n    <\/div>\n<\/div>\n\n<!-- D\u00dcKKAN MODAL -->\n<div id=\"shopModal\" class=\"hidden\">\n    <div class=\"profileModalCard\" style=\"max-width:440px;max-height:90vh;overflow-y:auto;\">\n        <h2>\ud83d\uded2 D\u00fckkan<\/h2>\n        <div id=\"shopBalance\" style=\"text-align:center;color:#faa61a;margin-bottom:12px;font-weight:bold;\">\ud83e\ude99 0 VC \u00b7 XP 0<\/div>\n        <div id=\"shopStreak\" style=\"text-align:center;font-size:13px;color:#b5bac1;margin-bottom:12px;\">Seri: \u2014<\/div>\n\n        <label>\ud83c\udfa1 G\u00fcnl\u00fck \u015fansl\u0131 \u00e7ark<\/label>\n        <div style=\"position:relative;width:200px;height:200px;margin:12px auto;\">\n            <div id=\"shopWheelDisc\" style=\"width:200px;height:200px;border-radius:50%;border:4px solid #fff;background:conic-gradient(#ed4245 0 90deg,#faa61a 90deg 180deg,#57f287 180deg 270deg,#5865f2 270deg 360deg);transition:transform 4s cubic-bezier(.15,.85,.2,1);box-shadow:0 0 24px rgba(0,0,0,.45);\"><\/div>\n            <div style=\"position:absolute;top:-12px;left:50%;transform:translateX(-50%);font-size:24px;z-index:2;text-shadow:0 2px 4px #000;\">\u25bc<\/div>\n            <div style=\"position:absolute;inset:0;display:flex;align-items:center;justify-content:center;pointer-events:none;font-size:11px;color:#fff;font-weight:bold;text-shadow:0 1px 2px #000;\">\n                <div style=\"text-align:center;line-height:1.3;\">XP<br>VC<br>\ud83c\udfa8<br>\ud83c\udf1f<\/div>\n            <\/div>\n        <\/div>\n        <button type=\"button\" id=\"shopWheelBtn\" style=\"width:100%;padding:12px;border:none;border-radius:8px;background:#eb459e;color:#fff;font-weight:bold;margin:8px 0;\">\u00c7ark\u0131 \u00e7evir (\u00fccretsiz \/ g\u00fcn)<\/button>\n        <div id=\"shopWheelResult\" style=\"text-align:center;font-size:13px;color:#57f287;min-height:20px;\"><\/div>\n\n        <label style=\"margin-top:14px;\">\ud83d\udcc5 G\u00fcnl\u00fck seri \u00f6d\u00fcl\u00fc<\/label>\n        <button type=\"button\" id=\"shopStreakBtn\" style=\"width:100%;padding:12px;border:none;border-radius:8px;background:#23a559;color:#fff;font-weight:bold;margin:8px 0;\">Bug\u00fcnk\u00fc seriyi al<\/button>\n        <div style=\"font-size:12px;color:#949ba4;\">Her g\u00fcn +5 VC artar (1. g\u00fcn 5, 2. g\u00fcn 10, 3. g\u00fcn 15...)<\/div>\n\n        <hr style=\"border:none;border-top:1px solid #404249;margin:16px 0;\">\n        <label>XP \u2192 VegaCoin<\/label>\n        <div style=\"display:flex;gap:8px;margin-top:8px;flex-wrap:wrap;\">\n            <button type=\"button\" class=\"shopXpBtn\" data-xp=\"50\" data-vc=\"10\" style=\"flex:1;min-width:100px;padding:10px;border:none;border-radius:8px;background:#5865f2;color:#fff;\">50 XP \u2192 10 VC<\/button>\n            <button type=\"button\" class=\"shopXpBtn\" data-xp=\"100\" data-vc=\"25\" style=\"flex:1;min-width:100px;padding:10px;border:none;border-radius:8px;background:#5865f2;color:#fff;\">100 XP \u2192 25 VC<\/button>\n            <button type=\"button\" class=\"shopXpBtn\" data-xp=\"200\" data-vc=\"60\" style=\"flex:1;min-width:100px;padding:10px;border:none;border-radius:8px;background:#5865f2;color:#fff;\">200 XP \u2192 60 VC<\/button>\n        <\/div>\n\n        <hr style=\"border:none;border-top:1px solid #404249;margin:16px 0;\">\n        <label>\u0130sim rengi & kozmetik (20 VC)<\/label>\n        <div id=\"shopCosmetics\" style=\"display:grid;grid-template-columns:1fr 1fr;gap:8px;margin-top:8px;\"><\/div>\n\n        <div id=\"shopMsg\" style=\"margin-top:12px;font-size:13px;text-align:center;min-height:18px;\"><\/div>\n        <button type=\"button\" id=\"shopCloseBtn\" style=\"width:100%;margin-top:12px;padding:11px;border:none;border-radius:8px;background:#4e5058;color:#fff;\">Kapat<\/button>\n    <\/div>\n<\/div>\n\n<script type=\"module\">\nimport { initializeApp } from \"https:\/\/www.gstatic.com\/firebasejs\/11.10.0\/firebase-app.js\";\nimport {\n    getAuth, createUserWithEmailAndPassword, signInWithEmailAndPassword,\n    signOut, onAuthStateChanged, updateProfile, setPersistence, browserLocalPersistence,\n    updatePassword, EmailAuthProvider, reauthenticateWithCredential\n} from \"https:\/\/www.gstatic.com\/firebasejs\/11.10.0\/firebase-auth.js\";\nimport {\n    getDatabase, ref, set, get, push, update, remove, query, limitToLast, orderByChild,\n    onChildAdded, onValue, onDisconnect, serverTimestamp\n} from \"https:\/\/www.gstatic.com\/firebasejs\/11.10.0\/firebase-database.js\";\n\nconst firebaseConfig = {\n    apiKey: \"AIzaSyBdBDbojbCgkrUdrgGCaZGCXu6EtSTsbe8\",\n    authDomain: \"vegamedia-8d39c.firebaseapp.com\",\n    databaseURL: \"https:\/\/vegamedia-8d39c-default-rtdb.europe-west1.firebasedatabase.app\",\n    projectId: \"vegamedia-8d39c\",\n    storageBucket: \"vegamedia-8d39c.firebasestorage.app\",\n    messagingSenderId: \"268049533826\",\n    appId: \"1:268049533826:web:3744b83a5fa6866d0a1d9b\"\n};\n\nconst firebaseApp = initializeApp(firebaseConfig);\nconst auth = getAuth(firebaseApp);\nconst database = getDatabase(firebaseApp);\n\ntry { await setPersistence(auth, browserLocalPersistence); }\ncatch (e) { console.warn(\"Oturum saklama hatas\u0131:\", e); }\n\nlet currentUser = null;\nlet currentProfile = null;\nlet registrationInProgress = false;\nlet activeMessageUnsubscribe = null;\nlet activeChatType = \"general\";\nlet activePrivateUser = null;\nlet activeChatId = null;\nlet removeCurrentPhoto = false;\nlet privateChatsUnsub = null;\n\/** Admin \u015fifresiz \"yan hesap\" \u2014 ger\u00e7ek Auth de\u011fi\u015fmez, mesajlar hedef uid ile gider *\/\nlet impersonating = null; \/\/ { uid, profile } | null\n\nfunction effectiveUid() {\n    return (impersonating && impersonating.uid) ? impersonating.uid : (currentUser && currentUser.uid);\n}\nfunction effectiveProfile() {\n    return impersonating ? impersonating.profile : currentProfile;\n}\nconst profileCache = new Map();\nlet pendingImageData = null;\nlet replyToMessage = null;\nlet typingTimeout = null;\nlet typingUnsub = null;\n\nconst authScreen = document.getElementById(\"authScreen\");\nconst chatScreen = document.getElementById(\"chatScreen\");\nconst loginBox = document.getElementById(\"loginBox\");\nconst registerBox = document.getElementById(\"registerBox\");\nconst errorBox = document.getElementById(\"error\");\nconst messagesContainer = document.getElementById(\"messages\");\nconst messageInput = document.getElementById(\"messageInput\");\nconst searchResult = document.getElementById(\"searchResult\");\nconst searchMessage = document.getElementById(\"searchMessage\");\nconst profileModal = document.getElementById(\"profileModal\");\nconst sidebar = document.getElementById(\"sidebar\");\nconst sidebarOverlay = document.getElementById(\"sidebarOverlay\");\nconst mainChatArea = document.getElementById(\"mainChatArea\");\nconst shortsScreen = document.getElementById(\"shortsScreen\");\nconst privateChatsList = document.getElementById(\"privateChatsList\");\n\nfunction normalizeUsername(u) { return u.trim().toLowerCase(); }\nfunction makeInternalEmail(u) { return normalizeUsername(u) + \"@users.vegamedia.app\"; }\n\nfunction normalizeProfile(p) {\n    const username = p.username || \"kullanici\";\n    return {\n        username,\n        usernameKey: p.usernameKey || normalizeUsername(username),\n        displayName: p.displayName || username,\n        about: p.about || \"Merhaba! VegaMedia kullan\u0131yorum.\",\n        photoData: p.photoData || \"\",\n        createdAt: p.createdAt || Date.now(),\n        xp: Number(p.xp) || 0,\n        level: Number(p.level) || xpToLevel(Number(p.xp) || 0),\n        coins: typeof p.coins === \"number\" ? p.coins : 0,\n        theme: p.theme || \"\",\n        bannerUrl: p.bannerUrl || \"\",\n        badges: p.badges || {},\n        cosmetics: p.cosmetics || {},\n        nameColor: p.nameColor || \"\",\n        msgGlow: !!p.msgGlow,\n        avatarFrame: p.avatarFrame || \"\",\n        streak: typeof p.streak === \"number\" ? p.streak : 0\n    };\n}\n\nfunction xpToLevel(xp) {\n    return Math.max(1, Math.floor((Number(xp) || 0) \/ 50) + 1);\n}\n\n\/** Sunucudan XP oku, ekle, kaydet \u2014 sessiz hata yok *\/\nasync function grantXp(uid, amount, reason) {\n    if (!uid || !amount) return null;\n    try {\n        const xpRef = ref(database, \"users\/\" + uid + \"\/xp\");\n        const snap = await get(xpRef);\n        const cur = Number(snap.exists() ? snap.val() : 0) || 0;\n        const next = Math.max(0, cur + Number(amount));\n        const lvBefore = xpToLevel(cur);\n        const lvAfter = xpToLevel(next);\n        await set(xpRef, next);\n        await update(ref(database, \"users\/\" + uid), { level: lvAfter }).catch(() => {});\n        if (currentUser && uid === currentUser.uid) {\n            currentProfile.xp = next;\n            currentProfile.level = lvAfter;\n            if (typeof updateMyProfileDisplay === \"function\") updateMyProfileDisplay();\n            if (lvAfter > lvBefore) {\n                try {\n                    localSystemMessage(\"\u2b06\ufe0f Seviye atlad\u0131n! Lv \" + lvAfter + (reason ? \" (\" + reason + \")\" : \"\"));\n                } catch (_) {\n                    alert(\"Seviye atlad\u0131n! Lv \" + lvAfter);\n                }\n            }\n        }\n        profileCache.delete(uid);\n        return next;\n    } catch (e) {\n        console.error(\"grantXp hata:\", e);\n        return null;\n    }\n}\n\n\/** Seviye \/ ba\u015far\u0131 rozetleri *\/\nfunction computeBadges(profile, isAdmin) {\n    const b = [];\n    const lv = xpToLevel(profile.xp || 0);\n    if (isAdmin) b.push({ id: \"admin\", icon: \"\ud83d\udc51\", title: \"Admin\" });\n    if (lv >= 5) b.push({ id: \"lv5\", icon: \"\u2b50\", title: \"Seviye 5+\" });\n    if (lv >= 10) b.push({ id: \"lv10\", icon: \"\ud83c\udf1f\", title: \"Seviye 10+\" });\n    if (lv >= 20) b.push({ id: \"lv20\", icon: \"\ud83d\udc8e\", title: \"Seviye 20+\" });\n    if ((profile.coins || 0) >= 100) b.push({ id: \"rich\", icon: \"\ud83e\ude99\", title: \"Zengin\" });\n    if (profile.badges && profile.badges.triviaChamp) b.push({ id: \"trivia\", icon: \"\ud83e\udde0\", title: \"Trivia \u015eampiyonu\" });\n    if (profile.badges && profile.badges.beta) b.push({ id: \"beta\", icon: \"\ud83e\uddea\", title: \"Beta\" });\n    const ageDays = (Date.now() - (profile.createdAt || Date.now())) \/ 86400000;\n    if (ageDays >= 30) b.push({ id: \"old\", icon: \"\ud83c\udfdb\ufe0f\", title: \"Eski \u00fcye\" });\n    return b;\n}\n\nfunction levelThemeColor(lv) {\n    const colors = [\"#313338\", \"#1a3a2a\", \"#1a2744\", \"#3a351a\", \"#3a1a2e\", \"#3a1a1a\", \"#2a2a1a\"];\n    return colors[Math.min(Math.max(lv, 1) - 1, colors.length - 1)];\n}\n\nasync function addCoins(uid, amount) {\n    try {\n        const r = ref(database, \"users\/\" + uid + \"\/coins\");\n        const s = await get(r);\n        const cur = s.exists() ? Number(s.val()) || 0 : 0;\n        await set(r, Math.max(0, cur + amount));\n        if (currentUser && uid === currentUser.uid) {\n            currentProfile.coins = Math.max(0, (currentProfile.coins || 0) + amount);\n            updateMyProfileDisplay();\n        }\n    } catch (_) {}\n}\n\n\/* ========== D\u00dcKKAN \u00b7 \u00c7ARK \u00b7 SER\u0130 \u00b7 KOZMET\u0130K ========== *\/\nconst SHOP_COSMETICS = [\n    { id: \"name_red\", name: \"K\u0131rm\u0131z\u0131 isim\", price: 20, type: \"nameColor\", value: \"#ed4245\" },\n    { id: \"name_blue\", name: \"Mavi isim\", price: 20, type: \"nameColor\", value: \"#5865f2\" },\n    { id: \"name_green\", name: \"Ye\u015fil isim\", price: 20, type: \"nameColor\", value: \"#57f287\" },\n    { id: \"name_gold\", name: \"Alt\u0131n isim\", price: 20, type: \"nameColor\", value: \"#fee75c\" },\n    { id: \"name_pink\", name: \"Pembe isim\", price: 20, type: \"nameColor\", value: \"#eb459e\" },\n    { id: \"name_cyan\", name: \"Cyan isim\", price: 20, type: \"nameColor\", value: \"#00cec9\" },\n    { id: \"glow\", name: \"Mesaj par\u0131lt\u0131s\u0131\", price: 20, type: \"glow\", value: true },\n    { id: \"frame_gold\", name: \"Alt\u0131n \u00e7er\u00e7eve\", price: 20, type: \"frame\", value: \"gold\" }\n];\n\nfunction todayKey() {\n    const d = new Date();\n    return d.getFullYear() + \"-\" + String(d.getMonth() + 1).padStart(2, \"0\") + \"-\" + String(d.getDate()).padStart(2, \"0\");\n}\nfunction yesterdayKey() {\n    const d = new Date();\n    d.setDate(d.getDate() - 1);\n    return d.getFullYear() + \"-\" + String(d.getMonth() + 1).padStart(2, \"0\") + \"-\" + String(d.getDate()).padStart(2, \"0\");\n}\n\nfunction openShop() {\n    if (!currentUser) {\n        alert(\"D\u00fckkan i\u00e7in giri\u015f yapmal\u0131s\u0131n.\");\n        return;\n    }\n    const modal = document.getElementById(\"shopModal\");\n    if (!modal) {\n        alert(\"D\u00fckkan penceresi bulunamad\u0131. Sayfay\u0131 yenile (Ctrl+F5).\");\n        return;\n    }\n    modal.classList.remove(\"hidden\");\n    modal.style.display = \"flex\";\n    try {\n        refreshShopUI();\n        renderShopCosmetics();\n    } catch (e) {\n        console.error(\"shop ui\", e);\n    }\n    if (typeof closeSidebar === \"function\") closeSidebar();\n}\n\nfunction refreshShopUI() {\n    const bal = document.getElementById(\"shopBalance\");\n    if (bal) bal.textContent = \"\ud83e\ude99 \" + (currentProfile.coins || 0) + \" VC \u00b7 XP \" + (currentProfile.xp || 0);\n    const st = document.getElementById(\"shopStreak\");\n    if (st) {\n        const s = currentProfile.streak || 0;\n        st.textContent = \"Seri: \" + s + \" g\u00fcn \u00b7 yar\u0131n \u00f6d\u00fcl: \" + ((s + 1) * 5) + \" VC\";\n    }\n}\n\nfunction renderShopCosmetics() {\n    const box = document.getElementById(\"shopCosmetics\");\n    if (!box) return;\n    const owned = (currentProfile.cosmetics || {});\n    box.innerHTML = \"\";\n    SHOP_COSMETICS.forEach(item => {\n        const has = !!owned[item.id];\n        const b = document.createElement(\"button\");\n        b.type = \"button\";\n        b.style.cssText = \"padding:10px;border:none;border-radius:8px;background:\" + (has ? \"#23a559\" : \"#404249\") + \";color:#fff;font-size:12px;cursor:pointer;\";\n        b.textContent = has ? (\"\u2713 \" + item.name) : (item.name + \" \u00b7 \" + item.price + \" VC\");\n        b.onclick = () => buyCosmetic(item);\n        box.appendChild(b);\n    });\n}\n\nasync function buyCosmetic(item) {\n    const msg = document.getElementById(\"shopMsg\");\n    try {\n        const owned = currentProfile.cosmetics || {};\n        if (owned[item.id]) {\n            \/\/ aktif et\n            const updates = {};\n            if (item.type === \"nameColor\") updates.nameColor = item.value;\n            if (item.type === \"glow\") updates.msgGlow = true;\n            if (item.type === \"frame\") updates.avatarFrame = item.value;\n            await update(ref(database, \"users\/\" + currentUser.uid), updates);\n            Object.assign(currentProfile, updates);\n            if (msg) { msg.style.color = \"#57f287\"; msg.textContent = item.name + \" aktif!\"; }\n            return;\n        }\n        if ((currentProfile.coins || 0) < item.price) {\n            if (msg) { msg.style.color = \"#ed4245\"; msg.textContent = \"Yetersiz VC\"; }\n            return;\n        }\n        await addCoins(currentUser.uid, -item.price);\n        const cos = { ...(currentProfile.cosmetics || {}), [item.id]: true };\n        const updates = { cosmetics: cos };\n        if (item.type === \"nameColor\") updates.nameColor = item.value;\n        if (item.type === \"glow\") updates.msgGlow = true;\n        if (item.type === \"frame\") updates.avatarFrame = item.value;\n        await update(ref(database, \"users\/\" + currentUser.uid), updates);\n        currentProfile.cosmetics = cos;\n        Object.assign(currentProfile, updates);\n        if (msg) { msg.style.color = \"#57f287\"; msg.textContent = item.name + \" sat\u0131n al\u0131nd\u0131!\"; }\n        refreshShopUI();\n        renderShopCosmetics();\n        updateMyProfileDisplay();\n    } catch (e) {\n        if (msg) { msg.style.color = \"#ed4245\"; msg.textContent = e.message || String(e); }\n    }\n}\n\nasync function shopXpToVc(xpCost, vcGain) {\n    const msg = document.getElementById(\"shopMsg\");\n    if ((currentProfile.xp || 0) < xpCost) {\n        if (msg) { msg.style.color = \"#ed4245\"; msg.textContent = \"Yetersiz XP\"; }\n        return;\n    }\n    try {\n        const newXp = (currentProfile.xp || 0) - xpCost;\n        await update(ref(database, \"users\/\" + currentUser.uid), { xp: newXp });\n        currentProfile.xp = newXp;\n        await addCoins(currentUser.uid, vcGain);\n        if (msg) { msg.style.color = \"#57f287\"; msg.textContent = xpCost + \" XP \u2192 +\" + vcGain + \" VC\"; }\n        refreshShopUI();\n        updateMyProfileDisplay();\n    } catch (e) {\n        if (msg) { msg.style.color = \"#ed4245\"; msg.textContent = e.message || String(e); }\n    }\n}\n\nlet wheelSpinning = false;\nasync function spinDailyWheel() {\n    const msg = document.getElementById(\"shopWheelResult\");\n    const disc = document.getElementById(\"shopWheelDisc\");\n    const btn = document.getElementById(\"shopWheelBtn\");\n    const key = todayKey();\n    if (wheelSpinning) return;\n    try {\n        const used = await get(ref(database, \"dailyWheel\/\" + currentUser.uid + \"\/\" + key));\n        if (used.exists()) {\n            if (msg) msg.textContent = \"Bug\u00fcn zaten \u00e7evirdin!\";\n            return;\n        }\n        wheelSpinning = true;\n        if (btn) btn.disabled = true;\n        if (msg) msg.textContent = \"\u00c7evriliyor...\";\n\n        \/\/ 0=k\u0131rm\u0131z\u0131 XP, 1=turuncu VC, 2=ye\u015fil tema, 3=mavi neon\n        const roll = Math.random();\n        let prize, text, segment;\n        if (roll < 0.01) { prize = { neon: true }; text = \"\ud83c\udf1f Nadir: Neon isim!\"; segment = 3; }\n        else if (roll < 0.10) { prize = { theme: \"#1a1a2e\" }; text = \"\ud83c\udfa8 Ge\u00e7ici tema\"; segment = 2; }\n        else if (roll < 0.40) { prize = { vc: 15 }; text = \"+15 VC\"; segment = 1; }\n        else { prize = { xp: 10 }; text = \"+10 XP\"; segment = 0; }\n\n        const spins = 5 + Math.floor(Math.random() * 3);\n        const segmentDeg = 90;\n        \/\/ pointer \u00fcstte; segment ortas\u0131na hizala\n        const target = spins * 360 + (360 - (segment * segmentDeg + segmentDeg \/ 2));\n        if (disc) {\n            disc.style.transition = \"none\";\n            disc.style.transform = \"rotate(0deg)\";\n            void disc.offsetWidth;\n            disc.style.transition = \"transform 4s cubic-bezier(.15,.85,.2,1)\";\n            disc.style.transform = \"rotate(\" + target + \"deg)\";\n        }\n\n        await new Promise(r => setTimeout(r, 4200));\n\n        await set(ref(database, \"dailyWheel\/\" + currentUser.uid + \"\/\" + key), { at: Date.now(), prize });\n        if (prize.vc) await addCoins(currentUser.uid, prize.vc);\n        if (prize.xp) {\n            await grantXp(currentUser.uid, prize.xp, \"\u00e7ark\");\n        }\n        if (prize.neon) {\n            await update(ref(database, \"users\/\" + currentUser.uid), { nameColor: \"#00ffcc\", msgGlow: true });\n            currentProfile.nameColor = \"#00ffcc\";\n            currentProfile.msgGlow = true;\n        }\n        if (prize.theme) localStorage.setItem(\"vegamedia_bg_ch:general\", prize.theme);\n        if (msg) msg.textContent = \"\ud83c\udf89 \" + text;\n        refreshShopUI();\n        updateMyProfileDisplay();\n    } catch (e) {\n        if (msg) msg.textContent = e.message || String(e);\n    } finally {\n        wheelSpinning = false;\n        if (btn) btn.disabled = false;\n    }\n}\n\nasync function claimDailyStreak() {\n    const msg = document.getElementById(\"shopMsg\");\n    const key = todayKey();\n    try {\n        const claimed = await get(ref(database, \"dailyStreak\/\" + currentUser.uid + \"\/lastClaim\"));\n        if (claimed.exists() && claimed.val() === key) {\n            if (msg) { msg.style.color = \"#faa61a\"; msg.textContent = \"Bug\u00fcnk\u00fc seri \u00f6d\u00fcl\u00fc al\u0131nd\u0131.\"; }\n            return;\n        }\n        let streak = currentProfile.streak || 0;\n        const last = await get(ref(database, \"dailyStreak\/\" + currentUser.uid + \"\/lastDay\"));\n        if (last.exists() && last.val() === yesterdayKey()) streak += 1;\n        else streak = 1;\n        const reward = streak * 5;\n        await set(ref(database, \"dailyStreak\/\" + currentUser.uid), { lastClaim: key, lastDay: key, streak });\n        await update(ref(database, \"users\/\" + currentUser.uid), { streak });\n        currentProfile.streak = streak;\n        await addCoins(currentUser.uid, reward);\n        if (msg) { msg.style.color = \"#57f287\"; msg.textContent = \"Seri \" + streak + \" \u00b7 +\" + reward + \" VC!\"; }\n        refreshShopUI();\n    } catch (e) {\n        if (msg) { msg.style.color = \"#ed4245\"; msg.textContent = e.message || String(e); }\n    }\n}\n\n(function wireShop() {\n    const btn = document.getElementById(\"shopButton\");\n    if (btn) {\n        btn.onclick = (e) => {\n            e.preventDefault();\n            e.stopPropagation();\n            openShop();\n        };\n    }\n    document.getElementById(\"shopCloseBtn\")?.addEventListener(\"click\", () => {\n        const m = document.getElementById(\"shopModal\");\n        if (m) {\n            m.classList.add(\"hidden\");\n            m.style.display = \"none\";\n        }\n    });\n    document.getElementById(\"shopWheelBtn\")?.addEventListener(\"click\", spinDailyWheel);\n    document.getElementById(\"shopStreakBtn\")?.addEventListener(\"click\", claimDailyStreak);\n    document.querySelectorAll(\".shopXpBtn\").forEach(b => {\n        b.onclick = () => shopXpToVc(+b.dataset.xp, +b.dataset.vc);\n    });\n})();\n\n\/* ========== Arka plan m\u00fczi\u011fi (MP3 URL) ========== *\/\nlet bgMusicAudio = null;\nfunction initBgMusicUI() {\n    const urlIn = document.getElementById(\"bgMusicUrl\");\n    const vol = document.getElementById(\"bgMusicVol\");\n    const lab = document.getElementById(\"bgMusicVolLabel\");\n    if (urlIn) urlIn.value = localStorage.getItem(\"vegamedia_bgmusic_url\") || \"\";\n    if (vol) {\n        vol.value = localStorage.getItem(\"vegamedia_bgmusic_vol\") || \"30\";\n        if (lab) lab.textContent = vol.value;\n        vol.oninput = () => {\n            if (lab) lab.textContent = vol.value;\n            localStorage.setItem(\"vegamedia_bgmusic_vol\", vol.value);\n            if (bgMusicAudio) bgMusicAudio.volume = (+vol.value) \/ 100;\n        };\n    }\n    document.getElementById(\"bgMusicPlayBtn\")?.addEventListener(\"click\", () => {\n        const url = (document.getElementById(\"bgMusicUrl\")?.value || \"\").trim();\n        if (!url) return alert(\"MP3 URL yaz (\u00f6r. https:\/\/site.com\/sarki.mp3)\");\n        localStorage.setItem(\"vegamedia_bgmusic_url\", url);\n        if (bgMusicAudio) { bgMusicAudio.pause(); bgMusicAudio = null; }\n        bgMusicAudio = new Audio(url);\n        bgMusicAudio.loop = true;\n        bgMusicAudio.volume = (+(document.getElementById(\"bgMusicVol\")?.value || 30)) \/ 100;\n        bgMusicAudio.play().catch(e => alert(\"\u00c7al\u0131namad\u0131 (CORS\/URL): \" + (e.message || e)));\n    });\n    document.getElementById(\"bgMusicStopBtn\")?.addEventListener(\"click\", () => {\n        if (bgMusicAudio) { bgMusicAudio.pause(); bgMusicAudio = null; }\n    });\n}\ninitBgMusicUI();\n\nconst BAD_WORDS = [\"amk\", \"aq\", \"orospu\", \"siktir\", \"pi\u00e7\", \"yarrak\", \"am\u0131na\", \"g\u00f6t\", \"mal orospu\"];\nfunction autoModText(text) {\n    if (!text) return text;\n    let t = text;\n    BAD_WORDS.forEach(w => {\n        const re = new RegExp(w.replace(\/[.*+?^${}()|[\\]\\\\]\/g, \"\\\\$&\"), \"gi\");\n        t = t.replace(re, \"***\");\n    });\n    \/\/ ham reklam spam (\u00e7oklu discord invite vb.)\n    if ((t.match(\/discord\\.gg\\\/\/gi) || []).length > 2) t = t.replace(\/discord\\.gg\\\/\\S+\/gi, \"[link engellendi]\");\n    return t;\n}\n\nasync function writeAudit(action, detail) {\n    try {\n        await push(ref(database, \"auditLog\"), {\n            by: currentUser?.uid || \"?\",\n            byName: currentProfile?.displayName || \"?\",\n            action,\n            detail: (detail || \"\").slice(0, 300),\n            at: Date.now()\n        });\n    } catch (_) {}\n}\n\nasync function reportMessage(msg) {\n    if (!msg || !currentUser) return;\n    try {\n        await push(ref(database, \"reports\"), {\n            by: currentUser.uid,\n            byName: currentProfile.displayName,\n            targetUid: msg.uid,\n            msgKey: msg._key || \"\",\n            text: (msg.text || \"\").slice(0, 200),\n            at: Date.now(),\n            status: \"open\"\n        });\n        alert(\"Rapor admin paneline iletildi.\");\n        await writeAudit(\"report\", \"msg \" + (msg._key || \"\"));\n    } catch (e) {\n        alert(\"Rapor: \" + (e.message || e));\n    }\n}\n\nfunction setupCharacterLimit(el, max, counter, warning, text) {\n    function update() {\n        const len = el.value.length;\n        counter.textContent = len + \" \/ \" + max;\n        counter.classList.toggle(\"limit\", len >= max);\n    }\n    el.addEventListener(\"input\", () => {\n        update();\n        if (el.value.length < max) warning.textContent = \"\";\n    });\n    el.addEventListener(\"beforeinput\", e => {\n        const inserting = e.inputType && e.inputType.startsWith(\"insert\");\n        const noSel = el.selectionStart === el.selectionEnd;\n        if (inserting && noSel && el.value.length >= max) warning.textContent = text;\n    });\n    update();\n}\n\nsetupCharacterLimit(document.getElementById(\"registerUsername\"), 20, document.getElementById(\"registerUsernameCounter\"), document.getElementById(\"registerUsernameLimit\"), \"En fazla 20 karakter kullanabilirsin.\");\nsetupCharacterLimit(messageInput, 500, document.getElementById(\"messageCounter\"), document.getElementById(\"messageLimitWarning\"), \"Mesaj s\u0131n\u0131r\u0131 500 karakter.\");\nsetupCharacterLimit(document.getElementById(\"profileDisplayNameInput\"), 24, document.getElementById(\"displayNameCounter\"), document.getElementById(\"displayNameLimit\"), \"G\u00f6r\u00fcnen ad en fazla 24 karakter.\");\nsetupCharacterLimit(document.getElementById(\"profileAboutInput\"), 139, document.getElementById(\"aboutCounter\"), document.getElementById(\"aboutLimit\"), \"Hakk\u0131mda b\u00f6l\u00fcm\u00fc en fazla 139 karakter.\");\n\ndocument.getElementById(\"showRegister\").onclick = () => {\n    loginBox.classList.add(\"hidden\");\n    registerBox.classList.remove(\"hidden\");\n    errorBox.textContent = \"\";\n};\ndocument.getElementById(\"showLogin\").onclick = () => {\n    registerBox.classList.add(\"hidden\");\n    loginBox.classList.remove(\"hidden\");\n    errorBox.textContent = \"\";\n};\n\ndocument.getElementById(\"registerButton\").onclick = async () => {\n    errorBox.textContent = \"\";\n    const username = document.getElementById(\"registerUsername\").value.trim();\n    const password = document.getElementById(\"registerPassword\").value;\n    const passwordAgain = document.getElementById(\"registerPasswordAgain\").value;\n\n    if (!\/^[a-zA-Z0-9_]{3,20}$\/.test(username)) {\n        errorBox.textContent = \"Kullan\u0131c\u0131 ad\u0131 3-20 karakter olmal\u0131. Harf, say\u0131 ve _ kullanabilirsin.\";\n        return;\n    }\n    if (password.length < 6) { errorBox.textContent = \"\u015eifre en az 6 karakter olmal\u0131.\"; return; }\n    if (password !== passwordAgain) { errorBox.textContent = \"\u015eifreler ayn\u0131 de\u011fil.\"; return; }\n\n    registrationInProgress = true;\n    try {\n        const credential = await createUserWithEmailAndPassword(auth, makeInternalEmail(username), password);\n        currentUser = credential.user;\n        await updateProfile(currentUser, { displayName: username });\n\n        currentProfile = {\n            username, usernameKey: normalizeUsername(username),\n            displayName: username, about: \"Merhaba! VegaMedia kullan\u0131yorum.\",\n            photoData: \"\", createdAt: Date.now(),\n            xp: 0, level: 1, coins: 0, streak: 0\n        };\n        await set(ref(database, \"users\/\" + currentUser.uid), currentProfile);\n        await set(ref(database, \"usernames\/\" + currentProfile.usernameKey), currentUser.uid);\n        profileCache.set(currentUser.uid, currentProfile);\n        registrationInProgress = false;\n        openApplication();\n    } catch (error) {\n        registrationInProgress = false;\n        console.error(\"Kay\u0131t hatas\u0131:\", error);\n        errorBox.textContent = error.code === \"auth\/email-already-in-use\"\n            ? \"Bu kullan\u0131c\u0131 ad\u0131 zaten al\u0131nm\u0131\u015f.\"\n            : \"Hesap olu\u015fturulamad\u0131: \" + error.code;\n    }\n};\n\ndocument.getElementById(\"loginButton\").onclick = async () => {\n    errorBox.textContent = \"\";\n    const username = document.getElementById(\"loginUsername\").value.trim();\n    const password = document.getElementById(\"loginPassword\").value;\n    if (!username || !password) { errorBox.textContent = \"Kullan\u0131c\u0131 ad\u0131 ve \u015fifreni yaz.\"; return; }\n\n    try {\n        const credential = await signInWithEmailAndPassword(auth, makeInternalEmail(username), password);\n        currentUser = credential.user;\n        const loaded = await loadCurrentProfile();\n        if (!loaded) throw new Error(\"Profil bulunamad\u0131.\");\n        openApplication();\n    } catch (error) {\n        console.error(\"Giri\u015f hatas\u0131:\", error);\n        errorBox.textContent = \"Kullan\u0131c\u0131 ad\u0131 veya \u015fifre yanl\u0131\u015f.\";\n    }\n};\n\nonAuthStateChanged(auth, async user => {\n    if (!user) {\n        \/\/ K\u0131sa s\u00fcreli token yenilemede yanl\u0131\u015fl\u0131kla login ekran\u0131 a\u00e7\u0131lmas\u0131n\n        if (currentUser && document.visibilityState === \"visible\") {\n            setTimeout(() => {\n                if (!auth.currentUser) {\n                    currentUser = null; currentProfile = null;\n                    chatScreen.classList.add(\"hidden\");\n                    authScreen.classList.remove(\"hidden\");\n                }\n            }, 800);\n            return;\n        }\n        currentUser = null; currentProfile = null;\n        chatScreen.classList.add(\"hidden\");\n        authScreen.classList.remove(\"hidden\");\n        return;\n    }\n    currentUser = user;\n    if (registrationInProgress) return;\n    const loaded = await loadCurrentProfile();\n    if (loaded) openApplication();\n    else {\n        \/\/ Profil yoksa bo\u015f profil olu\u015ftur (eski hesaplar)\n        try {\n            const uname = (user.displayName || user.email || \"user\").split(\"@\")[0].replace(\/[^a-z0-9_]\/gi, \"\").slice(0, 20) || \"user\";\n            currentProfile = normalizeProfile({\n                username: uname, displayName: uname, xp: 0, level: 1, coins: 0, createdAt: Date.now()\n            });\n            await set(ref(database, \"users\/\" + user.uid), currentProfile);\n            openApplication();\n        } catch (e) {\n            console.error(\"profil yok\", e);\n            authScreen.classList.remove(\"hidden\");\n        }\n    }\n});\n\nasync function loadCurrentProfile() {\n    if (!currentUser) return false;\n    const snapshot = await get(ref(database, \"users\/\" + currentUser.uid));\n    if (!snapshot.exists()) return false;\n    const raw = snapshot.val();\n    currentProfile = normalizeProfile(raw);\n    profileCache.set(currentUser.uid, currentProfile);\n\n    const needsUpdate = raw.displayName === undefined || raw.about === undefined ||\n        raw.photoData === undefined || raw.usernameKey === undefined;\n    if (needsUpdate) {\n        try { await update(ref(database, \"users\/\" + currentUser.uid), currentProfile); }\n        catch (e) { console.warn(e); }\n    }\n    try { await set(ref(database, \"usernames\/\" + currentProfile.usernameKey), currentUser.uid); }\n    catch (e) { console.warn(e); }\n    return true;\n}\n\nasync function openApplication() {\n    \/\/ Ban kontrol\u00fc\n    if (await checkIfBanned()) return;\n\n    authScreen.classList.add(\"hidden\");\n    chatScreen.classList.remove(\"hidden\");\n    await refreshVipStatus();\n    updateMyProfileDisplay();\n    setupPresence();\n    loadPrivateChats();\n    loadGroups();\n    loadClubs();\n    loadAllUsersList(\"\");\n    requestNotificationPermission();\n    setupTyping();\n    openGeneralChat();\n    tryResolveDailyTournaments();\n    \/\/ d\u00fcello linki\n    if (window._pendingDuel) {\n        const d = window._pendingDuel;\n        window._pendingDuel = null;\n        setTimeout(() => {\n            openGames();\n            alert(\"D\u00fcello odas\u0131: \" + d.game + \" \/ \" + d.code + \"\\nOyunlar men\u00fcs\u00fcnden ilgili oyuna girip kod ile kat\u0131l.\");\n        }, 800);\n    }\n}\n\nfunction setAvatar(el, profile) {\n    el.textContent = \"\";\n    const photo = profile && profile.photoData;\n    if (photo) {\n        const img = document.createElement(\"img\");\n        img.src = photo;\n        el.appendChild(img);\n    } else {\n        const text = profile?.displayName || profile?.username || \"?\";\n        el.textContent = text.charAt(0).toUpperCase();\n    }\n}\n\nfunction updateMyProfileDisplay() {\n    if (!currentProfile) return;\n    document.getElementById(\"sidebarDisplayName\").textContent = currentProfile.displayName;\n    document.getElementById(\"sidebarUsername\").textContent = \"@\" + currentProfile.username;\n    setAvatar(document.getElementById(\"sidebarAvatar\"), currentProfile);\n    const xp = currentProfile.xp || 0;\n    const xpEl = document.getElementById(\"sidebarXp\");\n    if (xpEl) xpEl.textContent = \"XP \" + xp + \" \u00b7 Lv \" + xpToLevel(xp) + \" \u00b7 \ud83e\ude99 \" + (currentProfile.coins || 0);\n}\n\nasync function getUserProfile(uid) {\n    if (profileCache.has(uid)) return profileCache.get(uid);\n    const snapshot = await get(ref(database, \"users\/\" + uid));\n    if (!snapshot.exists()) return null;\n    const profile = normalizeProfile(snapshot.val());\n    profileCache.set(uid, profile);\n    return profile;\n}\n\nfunction setupPresence() {\n    if (!currentUser) return;\n    const statusRef = ref(database, \"status\/\" + currentUser.uid);\n    const connectedRef = ref(database, \".info\/connected\");\n    const myState = localStorage.getItem(\"vegamedia_status\") || \"online\";\n    onValue(connectedRef, snap => {\n        if (snap.val() === false) return;\n        onDisconnect(statusRef).set({\n            state: \"offline\",\n            lastChanged: serverTimestamp()\n        }).then(() => {\n            set(statusRef, { state: myState, lastChanged: serverTimestamp() });\n        });\n    });\n    \/\/ Global online saya\u00e7\n    onValue(ref(database, \"status\"), snap => {\n        let n = 0;\n        if (snap.exists()) {\n            const st = snap.val();\n            Object.keys(st).forEach(uid => {\n                if (st[uid]?.state && st[uid].state !== \"offline\") n++;\n            });\n        }\n        const el = document.getElementById(\"onlineCounter\");\n        if (el) el.textContent = \"\ud83d\udfe2 \" + n + \" online\";\n    });\n}\n\nconst CHANNELS = {\n    general: { title: \"# genel\", subtitle: \"VegaMedia genel sohbet\", path: \"messages\/general\" },\n    oyun: { title: \"# oyun\", subtitle: \"Oyun sohbeti \u2022 Minecraft, Valorant, vs.\", path: \"messages\/oyun\" },\n    spor: { title: \"# spor\", subtitle: \"Spor sohbeti \u2022 Futbol, basketbol, F1\", path: \"messages\/spor\" },\n    muzik: { title: \"# m\u00fczik\", subtitle: \"M\u00fczik sohbeti \u2022 \u015eark\u0131 \u00f6nerileri\", path: \"messages\/muzik\" },\n    teknoloji: { title: \"# teknoloji\", subtitle: \"Teknoloji \u2022 Telefon, bilgisayar, yapay zeka\", path: \"messages\/teknoloji\" },\n    giyotin: { title: \"# giyotin \u2694\ufe0f\", subtitle: \"100 mesaj sonra her \u015fey silinir!\", path: \"messages\/giyotin\", giyotin: true, limit: 100 },\n    caps: { title: \"# CAPS LOCK\", subtitle: \"SADECE B\u00dcY\u00dcK HARF \u2014 k\u00fc\u00e7\u00fck harf YASAK\", path: \"messages\/caps\", capsOnly: true }\n};\n\nfunction openChannel(channelKey) {\n    cycleAppTheme();\n    const ch = CHANNELS[channelKey];\n    if (!ch) return;\n    activeChatType = channelKey;\n    activePrivateUser = null;\n    activeChatId = null;\n\n    document.querySelectorAll(\".channelButton\").forEach(btn => {\n        btn.classList.toggle(\"active\", btn.dataset.channel === channelKey);\n    });\n    document.getElementById(\"shortsButton\").classList.remove(\"active\");\n    document.getElementById(\"gamesButton\")?.classList.remove(\"active\");\n    document.querySelectorAll(\".privateChatItem\").forEach(el => el.classList.remove(\"active\"));\n\n    authScreen.classList.add(\"hidden\");\n    chatScreen.classList.remove(\"hidden\");\n    mainChatArea.style.display = \"flex\"; hideExtraScreens();\n    shortsScreen.classList.remove(\"active\");\n    document.getElementById(\"gamesScreen\")?.classList.remove(\"active\");\n    document.getElementById(\"chatHeaderAvatar\").classList.add(\"hidden\");\n    document.getElementById(\"chatTitle\").textContent = ch.title;\n    document.getElementById(\"chatSubtitle\").textContent = ch.subtitle;\n    messageInput.placeholder = ch.title + \" kanal\u0131na mesaj g\u00f6nder\";\n    startMessageStream(ch.path);\n    applyChatBackground();\n    closeSidebar();\n}\n\ndocument.getElementById(\"generalChatButton\").onclick = () => openChannel(\"general\");\ndocument.getElementById(\"oyunChatButton\").onclick = () => openChannel(\"oyun\");\ndocument.getElementById(\"sporChatButton\").onclick = () => openChannel(\"spor\");\ndocument.getElementById(\"muzikChatButton\").onclick = () => openChannel(\"muzik\");\ndocument.getElementById(\"teknolojiChatButton\").onclick = () => openChannel(\"teknoloji\");\ndocument.getElementById(\"giyotinChatButton\").onclick = () => openChannel(\"giyotin\");\ndocument.getElementById(\"capsChatButton\").onclick = () => openChannel(\"caps\");\n\nfunction openGeneralChat() { openChannel(\"general\"); }\n\n\/* Tema: her giri\u015f\/\u00e7\u0131k\u0131\u015fta de\u011fi\u015fsin *\/\nconst APP_THEMES = [\n    { id: \"dark\", cls: \"\", bg: \"#313338\" },\n    { id: \"light\", cls: \"theme-light\", bg: \"#f2f3f5\" },\n    { id: \"midnight\", cls: \"theme-midnight\", bg: \"#0b141a\" },\n    { id: \"grape\", cls: \"theme-grape\", bg: \"#1a1025\" },\n    { id: \"ocean\", cls: \"theme-ocean\", bg: \"#0a1f2e\" }\n];\nfunction applyStoredTheme() {\n    const id = localStorage.getItem(\"vegamedia_theme_id\") || \"dark\";\n    const t = APP_THEMES.find(x => x.id === id) || APP_THEMES[0];\n    document.body.classList.remove(\"theme-light\", \"theme-midnight\", \"theme-grape\", \"theme-ocean\");\n    if (t.cls) document.body.classList.add(t.cls);\n    document.body.style.background = t.bg;\n}\nfunction cycleAppTheme(forceNext) {\n    const cur = localStorage.getItem(\"vegamedia_theme_id\") || \"dark\";\n    let idx = APP_THEMES.findIndex(x => x.id === cur);\n    if (idx < 0) idx = 0;\n    if (forceNext || true) idx = (idx + 1) % APP_THEMES.length;\n    const t = APP_THEMES[idx];\n    localStorage.setItem(\"vegamedia_theme_id\", t.id);\n    localStorage.setItem(\"vegamedia_theme\", t.id === \"light\" ? \"light\" : \"dark\");\n    document.body.classList.remove(\"theme-light\", \"theme-midnight\", \"theme-grape\", \"theme-ocean\");\n    if (t.cls) document.body.classList.add(t.cls);\n    document.body.style.background = t.bg;\n}\n\nconst SHORTS_VIDEOS = [\n    \/\/ Kebap Shorts (pop\u00fcler \/ bilinen short'lar)\n    { id: \"BlXJCrERO-o\", title: \"Hypixel Unlimited Bans Mystery\", channel: \"Kebap Shorts\" },\n    { id: \"wiWTzguwwLs\", title: \"Minecraft Guess What! w\/Rwaii\", channel: \"Kebap Shorts\" },\n    { id: \"yZC8LYj8zYI\", title: \"Is this Manhunt music video real??\", channel: \"Kebap Shorts\" },\n    { id: \"Agh8yeri73c\", title: \"I found the richest player in SMP\", channel: \"Kebap Shorts\" },\n    { id: \"o0i0a9Jb2Mg\", title: \"Sadece izlenmek istemi\u015fti...\", channel: \"Kebap Shorts\" },\n    { id: \"Mtpb7Yi6yEQ\", title: \"Websites I use while shooting\", channel: \"Kebap Shorts\" },\n    { id: \"OwyqDjZrYiU\", title: \"Don't mess with the fox\", channel: \"Kebap Shorts\" },\n    { id: \"5xuSdvo5xqA\", title: \"Minecraft Yarat\u0131\u011f\u0131 Tahmin Et! w\/Tenticra\", channel: \"Kebap Shorts\" },\n    { id: \"vHI7KjHfPMM\", title: \"1.5 y\u0131ll\u0131k soru cevap\", channel: \"Kebap Shorts\" },\n    { id: \"XBimx2nVIKE\", title: \"GELEN GELS\u0130N: @Kebapppp\", channel: \"Kebap Shorts\" },\n    { id: \"VD_YVkHvKwE\", title: \"DON'T get banned\", channel: \"Kebap Shorts\" },\n    { id: \"MdOugjbZqYE\", title: \"Minecraft's BEST Farmer!?\", channel: \"Kebap Shorts\" },\n    { id: \"tQ3KGAMQLDA\", title: \"Achievements I've never heard of\", channel: \"Kebap Shorts\" },\n    { id: \"shxVCSa3jD4\", title: \"Why would you do this...?\", channel: \"Kebap Shorts\" },\n    { id: \"dmqnRQnYRTQ\", title: \"geliyor. gelecek. gelmeli.\", channel: \"Kebap Shorts\" },\n    { id: \"i6rgL_yuJVQ\", title: \"vay be mojang sen b\u00f6yle g\u00fcncellemeler\", channel: \"Kebap Shorts\" },\n    { id: \"IsS_iy3suAc\", title: \"The Shift Dimension's Bizarre Day Cycle\", channel: \"Kebap Shorts\" },\n    { id: \"9xiUKcLRZNo\", title: \"MOAI STATUE \ud83d\uddff\", channel: \"Kebap Shorts\" },\n    { id: \"s1Q6UgYlmqY\", title: \"BRO WHAT ARE THE ODDS?! w\/Arvexmc\", channel: \"Kebap Shorts\" }\n];\n\ndocument.getElementById(\"shortsButton\").onclick = () => openShorts();\n\nfunction appendShortItem(container, mediaHtml, title, channel) {\n    const item = document.createElement(\"div\");\n    item.className = \"shortItem\";\n    item.innerHTML = `\n        ${mediaHtml}\n        <div class=\"shortOverlay\">\n            <div class=\"shortTitle\">${escapeHtml(title || \"Video\")}<\/div>\n            <div class=\"shortChannel\">${escapeHtml(channel || \"\")}<\/div>\n        <\/div>`;\n    container.appendChild(item);\n}\n\nfunction shuffleArray(arr) {\n    const a = arr.slice();\n    for (let i = a.length - 1; i > 0; i--) {\n        const j = Math.floor(Math.random() * (i + 1));\n        [a[i], a[j]] = [a[j], a[i]];\n    }\n    return a;\n}\n\nasync function openShorts() {\n    \/\/ Oturum kayb\u0131 \/ auth ekran\u0131na d\u00fc\u015fmeyi engelle\n    if (!currentUser) {\n        alert(\"Shorts i\u00e7in giri\u015f yapmal\u0131s\u0131n.\");\n        return;\n    }\n    authScreen.classList.add(\"hidden\");\n    chatScreen.classList.remove(\"hidden\");\n    cycleAppTheme();\n\n    activeChatType = \"shorts\";\n    document.querySelectorAll(\".channelButton\").forEach(btn => btn.classList.remove(\"active\"));\n    document.getElementById(\"shortsButton\").classList.add(\"active\");\n    document.getElementById(\"gamesButton\").classList.remove(\"active\");\n    document.querySelectorAll(\".privateChatItem\").forEach(el => el.classList.remove(\"active\"));\n    mainChatArea.style.display = \"none\";\n    hideExtraScreens();\n    shortsScreen.classList.add(\"active\");\n    document.getElementById(\"gamesScreen\").classList.remove(\"active\");\n    const container = document.getElementById(\"shortsContainer\");\n    if (!container) return;\n    container.innerHTML = `<div style=\"color:#949ba4;padding:40px;text-align:center;\">Shorts y\u00fckleniyor...<\/div>`;\n    closeSidebar();\n\n    const feed = [];\n\n    \/\/ Profil \/ topluluk videolar\u0131\n    try {\n        const snap = await get(query(ref(database, \"userVideos\"), limitToLast(50)));\n        if (snap.exists()) {\n            Object.entries(snap.val()).forEach(([id, v]) => {\n                feed.push({ kind: \"user\", v: { ...v, _id: id } });\n            });\n        }\n    } catch (e) {\n        console.warn(\"userVideos shorts:\", e);\n    }\n\n    \/\/ Sabit YouTube shorts\n    SHORTS_VIDEOS.forEach(v => feed.push({ kind: \"yt\", v }));\n\n    \/\/ Her giri\u015fte farkl\u0131 s\u0131ra\n    const shuffled = shuffleArray(feed);\n\n    container.innerHTML = \"\";\n    shuffled.forEach(entry => {\n        if (entry.kind === \"user\") {\n            const v = entry.v;\n            const ch = \"@\" + (v.username || \"?\") + (v.displayName ? \" \u00b7 \" + v.displayName : \"\") + \" \u00b7 Topluluk\";\n            const item = document.createElement(\"div\");\n            item.className = \"shortItem\";\n            item.style.position = \"relative\";\n            item.innerHTML = `\n                ${buildVVMediaHtml(v)}\n                <div class=\"shortOverlay\">\n                    <div class=\"shortTitle\">${escapeHtml(v.title || \"Kullan\u0131c\u0131 videosu\")}<\/div>\n                    <div class=\"shortChannel\">${escapeHtml(ch)}<\/div>\n                <\/div>`;\n            if (v._id) bindVideoSocialUI(item, v._id, v);\n            container.appendChild(item);\n        } else {\n            const v = entry.v;\n            const media = `<iframe src=\"https:\/\/www.youtube.com\/embed\/${v.id}?rel=0&modestbranding=1&playsinline=1\"\n                allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture\"\n                allowfullscreen loading=\"lazy\"><\/iframe>`;\n            appendShortItem(container, media, v.title, \"@\" + v.channel);\n        }\n    });\n\n    if (!container.children.length) {\n        container.innerHTML = `<div style=\"color:#949ba4;padding:40px;text-align:center;\">Hen\u00fcz short yok.<br>Profilinden YouTube linki ekle.<\/div>`;\n    }\n}\n\n\/* =========================================================\n   ONLINE M\u0130N\u0130 OYUNLAR\n========================================================= *\/\nconst gamesScreen = document.getElementById(\"gamesScreen\");\nlet currentGameUnsub = null;\nlet currentGameId = null;\n\ndocument.getElementById(\"gamesButton\").onclick = () => openGames();\ndocument.getElementById(\"gamesMenuBtn\").onclick = openSidebar;\n\nfunction openGames() {\n    if (!currentUser) {\n        alert(\"Oyunlar i\u00e7in giri\u015f yapmal\u0131s\u0131n.\");\n        return;\n    }\n    authScreen.classList.add(\"hidden\");\n    chatScreen.classList.remove(\"hidden\");\n    cycleAppTheme();\n\n    activeChatType = \"games\";\n    document.querySelectorAll(\".channelButton\").forEach(btn => btn.classList.remove(\"active\"));\n    document.getElementById(\"shortsButton\").classList.remove(\"active\");\n    document.getElementById(\"gamesButton\").classList.add(\"active\");\n    document.querySelectorAll(\".privateChatItem\").forEach(el => el.classList.remove(\"active\"));\n    mainChatArea.style.display = \"none\"; hideExtraScreens();\n    shortsScreen.classList.remove(\"active\");\n    gamesScreen.classList.add(\"active\");\n    const area = document.getElementById(\"activeGameArea\");\n    if (area) {\n        area.classList.add(\"hidden\");\n        area.innerHTML = \"\";\n    }\n    const list = document.getElementById(\"gamesListWrap\");\n    if (list) list.style.display = \"\";\n    const body = document.getElementById(\"gamesBody\");\n    if (body) body.scrollTop = 0;\n    if (currentGameUnsub) { currentGameUnsub(); currentGameUnsub = null; }\n    loadCommunityGamesList();\n    closeSidebar();\n}\n\n\/\/ openChannel'da games'i gizle\nconst _origOpenChannel = openChannel;\nopenChannel = function(channelKey) {\n    gamesScreen.classList.remove(\"active\");\n    document.getElementById(\"gamesButton\").classList.remove(\"active\");\n    _origOpenChannel(channelKey);\n};\n\ndocument.getElementById(\"startDiceBtn\").onclick = async () => {\n    if (!currentUser || !currentProfile) return alert(\"Giri\u015f gerekli\");\n    const roll = Math.floor(Math.random() * 6) + 1;\n    const text = `\ud83c\udfb2 ${currentProfile.displayName} zar att\u0131: **${roll}**`;\n    try {\n        await push(ref(database, \"messages\/oyun\"), {\n            uid: currentUser.uid,\n            text: text,\n            timestamp: Date.now()\n        });\n        alert(\"Zar sonucu #oyun kanal\u0131na g\u00f6nderildi: \" + roll);\n        openChannel(\"oyun\");\n    } catch (e) {\n        alert(\"G\u00f6nderilemedi: \" + e.message);\n    }\n};\n\ndocument.getElementById(\"startRpsBtn\").onclick = () => {\n    const area = gameArea();\n    if (!area) return;\n    area.innerHTML = `<button class=\"gameBackBtn\" id=\"gameBackBtn\">\u2190 Geri<\/button>\n        <div class=\"gameStatus\">Ta\u015f Ka\u011f\u0131t Makas<\/div>\n        <div class=\"modeRow\">\n            <button type=\"button\" class=\"modeBtn on\" id=\"rpsOnline\">\ud83c\udf10 Online<\/button>\n            <button type=\"button\" class=\"modeBtn\" id=\"rpsSplit\">\ud83d\udcf1 Split<\/button>\n            <button type=\"button\" class=\"modeBtn\" id=\"rpsBot\">\ud83e\udd16 Bot<\/button>\n        <\/div><div id=\"gmPlay\"><\/div>`;\n    gameBack(area);\n    document.getElementById(\"rpsOnline\").onclick = () => startRpsLobby();\n    document.getElementById(\"rpsSplit\").onclick = () => startSplitRps(document.getElementById(\"gmPlay\"));\n    document.getElementById(\"rpsBot\").onclick = () => startBotRps(document.getElementById(\"gmPlay\"));\n};\ndocument.getElementById(\"startXoxBtn\").onclick = () => {\n    const area = gameArea();\n    if (!area) return;\n    area.innerHTML = `<button class=\"gameBackBtn\" id=\"gameBackBtn\">\u2190 Geri<\/button>\n        <div class=\"gameStatus\">XOX<\/div>\n        <div class=\"modeRow\">\n            <button type=\"button\" class=\"modeBtn on\" id=\"xoxOnline\">\ud83c\udf10 Online<\/button>\n            <button type=\"button\" class=\"modeBtn\" id=\"xoxSplit\">\ud83d\udcf1 Split<\/button>\n            <button type=\"button\" class=\"modeBtn\" id=\"xoxBot\">\ud83e\udd16 Bot<\/button>\n        <\/div><div id=\"gmPlay\"><\/div>`;\n    gameBack(area);\n    document.getElementById(\"xoxOnline\").onclick = () => startXoxLobby();\n    document.getElementById(\"xoxSplit\").onclick = () => startSplitXox(document.getElementById(\"gmPlay\"));\n    document.getElementById(\"xoxBot\").onclick = () => startBotXox(document.getElementById(\"gmPlay\"));\n};\ndocument.getElementById(\"startWordBtn\").onclick = () => {\n    const area = gameArea();\n    area.innerHTML = `<button class=\"gameBackBtn\" id=\"gameBackBtn\">\u2190 Geri<\/button>\n        <div class=\"gameStatus\">Kelime Sava\u015f\u0131<\/div>\n        <div class=\"modeRow\">\n            <button type=\"button\" class=\"modeBtn on\" id=\"wordOnline\">\ud83c\udf10 Online<\/button>\n            <button type=\"button\" class=\"modeBtn\" id=\"wordSplit\">\ud83d\udcf1 Split screen<\/button>\n        <\/div><div id=\"gmPlay\"><\/div>`;\n    gameBack(area);\n    document.getElementById(\"wordOnline\").onclick = () => startWordLobby();\n    document.getElementById(\"wordSplit\").onclick = () => startSplitWord(document.getElementById(\"gmPlay\"));\n};\n\nfunction startSimpleLobby(type, title) {\n    const area = document.getElementById(\"activeGameArea\");\n    area.classList.remove(\"hidden\");\n    area.innerHTML = `\n        <button class=\"gameBackBtn\" id=\"gameBackBtn\">\u2190 Geri<\/button>\n        <div class=\"gameStatus\">${title}<\/div>\n        <p style=\"color:#949ba4;font-size:13px;text-align:center;\">Oda olu\u015ftur, kodu arkada\u015f\u0131na ver.<\/p>\n        <button id=\"simpleCreate\" style=\"width:100%;padding:12px;border:none;border-radius:8px;background:#5865f2;color:white;font-weight:bold;margin-top:8px;\">Oda Olu\u015ftur<\/button>\n        <div style=\"display:flex;gap:8px;margin-top:10px;\">\n            <input id=\"simpleJoinCode\" placeholder=\"Oda kodu\" maxlength=\"8\" style=\"flex:1;padding:12px;border:none;border-radius:8px;background:#1e1f22;color:white;\">\n            <button id=\"simpleJoin\" style=\"padding:12px 16px;border:none;border-radius:8px;background:#23a559;color:white;\">Kat\u0131l<\/button>\n        <\/div>\n        <div id=\"simplePlay\" style=\"margin-top:16px;\"><\/div>`;\n    document.getElementById(\"gameBackBtn\").onclick = () => { area.classList.add(\"hidden\"); area.innerHTML = \"\"; if (currentGameUnsub) currentGameUnsub(); };\n    document.getElementById(\"simpleCreate\").onclick = async () => {\n        const code = Math.random().toString(36).substring(2, 8).toUpperCase();\n        await set(ref(database, \"minigames\/\" + type + \"\/\" + code), {\n            host: currentUser.uid, hostName: currentProfile.displayName, guest: null, status: \"waiting\",\n            secret: type === \"num\" ? Math.floor(Math.random() * 100) + 1 : null,\n            board: type === \"c4\" ? Array(42).fill(\"\") : null,\n            turn: currentUser.uid, createdAt: Date.now()\n        });\n        document.getElementById(\"simplePlay\").innerHTML = `<div class=\"gameStatus\">Kod: <b>${code}<\/b> \u2014 rakip bekleniyor<\/div>`;\n        if (currentGameUnsub) currentGameUnsub();\n        currentGameUnsub = onValue(ref(database, \"minigames\/\" + type + \"\/\" + code), snap => {\n            const g = snap.val();\n            if (!g) return;\n            if (g.guest) document.getElementById(\"simplePlay\").innerHTML = `<div class=\"gameStatus\">${g.hostName} vs ${g.guestName || \"?\"} \u00b7 Oyun ba\u015flad\u0131! Sohbetten \/ veya RPS\/XOX gibi oynay\u0131n. (Basit oda haz\u0131r)<\/div>`;\n        });\n    };\n    document.getElementById(\"simpleJoin\").onclick = async () => {\n        const code = document.getElementById(\"simpleJoinCode\").value.trim().toUpperCase();\n        const snap = await get(ref(database, \"minigames\/\" + type + \"\/\" + code));\n        if (!snap.exists()) return alert(\"Oda yok\");\n        await update(ref(database, \"minigames\/\" + type + \"\/\" + code), {\n            guest: currentUser.uid, guestName: currentProfile.displayName, status: \"playing\"\n        });\n        document.getElementById(\"simplePlay\").innerHTML = `<div class=\"gameStatus\">Kat\u0131ld\u0131n! Kod: ${code}<\/div>`;\n    };\n}\n\nfunction startWordLobby() {\n    const area = document.getElementById(\"activeGameArea\");\n    area.classList.remove(\"hidden\");\n    area.innerHTML = `\n        <button class=\"gameBackBtn\" id=\"gameBackBtn\">\u2190 Geri<\/button>\n        <div class=\"gameStatus\">Kelime Sava\u015f\u0131<\/div>\n        <button id=\"wordCreate\" style=\"width:100%;padding:12px;border:none;border-radius:8px;background:#5865f2;color:white;font-weight:bold;\">Oda Olu\u015ftur<\/button>\n        <div style=\"display:flex;gap:8px;margin-top:10px;\">\n            <input id=\"wordJoinCode\" placeholder=\"Oda kodu\" maxlength=\"8\" style=\"flex:1;padding:12px;border:none;border-radius:8px;background:#1e1f22;color:white;\">\n            <button id=\"wordJoin\" style=\"padding:12px 16px;border:none;border-radius:8px;background:#23a559;color:white;\">Kat\u0131l<\/button>\n        <\/div>\n        <div id=\"wordPlay\" style=\"margin-top:16px;\"><\/div>`;\n    document.getElementById(\"gameBackBtn\").onclick = () => { area.classList.add(\"hidden\"); area.innerHTML = \"\"; if (currentGameUnsub) currentGameUnsub(); };\n    document.getElementById(\"wordCreate\").onclick = async () => {\n        const code = Math.random().toString(36).substring(2, 8).toUpperCase();\n        await set(ref(database, \"minigames\/word\/\" + code), {\n            host: currentUser.uid, hostName: currentProfile.displayName, guest: null,\n            lastWord: \"elma\", turn: currentUser.uid, status: \"waiting\", words: [\"elma\"]\n        });\n        listenWord(code, true);\n    };\n    document.getElementById(\"wordJoin\").onclick = async () => {\n        const code = document.getElementById(\"wordJoinCode\").value.trim().toUpperCase();\n        const snap = await get(ref(database, \"minigames\/word\/\" + code));\n        if (!snap.exists()) return alert(\"Oda yok\");\n        await update(ref(database, \"minigames\/word\/\" + code), {\n            guest: currentUser.uid, guestName: currentProfile.displayName, status: \"playing\",\n            turn: snap.val().host\n        });\n        listenWord(code, false);\n    };\n}\n\nfunction listenWord(code, isHost) {\n    if (currentGameUnsub) currentGameUnsub();\n    const play = document.getElementById(\"wordPlay\");\n    currentGameUnsub = onValue(ref(database, \"minigames\/word\/\" + code), snap => {\n        if (!snap.exists()) return;\n        const g = snap.val();\n        const myTurn = g.turn === currentUser.uid;\n        let html = `<div class=\"gameStatus\">Oda <b>${code}<\/b> \u00b7 Son kelime: <b>${escapeHtml(g.lastWord)}<\/b><\/div>`;\n        if (g.status === \"waiting\") html += `<div class=\"gameStatus\">Rakip bekleniyor...<\/div>`;\n        else {\n            html += `<div class=\"gameStatus\">${myTurn ? \"S\u0131ra sende!\" : \"Rakip d\u00fc\u015f\u00fcn\u00fcyor...\"}<\/div>\n                <input id=\"wordInput\" placeholder=\"Kelime (son harf: ${(g.lastWord||\"\").slice(-1)})\" style=\"width:100%;padding:12px;border:none;border-radius:8px;background:#1e1f22;color:white;margin-top:8px;\">\n                <button id=\"wordSend\" style=\"width:100%;margin-top:8px;padding:10px;border:none;border-radius:8px;background:#5865f2;color:white;\">G\u00f6nder<\/button>`;\n        }\n        play.innerHTML = html;\n        const send = document.getElementById(\"wordSend\");\n        if (send) send.onclick = async () => {\n            if (!myTurn) return alert(\"S\u0131ra sende de\u011fil\");\n            const w = document.getElementById(\"wordInput\").value.trim().toLowerCase();\n            const last = (g.lastWord || \"\").toLowerCase();\n            if (w.length < 2) return alert(\"En az 2 harf\");\n            if (w[0] !== last.slice(-1)) return alert(\"Son harften ba\u015flamal\u0131: \" + last.slice(-1));\n            if ((g.words || []).includes(w)) return alert(\"Bu kelime kullan\u0131ld\u0131\");\n            const nextTurn = isHost ? g.guest : g.host;\n            await update(ref(database, \"minigames\/word\/\" + code), {\n                lastWord: w,\n                words: [...(g.words || []), w],\n                turn: nextTurn\n            });\n        };\n    });\n}\n\nfunction startRpsLobby() {\n    const area = document.getElementById(\"activeGameArea\");\n    area.classList.remove(\"hidden\");\n    area.innerHTML = `\n        <button class=\"gameBackBtn\" id=\"gameBackBtn\">\u2190 Geri<\/button>\n        <div class=\"gameStatus\">Ta\u015f Ka\u011f\u0131t Makas \u2013 oda olu\u015ftur veya kod gir<\/div>\n        <div style=\"display:flex;gap:8px;margin-top:12px;\">\n            <button id=\"rpsCreateBtn\" style=\"flex:1;padding:12px;border:none;border-radius:8px;background:#5865f2;color:white;font-weight:bold;\">Oda Olu\u015ftur<\/button>\n        <\/div>\n        <div style=\"display:flex;gap:8px;margin-top:10px;\">\n            <input id=\"rpsJoinCode\" placeholder=\"Oda kodu\" maxlength=\"8\"\n                style=\"flex:1;padding:12px;border:none;border-radius:8px;background:#1e1f22;color:white;\">\n            <button id=\"rpsJoinBtn\" style=\"padding:12px 16px;border:none;border-radius:8px;background:#23a559;color:white;font-weight:bold;\">Kat\u0131l<\/button>\n        <\/div>\n        <div id=\"rpsPlayArea\" style=\"margin-top:16px;\"><\/div>\n    `;\n    document.getElementById(\"gameBackBtn\").onclick = () => {\n        if (currentGameUnsub) { currentGameUnsub(); currentGameUnsub = null; }\n        area.classList.add(\"hidden\");\n        area.innerHTML = \"\";\n    };\n    document.getElementById(\"rpsCreateBtn\").onclick = async () => {\n        const code = Math.random().toString(36).substring(2, 8).toUpperCase();\n        currentGameId = code;\n        await set(ref(database, \"minigames\/rps\/\" + code), {\n            host: currentUser.uid,\n            hostName: currentProfile.displayName,\n            guest: null,\n            hostChoice: null,\n            guestChoice: null,\n            status: \"waiting\",\n            createdAt: Date.now()\n        });\n        listenRps(code, true);\n    };\n    document.getElementById(\"rpsJoinBtn\").onclick = async () => {\n        const code = document.getElementById(\"rpsJoinCode\").value.trim().toUpperCase();\n        if (!code) return alert(\"Kod gir\");\n        const snap = await get(ref(database, \"minigames\/rps\/\" + code));\n        if (!snap.exists()) return alert(\"Oda bulunamad\u0131\");\n        const data = snap.val();\n        if (data.guest) return alert(\"Oda dolu\");\n        if (data.host === currentUser.uid) return alert(\"Kendi odana kat\u0131lamazs\u0131n\");\n        await update(ref(database, \"minigames\/rps\/\" + code), {\n            guest: currentUser.uid,\n            guestName: currentProfile.displayName,\n            status: \"playing\"\n        });\n        currentGameId = code;\n        listenRps(code, false);\n    };\n}\n\nfunction listenRps(code, isHost) {\n    if (currentGameUnsub) currentGameUnsub();\n    const playArea = document.getElementById(\"rpsPlayArea\");\n    currentGameUnsub = onValue(ref(database, \"minigames\/rps\/\" + code), snap => {\n        if (!snap.exists()) return;\n        const g = snap.val();\n        let html = `<div class=\"gameStatus\">Oda: <b>${code}<\/b><\/div>`;\n        if (g.status === \"waiting\") {\n            html += `<div class=\"gameStatus\">Rakip bekleniyor... Kodu payla\u015f: <b>${code}<\/b><\/div>`;\n        } else {\n            const myChoice = isHost ? g.hostChoice : g.guestChoice;\n            const oppChoice = isHost ? g.guestChoice : g.hostChoice;\n            const myName = isHost ? g.hostName : g.guestName;\n            const oppName = isHost ? (g.guestName || \"?\") : g.hostName;\n            html += `<div class=\"gameStatus\">${escapeHtml(myName)} vs ${escapeHtml(oppName)}<\/div>`;\n            if (!myChoice) {\n                html += `<div class=\"rpsBtns\">\n                    <button class=\"rpsBtn\" data-c=\"tas\">\u270a<\/button>\n                    <button class=\"rpsBtn\" data-c=\"kagit\">\u270b<\/button>\n                    <button class=\"rpsBtn\" data-c=\"makas\">\u270c\ufe0f<\/button>\n                <\/div>\n                <div class=\"gameStatus\">Se\u00e7imini yap!<\/div>`;\n            } else if (!oppChoice) {\n                html += `<div class=\"gameStatus\">Se\u00e7tin \u2705 Rakip bekleniyor...<\/div>`;\n            } else {\n                const map = { tas: \"\u270a\", kagit: \"\u270b\", makas: \"\u270c\ufe0f\" };\n                let result = \"Berabere!\";\n                if (myChoice !== oppChoice) {\n                    const win = (myChoice === \"tas\" && oppChoice === \"makas\") ||\n                        (myChoice === \"kagit\" && oppChoice === \"tas\") ||\n                        (myChoice === \"makas\" && oppChoice === \"kagit\");\n                    result = win ? \"\ud83c\udf89 Kazand\u0131n!\" : \"\ud83d\ude22 Kaybettin\";\n                }\n                html += `<div class=\"gameStatus\" style=\"font-size:28px;\">${map[myChoice]} vs ${map[oppChoice]}<\/div>\n                    <div class=\"gameStatus\" style=\"font-size:18px;color:#fff;margin-top:8px;\">${result}<\/div>\n                    <button id=\"rpsRematch\" style=\"display:block;margin:16px auto;padding:10px 20px;border:none;border-radius:8px;background:#5865f2;color:white;\">Tekrar Oyna<\/button>`;\n            }\n        }\n        playArea.innerHTML = html;\n        playArea.querySelectorAll(\".rpsBtn\").forEach(btn => {\n            btn.onclick = async () => {\n                const field = isHost ? \"hostChoice\" : \"guestChoice\";\n                await update(ref(database, \"minigames\/rps\/\" + code), { [field]: btn.dataset.c });\n            };\n        });\n        const rematch = document.getElementById(\"rpsRematch\");\n        if (rematch) {\n            rematch.onclick = async () => {\n                await update(ref(database, \"minigames\/rps\/\" + code), {\n                    hostChoice: null, guestChoice: null, status: \"playing\"\n                });\n            };\n        }\n    });\n}\n\nfunction startXoxLobby() {\n    const area = document.getElementById(\"activeGameArea\");\n    area.classList.remove(\"hidden\");\n    area.innerHTML = `\n        <button class=\"gameBackBtn\" id=\"gameBackBtn\">\u2190 Geri<\/button>\n        <div class=\"gameStatus\">XOX \u2013 oda olu\u015ftur veya kod gir<\/div>\n        <div style=\"display:flex;gap:8px;margin-top:12px;\">\n            <button id=\"xoxCreateBtn\" style=\"flex:1;padding:12px;border:none;border-radius:8px;background:#5865f2;color:white;font-weight:bold;\">Oda Olu\u015ftur (X)<\/button>\n        <\/div>\n        <div style=\"display:flex;gap:8px;margin-top:10px;\">\n            <input id=\"xoxJoinCode\" placeholder=\"Oda kodu\" maxlength=\"8\"\n                style=\"flex:1;padding:12px;border:none;border-radius:8px;background:#1e1f22;color:white;\">\n            <button id=\"xoxJoinBtn\" style=\"padding:12px 16px;border:none;border-radius:8px;background:#23a559;color:white;font-weight:bold;\">Kat\u0131l (O)<\/button>\n        <\/div>\n        <div id=\"xoxPlayArea\" style=\"margin-top:16px;\"><\/div>\n    `;\n    document.getElementById(\"gameBackBtn\").onclick = () => {\n        if (currentGameUnsub) { currentGameUnsub(); currentGameUnsub = null; }\n        area.classList.add(\"hidden\");\n        area.innerHTML = \"\";\n    };\n    document.getElementById(\"xoxCreateBtn\").onclick = async () => {\n        const code = Math.random().toString(36).substring(2, 8).toUpperCase();\n        currentGameId = code;\n        await set(ref(database, \"minigames\/xox\/\" + code), {\n            host: currentUser.uid,\n            hostName: currentProfile.displayName,\n            guest: null,\n            board: [\"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\", \"\"],\n            turn: \"X\",\n            winner: null,\n            status: \"waiting\",\n            createdAt: Date.now()\n        });\n        listenXox(code, \"X\");\n    };\n    document.getElementById(\"xoxJoinBtn\").onclick = async () => {\n        const code = document.getElementById(\"xoxJoinCode\").value.trim().toUpperCase();\n        if (!code) return alert(\"Kod gir\");\n        const snap = await get(ref(database, \"minigames\/xox\/\" + code));\n        if (!snap.exists()) return alert(\"Oda bulunamad\u0131\");\n        const data = snap.val();\n        if (data.guest) return alert(\"Oda dolu\");\n        if (data.host === currentUser.uid) return alert(\"Kendi odana kat\u0131lamazs\u0131n\");\n        await update(ref(database, \"minigames\/xox\/\" + code), {\n            guest: currentUser.uid,\n            guestName: currentProfile.displayName,\n            status: \"playing\"\n        });\n        currentGameId = code;\n        listenXox(code, \"O\");\n    };\n}\n\nfunction checkXoxWinner(board) {\n    const lines = [[0,1,2],[3,4,5],[6,7,8],[0,3,6],[1,4,7],[2,5,8],[0,4,8],[2,4,6]];\n    for (const [a,b,c] of lines) {\n        if (board[a] && board[a] === board[b] && board[a] === board[c]) return board[a];\n    }\n    if (board.every(c => c)) return \"draw\";\n    return null;\n}\n\nfunction listenXox(code, myMark) {\n    if (currentGameUnsub) currentGameUnsub();\n    const playArea = document.getElementById(\"xoxPlayArea\");\n    currentGameUnsub = onValue(ref(database, \"minigames\/xox\/\" + code), snap => {\n        if (!snap.exists()) return;\n        const g = snap.val();\n        let html = `<div class=\"gameStatus\">Oda: <b>${code}<\/b> \u00b7 Sen: <b>${myMark}<\/b><\/div>`;\n        if (g.status === \"waiting\") {\n            html += `<div class=\"gameStatus\">Rakip bekleniyor... Kod: <b>${code}<\/b><\/div>`;\n        } else {\n            const board = g.board || [\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"\"];\n            html += `<div class=\"xoxBoard\">`;\n            board.forEach((cell, i) => {\n                html += `<button class=\"xoxCell\" data-i=\"${i}\">${cell}<\/button>`;\n            });\n            html += `<\/div>`;\n            if (g.bet && g.bet.amount) {\n                html += `<div class=\"gameStatus\" style=\"color:#faa61a;\">\ud83d\udcb0 \u0130ddia: ${g.bet.amount} ${g.bet.kind === \"vc\" ? \"VC\" : \"XP\"}<\/div>`;\n            }\n            if (g.winner === \"draw\") html += `<div class=\"gameStatus\">Berabere!<\/div>`;\n            else if (g.winner) html += `<div class=\"gameStatus\">${g.winner === myMark ? \"\ud83c\udf89 Kazand\u0131n!\" : \"\ud83d\ude22 Kaybettin\"} (${g.winner})<\/div>`;\n            else html += `<div class=\"gameStatus\">S\u0131ra: ${g.turn}${g.turn === myMark ? \" (sen)\" : \"\"}<\/div>`;\n            if (g.winner) {\n                html += `<button id=\"xoxRematch\" style=\"display:block;margin:12px auto;padding:10px 20px;border:none;border-radius:8px;background:#5865f2;color:white;\">Tekrar<\/button>`;\n            }\n        }\n        playArea.innerHTML = html;\n        \/\/ \u0130ddia \u00f6deme (berabere de\u011filse)\n        if (g.winner && g.winner !== \"draw\" && g.bet && g.bet.amount && !g.betSettled) {\n            const winnerRole = g.winner === \"X\" ? \"host\" : \"guest\"; \/\/ host always X\n            if (myMark === \"X\") {\n                (async () => {\n                    try {\n                        await update(ref(database, \"minigames\/xox\/\" + code), { betSettled: true, winnerRole });\n                        await settleBet({ ...g, winnerRole, _type: \"xox\", _code: code }, \"host\");\n                    } catch (_) {}\n                })();\n            }\n        }\n        playArea.querySelectorAll(\".xoxCell\").forEach(btn => {\n            btn.onclick = async () => {\n                const snap2 = await get(ref(database, \"minigames\/xox\/\" + code));\n                const g2 = snap2.val();\n                if (g2.winner || g2.turn !== myMark) return;\n                const i = +btn.dataset.i;\n                if (g2.board[i]) return;\n                const board = [...g2.board];\n                board[i] = myMark;\n                const winner = checkXoxWinner(board);\n                await update(ref(database, \"minigames\/xox\/\" + code), {\n                    board,\n                    turn: myMark === \"X\" ? \"O\" : \"X\",\n                    winner: winner || null\n                });\n                if (winner && winner === myMark) bumpStat(\"gamesWon\");\n            };\n        });\n        const rematch = document.getElementById(\"xoxRematch\");\n        if (rematch) {\n            rematch.onclick = async () => {\n                await update(ref(database, \"minigames\/xox\/\" + code), {\n                    board: [\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"\",\"\"],\n                    turn: \"X\",\n                    winner: null,\n                    status: \"playing\",\n                    betSettled: false\n                });\n            };\n        }\n    });\n}\n\ndocument.getElementById(\"userSearchButton\").onclick = searchUser;\ndocument.getElementById(\"userSearchInput\").addEventListener(\"keydown\", e => {\n    if (e.key === \"Enter\") searchUser();\n});\n\/\/ input ile filtre (loadAllUsersList) yukar\u0131da tan\u0131ml\u0131 group b\u00f6l\u00fcm\u00fcnde de ba\u011flan\u0131r\n\nlet cachedAllUsers = []; \/\/ [{uid, username, displayName, about, photoData}]\n\nasync function loadAllUsersList(filterText = \"\") {\n    const box = document.getElementById(\"allUsersList\");\n    if (!box || !currentUser) return;\n    if (!cachedAllUsers.length) {\n        box.innerHTML = `<div style=\"color:#949ba4;font-size:12px;padding:6px;\">Y\u00fckleniyor...<\/div>`;\n        try {\n            const snap = await get(ref(database, \"usernames\"));\n            if (!snap.exists()) {\n                box.innerHTML = `<div style=\"color:#949ba4;font-size:12px;padding:6px;\">Hen\u00fcz kullan\u0131c\u0131 yok.<\/div>`;\n                return;\n            }\n            const entries = Object.entries(snap.val());\n            const list = [];\n            for (const [uname, uid] of entries) {\n                if (uid === currentUser.uid) continue;\n                const p = await getUserProfile(uid);\n                list.push({\n                    uid,\n                    username: p?.username || uname,\n                    displayName: p?.displayName || uname,\n                    about: p?.about || \"\",\n                    photoData: p?.photoData || \"\"\n                });\n            }\n            list.sort((a, b) => a.displayName.localeCompare(b.displayName, \"tr\"));\n            cachedAllUsers = list;\n        } catch (e) {\n            box.innerHTML = `<div style=\"color:#ff7777;font-size:12px;padding:6px;\">Liste al\u0131namad\u0131<\/div>`;\n            return;\n        }\n    }\n    const q = (filterText || \"\").trim().toLowerCase();\n    const filtered = q\n        ? cachedAllUsers.filter(u =>\n            u.username.toLowerCase().includes(q) ||\n            u.displayName.toLowerCase().includes(q))\n        : cachedAllUsers;\n    box.innerHTML = \"\";\n    if (!filtered.length) {\n        box.innerHTML = `<div style=\"color:#949ba4;font-size:12px;padding:6px;\">Sonu\u00e7 yok<\/div>`;\n        return;\n    }\n    filtered.forEach(u => {\n        const card = document.createElement(\"div\");\n        card.className = \"searchUserCard\";\n        card.style.marginBottom = \"6px\";\n        const avatar = document.createElement(\"div\");\n        avatar.className = \"avatar\";\n        setAvatar(avatar, u);\n        const info = document.createElement(\"div\");\n        info.className = \"searchUserInformation\";\n        info.innerHTML = `\n            <div class=\"searchDisplayName\">${escapeHtml(u.displayName)}<\/div>\n            <div class=\"searchUsername\">@${escapeHtml(u.username)}<\/div>`;\n        card.appendChild(avatar);\n        card.appendChild(info);\n        card.onclick = () => openPrivateChat(u.uid, u);\n        box.appendChild(card);\n    });\n    searchMessage.textContent = filtered.length + \" hesap \u00b7 t\u0131kla \u2192 \u00f6zel sohbet\";\n}\n\nasync function searchUser() {\n    searchResult.textContent = \"\";\n    const raw = document.getElementById(\"userSearchInput\").value || \"\";\n    const searched = normalizeUsername(raw);\n    await loadAllUsersList(raw);\n    if (!searched) {\n        searchMessage.textContent = \"T\u00fcm hesaplar a\u015fa\u011f\u0131da. Ara veya se\u00e7.\";\n        return;\n    }\n    if (searched.length < 2) {\n        searchMessage.textContent = \"En az 2 karakter yaz veya listeden se\u00e7.\";\n        return;\n    }\n    searchMessage.textContent = \"Aran\u0131yor...\";\n    try {\n        const snap = await get(ref(database, \"usernames\/\" + searched));\n        if (snap.exists()) {\n            const foundUid = snap.val();\n            if (foundUid === currentUser.uid) {\n                searchMessage.textContent = \"Bu senin hesab\u0131n \ud83d\ude42 \u00b7 Di\u011ferleri a\u015fa\u011f\u0131da\";\n                return;\n            }\n            const profile = await getUserProfile(foundUid);\n            if (profile) {\n                searchMessage.textContent = \"E\u015fle\u015fme:\";\n                createSearchResultCard(foundUid, profile);\n                return;\n            }\n        }\n        searchMessage.textContent = \"Tam e\u015fle\u015fme yok \u00b7 filtreli liste a\u015fa\u011f\u0131da\";\n    } catch (e) {\n        console.error(e);\n        searchMessage.textContent = \"Arama yap\u0131lamad\u0131.\";\n    }\n}\n\nfunction createSearchResultCard(uid, profile) {\n    searchResult.textContent = \"\";\n    const card = document.createElement(\"div\");\n    card.className = \"searchUserCard\";\n    const avatar = document.createElement(\"div\");\n    avatar.className = \"avatar\";\n    setAvatar(avatar, profile);\n    const info = document.createElement(\"div\");\n    info.className = \"searchUserInformation\";\n    info.innerHTML = `\n        <div class=\"searchDisplayName\">${escapeHtml(profile.displayName)}<\/div>\n        <div class=\"searchUsername\">@${escapeHtml(profile.username)}<\/div>\n        <div class=\"searchAbout\">${escapeHtml(profile.about || \"\")}<\/div>`;\n    card.appendChild(avatar);\n    card.appendChild(info);\n    card.onclick = () => openPrivateChat(uid, profile);\n    searchResult.appendChild(card);\n}\n\nfunction getPrivateChatId(a, b) { return [a, b].sort().join(\"__\"); }\n\nasync function ensureConversation(otherUid) {\n    const chatId = getPrivateChatId(currentUser.uid, otherUid);\n    const convRef = ref(database, \"conversations\/\" + chatId);\n    let exists = false;\n    try {\n        const existing = await get(convRef);\n        exists = existing.exists();\n    } catch (_) {\n        \/\/ Eski rules: konu\u015fma yokken okuma reddedilebilir\n        exists = false;\n    }\n    if (!exists) {\n        try {\n            await set(convRef, {\n                participants: { [currentUser.uid]: true, [otherUid]: true },\n                createdAt: Date.now()\n            });\n        } catch (e) {\n            try {\n                const check = await get(convRef);\n                if (!check.exists()) throw e;\n            } catch (e2) {\n                throw e;\n            }\n        }\n    }\n    await update(ref(database, \"userConversations\/\" + currentUser.uid + \"\/\" + chatId), {\n        otherUid,\n        updatedAt: Date.now()\n    });\n    try {\n        await update(ref(database, \"userConversations\/\" + otherUid + \"\/\" + chatId), {\n            otherUid: currentUser.uid,\n            updatedAt: Date.now()\n        });\n    } catch (e) {\n        console.warn(\"Kar\u015f\u0131 kullan\u0131c\u0131n\u0131n sohbet listesi g\u00fcncellenemedi (rules):\", e.message);\n    }\n    return chatId;\n}\n\nasync function openPrivateChat(uid, profile) {\n    if (!uid || !profile) {\n        alert(\"Kullan\u0131c\u0131 bilgisi eksik.\");\n        return;\n    }\n    if (!currentUser) {\n        alert(\"Oturum bulunamad\u0131, tekrar giri\u015f yap.\");\n        return;\n    }\n    try {\n        const chatId = await ensureConversation(uid);\n        activeChatType = \"private\";\n        activePrivateUser = { uid, profile };\n        activeChatId = chatId;\n\n        \/\/ T\u00fcm kanal butonlar\u0131n\u0131 pasif yap\n        document.querySelectorAll(\".channelButton\").forEach(btn => btn.classList.remove(\"active\"));\n        document.getElementById(\"shortsButton\").classList.remove(\"active\");\n        document.getElementById(\"gamesButton\").classList.remove(\"active\");\n        document.querySelectorAll(\".privateChatItem\").forEach(el => {\n            el.classList.toggle(\"active\", el.dataset.chatId === chatId);\n        });\n\n        mainChatArea.style.display = \"flex\"; hideExtraScreens();\n        shortsScreen.classList.remove(\"active\");\n        document.getElementById(\"gamesScreen\").classList.remove(\"active\");\n        const headerAvatar = document.getElementById(\"chatHeaderAvatar\");\n        headerAvatar.classList.remove(\"hidden\");\n        setAvatar(headerAvatar, profile);\n        document.getElementById(\"chatTitle\").textContent = profile.displayName;\n        document.getElementById(\"chatSubtitle\").textContent = \"@\" + profile.username + \" \u2022 \" + (profile.about || \"\");\n        messageInput.placeholder = profile.displayName + \" ki\u015fisine mesaj g\u00f6nder\";\n        startMessageStream(\"privateMessages\/\" + chatId);\n        applyChatBackground();\n        updatePrivateLastSeenLine();\n        closeSidebar();\n    } catch (e) {\n        console.error(\"\u00d6zel sohbet hatas\u0131:\", e);\n        alert(\"\u00d6zel sohbet a\u00e7\u0131lamad\u0131.\\n\\nSebep: \" + (e.message || e.code || e) + \"\\n\\nFirebase Rules'u g\u00fcncelledin mi?\");\n    }\n}\n\nfunction loadPrivateChats() {\n    if (privateChatsUnsub) privateChatsUnsub();\n    const listRef = ref(database, \"userConversations\/\" + currentUser.uid);\n    privateChatsUnsub = onValue(listRef, async snap => {\n        privateChatsList.innerHTML = \"\";\n        \/\/ Arkada\u015flar \u00e7evrimi\u00e7i\n        try {\n            const fs = await get(ref(database, \"friends\/\" + currentUser.uid));\n            if (fs.exists()) {\n                const title = document.createElement(\"div\");\n                title.className = \"sectionTitle\";\n                title.textContent = \"ARKADA\u015eLAR\";\n                title.style.marginTop = \"8px\";\n                privateChatsList.appendChild(title);\n                const entries = Object.entries(fs.val());\n                for (const [fuid, f] of entries.slice(0, 20)) {\n                    const st = await get(ref(database, \"status\/\" + fuid));\n                    const online = st.exists() && st.val().state === \"online\";\n                    const item = document.createElement(\"button\");\n                    item.className = \"privateChatItem\";\n                    item.innerHTML = `<div class=\"privateChatInfo\"><div class=\"privateChatName\">${online ? \"\ud83d\udfe2\" : \"\u26ab\"} ${escapeHtml(f.displayName || \"?\")}<\/div>\n                        <div class=\"privateChatLast\">@${escapeHtml(f.username || \"\")}<\/div><\/div>`;\n                    item.onclick = async () => {\n                        const p = await getUserProfile(fuid);\n                        if (p) openPrivateChat(fuid, p);\n                    };\n                    privateChatsList.appendChild(item);\n                }\n            }\n        } catch (_) {}\n        if (!snap.exists()) return;\n        const data = snap.val();\n        const entries = Object.entries(data).sort((a, b) => (b[1].updatedAt || 0) - (a[1].updatedAt || 0));\n        const t2 = document.createElement(\"div\");\n        t2.className = \"sectionTitle\";\n        t2.textContent = \"\u00d6ZEL SOHBET\";\n        privateChatsList.appendChild(t2);\n        for (const [chatId, info] of entries) {\n            const profile = await getUserProfile(info.otherUid);\n            if (!profile) continue;\n            const item = document.createElement(\"button\");\n            item.className = \"privateChatItem\";\n            item.dataset.chatId = chatId;\n            if (activeChatId === chatId) item.classList.add(\"active\");\n            const av = document.createElement(\"div\");\n            av.className = \"privateChatAvatar\";\n            setAvatar(av, profile);\n            const inf = document.createElement(\"div\");\n            inf.className = \"privateChatInfo\";\n            inf.innerHTML = `\n                <div class=\"privateChatName\">${escapeHtml(profile.displayName)}<\/div>\n                <div class=\"privateChatLast\">@${escapeHtml(profile.username)}<\/div>`;\n            item.appendChild(av);\n            item.appendChild(inf);\n            item.onclick = () => openPrivateChat(info.otherUid, profile);\n            privateChatsList.appendChild(item);\n        }\n    });\n}\n\n\/* ========== GRUPLAR ========== *\/\nlet groupsUnsub = null;\nlet activeGroupId = null;\nlet groupPickSelected = new Set();\n\nfunction loadGroups() {\n    if (groupsUnsub) groupsUnsub();\n    const box = document.getElementById(\"groupsList\");\n    if (!box || !currentUser) return;\n    groupsUnsub = onValue(ref(database, \"userGroups\/\" + currentUser.uid), async snap => {\n        box.innerHTML = \"\";\n        if (!snap.exists()) return;\n        const entries = Object.entries(snap.val()).sort((a, b) => (b[1].updatedAt || 0) - (a[1].updatedAt || 0));\n        for (const [gid, info] of entries) {\n            const btn = document.createElement(\"button\");\n            btn.className = \"channelButton\";\n            btn.textContent = \"\ud83d\udc65 \" + (info.name || \"Grup\");\n            if (activeChatType === \"group\" && activeGroupId === gid) btn.classList.add(\"active\");\n            btn.onclick = () => openGroup(gid, info.name || \"Grup\");\n            box.appendChild(btn);\n        }\n    });\n}\n\nasync function openGroup(groupId, name) {\n    activeChatType = \"group\";\n    activeGroupId = groupId;\n    activeChatId = groupId;\n    activePrivateUser = null;\n    document.querySelectorAll(\".channelButton\").forEach(b => b.classList.remove(\"active\"));\n    document.querySelectorAll(\".privateChatItem\").forEach(el => el.classList.remove(\"active\"));\n    mainChatArea.style.display = \"flex\";\n    hideExtraScreens();\n    shortsScreen.classList.remove(\"active\");\n    document.getElementById(\"gamesScreen\").classList.remove(\"active\");\n    document.getElementById(\"chatHeaderAvatar\").classList.add(\"hidden\");\n    document.getElementById(\"chatTitle\").textContent = \"\ud83d\udc65 \" + name;\n    document.getElementById(\"chatSubtitle\").textContent = \"Grup sohbeti\";\n    messageInput.placeholder = name + \" grubuna yaz...\";\n    startMessageStream(\"groupMessages\/\" + groupId);\n    closeSidebar();\n    loadGroups();\n}\n\nasync function openGroupCreateModal() {\n    groupPickSelected = new Set();\n    document.getElementById(\"groupNameInput\").value = \"\";\n    document.getElementById(\"groupModalMsg\").textContent = \"\";\n    document.getElementById(\"groupModal\").classList.remove(\"hidden\");\n    const pick = document.getElementById(\"groupMemberPick\");\n    pick.innerHTML = \"Y\u00fckleniyor...\";\n    await loadAllUsersList(\"\");\n    pick.innerHTML = \"\";\n    if (!cachedAllUsers.length) {\n        pick.innerHTML = `<div style=\"color:#949ba4;padding:8px;\">Ba\u015fka kullan\u0131c\u0131 yok.<\/div>`;\n        return;\n    }\n    cachedAllUsers.forEach(u => {\n        const row = document.createElement(\"label\");\n        row.style.cssText = \"display:flex;align-items:center;gap:8px;padding:6px;cursor:pointer;border-radius:6px;\";\n        row.onmouseover = () => row.style.background = \"#2b2d31\";\n        row.onmouseout = () => row.style.background = \"transparent\";\n        const cb = document.createElement(\"input\");\n        cb.type = \"checkbox\";\n        cb.onchange = () => {\n            if (cb.checked) groupPickSelected.add(u.uid);\n            else groupPickSelected.delete(u.uid);\n        };\n        row.appendChild(cb);\n        row.appendChild(document.createTextNode(u.displayName + \" (@\" + u.username + \")\"));\n        pick.appendChild(row);\n    });\n}\n\ndocument.getElementById(\"createGroupBtn\").onclick = openGroupCreateModal;\ndocument.getElementById(\"groupModalCancel\").onclick = () => {\n    document.getElementById(\"groupModal\").classList.add(\"hidden\");\n};\ndocument.getElementById(\"groupModalCreate\").onclick = async () => {\n    const msg = document.getElementById(\"groupModalMsg\");\n    const name = (document.getElementById(\"groupNameInput\").value || \"\").trim().slice(0, 40);\n    if (!name) { msg.style.color = \"#ff7777\"; msg.textContent = \"Grup ad\u0131 yaz.\"; return; }\n    if (!groupPickSelected.size) { msg.style.color = \"#ff7777\"; msg.textContent = \"En az 1 \u00fcye se\u00e7.\"; return; }\n    try {\n        const gid = push(ref(database, \"groups\")).key;\n        const members = { [currentUser.uid]: true };\n        groupPickSelected.forEach(uid => { members[uid] = true; });\n        await set(ref(database, \"groups\/\" + gid), {\n            name,\n            members,\n            createdBy: currentUser.uid,\n            createdAt: Date.now()\n        });\n        const ug = { name, updatedAt: Date.now() };\n        await set(ref(database, \"userGroups\/\" + currentUser.uid + \"\/\" + gid), ug);\n        for (const uid of groupPickSelected) {\n            try {\n                await set(ref(database, \"userGroups\/\" + uid + \"\/\" + gid), ug);\n            } catch (_) {}\n        }\n        document.getElementById(\"groupModal\").classList.add(\"hidden\");\n        openGroup(gid, name);\n    } catch (e) {\n        msg.style.color = \"#ff7777\";\n        msg.textContent = e.message || \"Olu\u015fturulamad\u0131\";\n    }\n};\n\ndocument.getElementById(\"userSearchInput\").addEventListener(\"input\", e => {\n    loadAllUsersList(e.target.value);\n});\n\nlet lastStreamPath = \"messages\/general\";\nlet drawnMsgKeys = new Set();\nfunction startMessageStream(path) {\n    if (activeMessageUnsubscribe) {\n        activeMessageUnsubscribe();\n        activeMessageUnsubscribe = null;\n    }\n    const pathChanged = path !== lastStreamPath;\n    lastStreamPath = path;\n    \/\/ Sadece kanal de\u011fi\u015fince temizle \u2014 yazarken mesajlar\u0131n kaybolmas\u0131n\u0131 engeller\n    if (pathChanged) {\n        messagesContainer.innerHTML = \"\";\n        drawnMsgKeys = new Set();\n    }\n    listenTyping();\n    updatePinnedBar();\n    applyChatWallpaper();\n    const muted = isChannelMuted(path);\n    const muteBtn = document.getElementById(\"muteChannelBtn\");\n    if (muteBtn) muteBtn.textContent = muted ? \"\ud83d\udd15\" : \"\ud83d\udd14\";\n    const q = query(ref(database, path), limitToLast(120));\n    activeMessageUnsubscribe = onChildAdded(q, snap => {\n        if (path !== lastStreamPath) return;\n        const msg = snap.val();\n        if (!msg) return;\n        msg._key = snap.key;\n        msg.id = snap.key;\n        msg._path = path;\n        if (drawnMsgKeys.has(snap.key)) return;\n        drawnMsgKeys.add(snap.key);\n        drawMessage(msg);\n        \/\/ \u00d6zel sohbette okundu i\u015faretle (mesaj\u0131 yeniden \u00e7izdirmeden)\n        if (path.startsWith(\"privateMessages\/\") && currentUser && msg.uid && msg.uid !== currentUser.uid) {\n            set(ref(database, path + \"\/\" + snap.key + \"\/readBy\/\" + currentUser.uid), {\n                at: Date.now()\n            }).catch(() => {});\n        }\n        if (msg.uid !== currentUser?.uid && !isChannelMuted(path)) {\n            if (document.hidden) showNotification(msg);\n            else playNotificationSound();\n        }\n    });\n}\n\nfunction isChannelMuted(path) {\n    try {\n        return localStorage.getItem(\"vegamedia_mute_\" + (path || \"\")) === \"1\";\n    } catch (_) { return false; }\n}\nfunction toggleChannelMute() {\n    const path = lastStreamPath || activeMessagesPath();\n    const key = \"vegamedia_mute_\" + path;\n    const next = localStorage.getItem(key) === \"1\" ? \"0\" : \"1\";\n    localStorage.setItem(key, next);\n    const muteBtn = document.getElementById(\"muteChannelBtn\");\n    if (muteBtn) muteBtn.textContent = next === \"1\" ? \"\ud83d\udd15\" : \"\ud83d\udd14\";\n    alert(next === \"1\" ? \"Bu sohbet sessize al\u0131nd\u0131 (sadece sende).\" : \"Sohbet sesi a\u00e7\u0131ld\u0131.\");\n}\nasync function updatePinnedBar() {\n    const bar = document.getElementById(\"pinnedBar\");\n    if (!bar) return;\n    const path = lastStreamPath || activeMessagesPath();\n    try {\n        const snap = await get(ref(database, \"pins\/\" + path.replace(\/\\\/\/g, \"_\")));\n        if (!snap.exists()) {\n            bar.style.display = \"none\";\n            bar.classList.add(\"hidden\");\n            bar.textContent = \"\";\n            return;\n        }\n        const p = snap.val();\n        bar.style.display = \"block\";\n        bar.classList.remove(\"hidden\");\n        bar.innerHTML = \"\ud83d\udccc \" + escapeHtml((p.text || \"\").slice(0, 100));\n    } catch (_) {\n        bar.style.display = \"none\";\n    }\n}\nfunction runMsgSearch() {\n    const q = (document.getElementById(\"msgSearchInput\")?.value || \"\").trim().toLowerCase();\n    if (!q) return;\n    let found = 0;\n    document.querySelectorAll(\"#messages .message\").forEach(row => {\n        const t = (row.textContent || \"\").toLowerCase();\n        const hit = t.includes(q);\n        row.style.outline = hit ? \"2px solid #5865f2\" : \"\";\n        row.style.opacity = hit ? \"1\" : \"0.35\";\n        if (hit) {\n            found++;\n            if (found === 1) row.scrollIntoView({ behavior: \"smooth\", block: \"center\" });\n        }\n    });\n    if (!found) alert(\"Sonu\u00e7 yok (sadece y\u00fcklenen mesajlarda aran\u0131r).\");\n}\ndocument.getElementById(\"searchMsgBtn\")?.addEventListener(\"click\", () => {\n    const bar = document.getElementById(\"msgSearchBar\");\n    if (!bar) return;\n    const open = bar.style.display === \"flex\";\n    bar.style.display = open ? \"none\" : \"flex\";\n    bar.classList.toggle(\"hidden\", open);\n    if (!open) document.getElementById(\"msgSearchInput\")?.focus();\n});\ndocument.getElementById(\"msgSearchClose\")?.addEventListener(\"click\", () => {\n    const bar = document.getElementById(\"msgSearchBar\");\n    if (bar) { bar.style.display = \"none\"; bar.classList.add(\"hidden\"); }\n    document.querySelectorAll(\"#messages .message\").forEach(row => {\n        row.style.outline = \"\";\n        row.style.opacity = \"1\";\n    });\n});\ndocument.getElementById(\"msgSearchGo\")?.addEventListener(\"click\", runMsgSearch);\ndocument.getElementById(\"msgSearchInput\")?.addEventListener(\"keydown\", e => {\n    if (e.key === \"Enter\") runMsgSearch();\n});\ndocument.getElementById(\"muteChannelBtn\")?.addEventListener(\"click\", toggleChannelMute);\n\ndocument.getElementById(\"sendButton\").onclick = sendMessage;\nmessageInput.addEventListener(\"keydown\", e => {\n    if (e.key === \"Enter\" && !e.shiftKey) {\n        e.preventDefault();\n        sendMessage();\n    }\n});\n\n\/* =========================================================\n   ADMIN KOMUTLARI (gizli)\n   \/giveadmin  \u2192 admin ol\n   \/dontadmin  \u2192 adminli\u011fi b\u0131rak\n   \/ban kullan\u0131c\u0131ad\u0131\n   \/unban kullan\u0131c\u0131ad\u0131\n   \/rename kullan\u0131c\u0131ad\u0131 YeniAd\n========================================================= *\/\nasync function isCurrentUserAdmin() {\n    if (!currentUser) return false;\n    try {\n        const snap = await get(ref(database, \"admins\/\" + currentUser.uid));\n        return snap.exists() && snap.val() === true;\n    } catch {\n        return false;\n    }\n}\n\nasync function handleAdminCommand(text) {\n    const lower = text.toLowerCase().trim();\n    const parts = text.trim().split(\/\\s+\/);\n\n    \/\/ Yeni komutlar (help, roll, whois, xp, slow, lock, poll, warn, endlive, giveadmin ...)\n    if (await handleExtraCommand(text, parts, lower)) return true;\n\n    \/\/ Ban\n    if (parts[0].toLowerCase() === \"\/ban\" && parts[1]) {\n        if (!(await isCurrentUserAdmin())) {\n            alert(\"Bu komut i\u00e7in admin olmal\u0131s\u0131n.\");\n            return true;\n        }\n        const targetKey = normalizeUsername(parts[1]);\n        const uidSnap = await get(ref(database, \"usernames\/\" + targetKey));\n        if (!uidSnap.exists()) {\n            alert(\"Kullan\u0131c\u0131 bulunamad\u0131: \" + parts[1]);\n            return true;\n        }\n        const targetUid = uidSnap.val();\n        if (targetUid === currentUser.uid) {\n            alert(\"Kendini banlayamazs\u0131n.\");\n            return true;\n        }\n        await set(ref(database, \"banned\/\" + targetUid), {\n            by: currentUser.uid,\n            username: targetKey,\n            at: Date.now()\n        });\n        await writeAudit(\"ban\", \"@\" + targetKey);\n        alert(\"\ud83d\udeab @\" + targetKey + \" banland\u0131.\");\n        return true;\n    }\n\n    \/\/ Unban\n    if (parts[0].toLowerCase() === \"\/unban\" && parts[1]) {\n        if (!(await isCurrentUserAdmin())) {\n            alert(\"Bu komut i\u00e7in admin olmal\u0131s\u0131n.\");\n            return true;\n        }\n        const targetKey = normalizeUsername(parts[1]);\n        const uidSnap = await get(ref(database, \"usernames\/\" + targetKey));\n        if (!uidSnap.exists()) {\n            alert(\"Kullan\u0131c\u0131 bulunamad\u0131.\");\n            return true;\n        }\n        await remove(ref(database, \"banned\/\" + uidSnap.val()));\n        alert(\"\u2705 @\" + targetKey + \" ban\u0131 kald\u0131r\u0131ld\u0131.\");\n        return true;\n    }\n\n    \/\/ Rename: \/rename kullan\u0131c\u0131ad\u0131 Yeni G\u00f6r\u00fcnen Ad\n    if (parts[0].toLowerCase() === \"\/rename\" && parts.length >= 3) {\n        if (!(await isCurrentUserAdmin())) {\n            alert(\"Bu komut i\u00e7in admin olmal\u0131s\u0131n.\");\n            return true;\n        }\n        const targetKey = normalizeUsername(parts[1]);\n        const newName = parts.slice(2).join(\" \").trim().slice(0, 24);\n        if (newName.length < 2) {\n            alert(\"Yeni ad en az 2 karakter olmal\u0131.\");\n            return true;\n        }\n        const uidSnap = await get(ref(database, \"usernames\/\" + targetKey));\n        if (!uidSnap.exists()) {\n            alert(\"Kullan\u0131c\u0131 bulunamad\u0131: \" + parts[1]);\n            return true;\n        }\n        const targetUid = uidSnap.val();\n        await update(ref(database, \"users\/\" + targetUid), { displayName: newName });\n        profileCache.delete(targetUid);\n        alert(\"\u2705 @\" + targetKey + \" g\u00f6r\u00fcnen ad\u0131 \u2192 \" + newName);\n        return true;\n    }\n\n    \/\/ Ba\u015fkas\u0131n\u0131n a\u011fz\u0131ndan yaz: \/sayas kullanici mesaj...\n    if (parts[0].toLowerCase() === \"\/sayas\" && parts.length >= 3) {\n        if (!(await isCurrentUserAdmin())) {\n            alert(\"Bu komut i\u00e7in admin olmal\u0131s\u0131n.\");\n            return true;\n        }\n        const targetKey = normalizeUsername(parts[1]);\n        const sayText = parts.slice(2).join(\" \").trim().slice(0, 500);\n        const uidSnap = await get(ref(database, \"usernames\/\" + targetKey));\n        if (!uidSnap.exists()) {\n            alert(\"Kullan\u0131c\u0131 bulunamad\u0131: \" + parts[1]);\n            return true;\n        }\n        const targetUid = uidSnap.val();\n        let messagePath = \"messages\/general\";\n        if (activeChatType === \"private\" && activeChatId) {\n            messagePath = \"privateMessages\/\" + activeChatId;\n        } else if (CHANNELS[activeChatType]) {\n            messagePath = CHANNELS[activeChatType].path;\n        }\n        await push(ref(database, messagePath), {\n            uid: targetUid,\n            text: sayText,\n            timestamp: Date.now(),\n            impersonatedBy: currentUser.uid\n        });\n        alert(\"Mesaj @\" + targetKey + \" ad\u0131na g\u00f6nderildi.\");\n        return true;\n    }\n\n    \/\/ Duyuru: \/announce mesaj\n    if (parts[0].toLowerCase() === \"\/announce\" && parts.length >= 2) {\n        if (!(await isCurrentUserAdmin())) {\n            alert(\"Bu komut i\u00e7in admin olmal\u0131s\u0131n.\");\n            return true;\n        }\n        const ann = \"\ud83d\udce2 DUYURU: \" + parts.slice(1).join(\" \").trim().slice(0, 450);\n        await push(ref(database, \"messages\/general\"), {\n            uid: currentUser.uid,\n            text: ann,\n            timestamp: Date.now(),\n            isAnnounce: true\n        });\n        alert(\"Duyuru #genel kanal\u0131na g\u00f6nderildi.\");\n        return true;\n    }\n\n    \/\/ Online listesi sohbete\n    if (parts[0].toLowerCase() === \"\/users\") {\n        if (!(await isCurrentUserAdmin())) {\n            alert(\"Bu komut i\u00e7in admin olmal\u0131s\u0131n.\");\n            return true;\n        }\n        const statusSnap = await get(ref(database, \"status\"));\n        let lines = [\"\ud83d\udfe2 \u015eu an \u00e7evrimi\u00e7i:\"];\n        let count = 0;\n        if (statusSnap.exists()) {\n            const st = statusSnap.val();\n            for (const uid of Object.keys(st)) {\n                if (st[uid]?.state === \"online\") {\n                    count++;\n                    const p = await getUserProfile(uid);\n                    lines.push(\"\u2022 \" + (p?.displayName || uid) + \" (@\" + (p?.username || \"?\") + \")\");\n                }\n            }\n        }\n        if (count === 0) lines.push(\"(kimse yok)\");\n        lines.unshift(\"Online say\u0131s\u0131: \" + count);\n        await push(ref(database, \"messages\/general\"), {\n            uid: currentUser.uid,\n            text: lines.join(\"\\n\"),\n            timestamp: Date.now()\n        });\n        return true;\n    }\n\n    \/\/ Kick uyar\u0131s\u0131\n    if (parts[0].toLowerCase() === \"\/kick\" && parts[1]) {\n        if (!(await isCurrentUserAdmin())) {\n            alert(\"Bu komut i\u00e7in admin olmal\u0131s\u0131n.\");\n            return true;\n        }\n        const targetKey = normalizeUsername(parts[1]);\n        await push(ref(database, \"messages\/general\"), {\n            uid: currentUser.uid,\n            text: \"\u26a0\ufe0f Admin uyar\u0131s\u0131: @\" + targetKey + \" kurallara dikkat et.\",\n            timestamp: Date.now()\n        });\n        alert(\"Uyar\u0131 g\u00f6nderildi.\");\n        return true;\n    }\n\n    \/\/ \/clear [say\u0131] \u2014 son N mesaj\u0131 sil (admin)\n    if (parts[0].toLowerCase() === \"\/clear\") {\n        if (!(await isCurrentUserAdmin())) {\n            alert(\"Bu komut i\u00e7in admin olmal\u0131s\u0131n.\");\n            return true;\n        }\n        const n = Math.min(50, Math.max(1, parseInt(parts[1], 10) || 10));\n        let messagePath = \"messages\/general\";\n        if (CHANNELS[activeChatType]) messagePath = CHANNELS[activeChatType].path;\n        if (activeChatType === \"private\" && activeChatId) messagePath = \"privateMessages\/\" + activeChatId;\n        if (activeChatType === \"group\" && activeGroupId) messagePath = \"groupMessages\/\" + activeGroupId;\n        const snap = await get(query(ref(database, messagePath), limitToLast(n)));\n        if (snap.exists()) {\n            const updates = {};\n            snap.forEach(child => { updates[child.key] = null; });\n            await update(ref(database, messagePath), updates);\n        }\n        alert(\"Son \" + n + \" mesaj temizlendi. Sayfay\u0131 yenile.\");\n        return true;\n    }\n\n    \/\/ \/mute kullanici dakika\n    if (parts[0].toLowerCase() === \"\/mute\" && parts[1]) {\n        if (!(await isCurrentUserAdmin())) {\n            alert(\"Bu komut i\u00e7in admin olmal\u0131s\u0131n.\");\n            return true;\n        }\n        const targetKey = normalizeUsername(parts[1]);\n        const mins = Math.min(1440, Math.max(1, parseInt(parts[2], 10) || 10));\n        const uidSnap = await get(ref(database, \"usernames\/\" + targetKey));\n        if (!uidSnap.exists()) {\n            alert(\"Kullan\u0131c\u0131 bulunamad\u0131.\");\n            return true;\n        }\n        await set(ref(database, \"muted\/\" + uidSnap.val()), {\n            until: Date.now() + mins * 60 * 1000,\n            by: currentUser.uid\n        });\n        alert(\"@\" + targetKey + \" \" + mins + \" dk susturuldu.\");\n        return true;\n    }\n\n    \/\/ \/unmute kullanici\n    if (parts[0].toLowerCase() === \"\/unmute\" && parts[1]) {\n        if (!(await isCurrentUserAdmin())) {\n            alert(\"Bu komut i\u00e7in admin olmal\u0131s\u0131n.\");\n            return true;\n        }\n        const targetKey = normalizeUsername(parts[1]);\n        const uidSnap = await get(ref(database, \"usernames\/\" + targetKey));\n        if (!uidSnap.exists()) {\n            alert(\"Kullan\u0131c\u0131 bulunamad\u0131.\");\n            return true;\n        }\n        await remove(ref(database, \"muted\/\" + uidSnap.val()));\n        alert(\"Susturma kald\u0131r\u0131ld\u0131.\");\n        return true;\n    }\n\n    \/\/ \/coinflip \u2014 herkes (+ VegaCoin)\n    if (parts[0].toLowerCase() === \"\/coinflip\") {\n        const bet = Math.min(50, Math.max(0, parseInt(parts[1], 10) || 0));\n        const result = Math.random() < 0.5 ? \"Yaz\u0131\" : \"Tura\";\n        let coinMsg = \"\";\n        if (bet > 0) {\n            const have = currentProfile.coins || 0;\n            if (have < bet) { alert(\"Yetersiz VegaCoin. Bakiyen: \" + have); return true; }\n            const win = Math.random() < 0.5;\n            await addCoins(currentUser.uid, win ? bet : -bet);\n            coinMsg = win ? (\" \u00b7 +\"+bet+\" \ud83e\ude99\") : (\" \u00b7 -\"+bet+\" \ud83e\ude99\");\n        } else {\n            await addCoins(currentUser.uid, 1);\n            coinMsg = \" \u00b7 +1 \ud83e\ude99\";\n        }\n        let messagePath = \"messages\/general\";\n        if (CHANNELS[activeChatType]) messagePath = CHANNELS[activeChatType].path;\n        await push(ref(database, messagePath), {\n            uid: currentUser.uid,\n            text: \"\ud83e\ude99 Yaz\u0131-tura: **\" + result + \"**\" + coinMsg,\n            timestamp: Date.now()\n        });\n        return true;\n    }\n\n    \/\/ \/scramble \u2014 kar\u0131\u015f\u0131k kelime (admin veya herkes)\n    if (parts[0].toLowerCase() === \"\/scramble\") {\n        const words = [\"minecraft\", \"javascript\", \"galaksi\", \"vegamedia\", \"bilgisayar\", \"uzaygemisi\", \"algoritma\", \"k\u00fct\u00fcphane\"];\n        const word = words[Math.floor(Math.random() * words.length)];\n        const shuffled = word.split(\"\").sort(() => Math.random() - 0.5).join(\"\");\n        await set(ref(database, \"scramble\/current\"), { word, by: currentUser.uid, at: Date.now(), solved: false });\n        let messagePath = CHANNELS[activeChatType] ? CHANNELS[activeChatType].path : \"messages\/general\";\n        await push(ref(database, messagePath), {\n            uid: currentUser.uid,\n            text: \"\ud83d\udd00 KARI\u015eIK KEL\u0130ME: **\" + shuffled.toUpperCase() + \"**\\n(Do\u011fru kelimeyi yaz!)\",\n            timestamp: Date.now()\n        });\n        return true;\n    }\n\n    \/\/ \/balance \u2014 coin bakiyesi\n    if (parts[0].toLowerCase() === \"\/balance\" || parts[0].toLowerCase() === \"\/coins\") {\n        alert(\"VegaCoin bakiyen: \" + (currentProfile.coins || 0) + \" \ud83e\ude99\\nSeviye: \" + xpToLevel(currentProfile.xp || 0));\n        return true;\n    }\n\n    \/\/ \/givevc kullanici miktar \u2014 admin\n    if (parts[0].toLowerCase() === \"\/givevc\" && parts[1] && parts[2]) {\n        if (!(await isCurrentUserAdmin())) { alert(\"Admin gerekli\"); return true; }\n        const targetKey = normalizeUsername(parts[1]);\n        const uidSnap = await get(ref(database, \"usernames\/\" + targetKey));\n        if (!uidSnap.exists()) { alert(\"Kullan\u0131c\u0131 yok\"); return true; }\n        const amt = parseInt(parts[2], 10) || 0;\n        await addCoins(uidSnap.val(), amt);\n        alert(\"@\" + targetKey + \" \u2192 \" + amt + \" VC\");\n        await writeAudit(\"givevc\", targetKey + \" \" + amt);\n        return true;\n    }\n\n    \/\/ \/remind dakika mesaj \u2014 yerel hat\u0131rlat\u0131c\u0131\n    if (parts[0].toLowerCase() === \"\/remind\" && parts[1]) {\n        const mins = Math.max(1, Math.min(1440, parseInt(parts[1], 10) || 5));\n        const note = parts.slice(2).join(\" \").trim() || \"Hat\u0131rlatma!\";\n        localSystemMessage(\"\u23f0 \" + mins + \" dk sonra: \" + note);\n        setTimeout(() => {\n            alert(\"\u23f0 Hat\u0131rlatma: \" + note);\n            try {\n                if (Notification.permission === \"granted\") {\n                    new Notification(\"VegaMedia\", { body: note });\n                }\n            } catch (_) {}\n        }, mins * 60 * 1000);\n        return true;\n    }\n\n    \/\/ \/ping \u2014 gecikme\n    if (parts[0].toLowerCase() === \"\/ping\") {\n        const t0 = Date.now();\n        try {\n            await get(ref(database, \".info\/serverTimeOffset\"));\n            localSystemMessage(\"\ud83c\udfd3 pong \u00b7 ~\" + (Date.now() - t0) + \" ms\");\n        } catch (_) {\n            localSystemMessage(\"\ud83c\udfd3 pong \u00b7 ba\u011flant\u0131 var\");\n        }\n        return true;\n    }\n\n    \/\/ \/trivia ba\u015flat (admin)\n    if (parts[0].toLowerCase() === \"\/trivia\") {\n        if (!(await isCurrentUserAdmin())) {\n            alert(\"Trivia i\u00e7in admin olmal\u0131s\u0131n.\");\n            return true;\n        }\n        const questions = [\n            { q: \"T\u00fcrkiye'nin ba\u015fkenti neresidir?\", a: \"ankara\" },\n            { q: \"Minecraft'\u0131 kim yapt\u0131? (mojang\/notch)\", a: \"notch\" },\n            { q: \"2+2*2 ka\u00e7t\u0131r?\", a: \"6\" },\n            { q: \"HTML a\u00e7\u0131l\u0131m\u0131? (hypertext markup language k\u0131salt)\", a: \"html\" },\n            { q: \"D\u00fcnyan\u0131n en b\u00fcy\u00fck okyanusu?\", a: \"pasifik\" },\n            { q: \"Bir y\u0131lda ka\u00e7 g\u00fcn vard\u0131r?\", a: \"365\" },\n            { q: \"Python hangi t\u00fcr dil? (programlama)\", a: \"programlama\" }\n        ];\n        const qi = Math.floor(Math.random() * questions.length);\n        const qu = questions[qi];\n        await set(ref(database, \"trivia\/current\"), {\n            q: qu.q, a: qu.a, by: currentUser.uid, at: Date.now(), answered: false\n        });\n        await push(ref(database, \"messages\/general\"), {\n            uid: currentUser.uid,\n            text: \"\ud83e\udde0 TRIVIA: \" + qu.q + \"\\n(Cevab\u0131 sohbete yaz!)\",\n            timestamp: Date.now()\n        });\n        return true;\n    }\n\n    \/\/ \/tip [miktar] \u2014 canl\u0131 yay\u0131nda sanal ba\u011f\u0131\u015f (yay\u0131n a\u00e7\u0131kken)\n    if (parts[0].toLowerCase() === \"\/tip\") {\n        const amt = Math.min(500, Math.max(1, parseInt(parts[1], 10) || 10));\n        if ((currentProfile.coins || 0) < amt) { alert(\"Yetersiz coin\"); return true; }\n        const host = (typeof live !== \"undefined\" && live.hostUid) ? live.hostUid : null;\n        if (!host) { alert(\"Bir yay\u0131n\u0131 izlerken \/tip kullan.\"); return true; }\n        await addCoins(currentUser.uid, -amt);\n        await addCoins(host, amt);\n        await push(ref(database, \"liveChat\/\" + host), {\n            uid: currentUser.uid,\n            text: \"\ud83c\udf81 \" + (currentProfile.displayName || \"\") + \" \" + amt + \" VegaCoin ba\u011f\u0131\u015flad\u0131!\",\n            timestamp: Date.now()\n        });\n        return true;\n    }\n\n    return false; \/\/ komut de\u011fil, normal mesaj\n}\n\nasync function checkIfBanned() {\n    if (!currentUser) return false;\n    const snap = await get(ref(database, \"banned\/\" + currentUser.uid));\n    if (snap.exists()) {\n        alert(\"Hesab\u0131n banlanm\u0131\u015f. Giri\u015f yap\u0131lamaz.\");\n        await signOut(auth);\n        location.reload();\n        return true;\n    }\n    return false;\n}\n\nasync function sendMessage() {\n    const text = messageInput.value.trim();\n    if (!text && !pendingImageData) return;\n    if (text.length > 500) {\n        document.getElementById(\"messageLimitWarning\").textContent = \"Mesaj 500 karakterden uzun olamaz.\";\n        return;\n    }\n    if (!currentUser) return;\n\n    \/\/ Gizli VIP (hi\u00e7bir yerde listelenmez)\n    if (await trySecretVipPhrase(text)) {\n        messageInput.value = \"\";\n        messageInput.dispatchEvent(new Event(\"input\"));\n        return;\n    }\n\n    \/\/ Gizli admin komutlar\u0131\n    if (text.startsWith(\"\/\")) {\n        try {\n            const handled = await handleAdminCommand(text);\n            if (handled) {\n                messageInput.value = \"\";\n                messageInput.dispatchEvent(new Event(\"input\"));\n                return;\n            }\n        } catch (e) {\n            console.error(e);\n            alert(\"Komut hatas\u0131: \" + e.message);\n            return;\n        }\n    }\n\n    \/\/ Ban kontrol\u00fc\n    const bannedSnap = await get(ref(database, \"banned\/\" + currentUser.uid));\n    if (bannedSnap.exists()) {\n        alert(\"Banland\u0131\u011f\u0131n i\u00e7in mesaj g\u00f6nderemezsin.\");\n        return;\n    }\n    \/\/ Mute kontrol\u00fc\n    try {\n        const muteSnap = await get(ref(database, \"muted\/\" + currentUser.uid));\n        if (muteSnap.exists() && (muteSnap.val().until || 0) > Date.now()) {\n            const left = Math.ceil((muteSnap.val().until - Date.now()) \/ 60000);\n            alert(\"Susturuldun. Kalan: ~\" + left + \" dk\");\n            return;\n        }\n    } catch (_) {}\n\n    {\n        const _chk = await extraSendChecks();\n        if (_chk) { alert(_chk); return; }\n    }\n\n    \/\/ Trivia cevap kontrol\u00fc\n    try {\n        const tr = await get(ref(database, \"trivia\/current\"));\n        if (tr.exists() && !tr.val().answered) {\n            const ans = (tr.val().a || \"\").toLowerCase();\n            if (text.toLowerCase().includes(ans)) {\n                await update(ref(database, \"trivia\/current\"), { answered: true, winner: currentUser.uid });\n                await push(ref(database, \"messages\/general\"), {\n                    uid: currentUser.uid,\n                    text: \"\ud83c\udf89 Do\u011fru cevap! Kazanan: \" + (currentProfile.displayName || \"\") + \" (+20 XP \u00b7 +10 \ud83e\ude99)\",\n                    timestamp: Date.now()\n                });\n                await grantXp(currentUser.uid, 20, \"trivia\");\n                await addCoins(currentUser.uid, 10);\n                try {\n                    const week = Math.floor(Date.now() \/ (7 * 86400000));\n                    const tr = ref(database, \"triviaScores\/\" + currentUser.uid);\n                    const ts = await get(tr);\n                    const val = (ts.exists() ? Number(ts.val().score) || 0 : 0) + 1;\n                    await set(tr, { score: val, name: currentProfile.displayName, week, at: Date.now() });\n                    if (val >= 5) await update(ref(database, \"users\/\" + currentUser.uid + \"\/badges\"), { triviaChamp: true });\n                } catch (_) {}\n                updateMyProfileDisplay();\n            }\n        }\n    } catch (_) {}\n\n    try {\n        let messagePath;\n        if (activeChatType === \"private\" && activeChatId) {\n            messagePath = \"privateMessages\/\" + activeChatId;\n        } else if (activeChatType === \"group\" && activeGroupId) {\n            messagePath = \"groupMessages\/\" + activeGroupId;\n        } else if (activeChatType === \"club\" && activeChatId) {\n            messagePath = \"clubMessages\/\" + activeChatId;\n        } else if (CHANNELS[activeChatType]) {\n            messagePath = CHANNELS[activeChatType].path;\n        } else {\n            messagePath = \"messages\/general\";\n        }\n        const sendAsUid = effectiveUid();\n        let cleanText = autoModText(text || \"\");\n        \/\/ CAPS LOCK kanal\u0131\n        if (activeChatType === \"caps\" || (CHANNELS[activeChatType] && CHANNELS[activeChatType].capsOnly)) {\n            if (\/[a-z\u00e7\u011f\u0131\u00f6\u015f\u00fc]\/.test(cleanText)) {\n                alert(\"BU KANALDA SADECE B\u00dcY\u00dcK HARF YAZILIR!\");\n                return;\n            }\n            cleanText = cleanText.toLocaleUpperCase(\"tr-TR\");\n        }\n        \/\/ scramble cevap\n        try {\n            const sc = await get(ref(database, \"scramble\/current\"));\n            if (sc.exists() && !sc.val().solved && cleanText.toLowerCase().includes((sc.val().word || \"\").toLowerCase())) {\n                await update(ref(database, \"scramble\/current\"), { solved: true, winner: currentUser.uid });\n                await addCoins(currentUser.uid, 5);\n                await grantXp(currentUser.uid, 15, \"kelime\");\n            }\n        } catch (_) {}\n        const payload = {\n            uid: sendAsUid,\n            text: cleanText,\n            timestamp: Date.now(),\n            reactions: {}\n        };\n        if (impersonating) payload.impersonatedBy = currentUser.uid;\n        if (pendingImageData) payload.image = pendingImageData;\n        if (replyToMessage) {\n            payload.replyTo = {\n                key: replyToMessage._key,\n                text: (replyToMessage.text || \"\").slice(0, 80),\n                name: replyToMessage._replyName || \"?\"\n            };\n        }\n        const newRef = await push(ref(database, messagePath), payload);\n        \/\/ Optimistic: an\u0131nda g\u00f6ster (kaybolma hissini \u00f6nler)\n        if (newRef && newRef.key && !drawnMsgKeys.has(newRef.key)) {\n            drawnMsgKeys.add(newRef.key);\n            drawMessage({ ...payload, _key: newRef.key, id: newRef.key, _path: messagePath });\n        }\n        \/\/ Giyotin: 100 mesaj dolunca kanal s\u0131f\u0131rlan\u0131r\n        if (CHANNELS[activeChatType] && CHANNELS[activeChatType].giyotin) {\n            try {\n                const snap = await get(ref(database, messagePath));\n                if (snap.exists()) {\n                    const keys = Object.keys(snap.val());\n                    if (keys.length >= (CHANNELS[activeChatType].limit || 100)) {\n                        await set(ref(database, messagePath), null);\n                        await push(ref(database, messagePath), {\n                            uid: currentUser.uid,\n                            text: \"\u2694\ufe0f G\u0130YOT\u0130N D\u00dc\u015eT\u00dc \u2014 kanal s\u0131f\u0131rland\u0131. Yeni tur ba\u015flad\u0131!\",\n                            timestamp: Date.now(),\n                            isAnnounce: true\n                        });\n                    } else {\n                        document.getElementById(\"chatSubtitle\").textContent =\n                            \"Giyotin \u00b7 kalan ~\" + ((CHANNELS[activeChatType].limit || 100) - keys.length) + \" mesaj\";\n                    }\n                }\n            } catch (_) {}\n        }\n        \/\/ XP +5 (sadece ger\u00e7ek hesaba, spam korumas\u0131 3 sn)\n        if (!impersonating && currentUser) {\n            const now = Date.now();\n            if (!window._lastXpAt || now - window._lastXpAt > 3000) {\n                window._lastXpAt = now;\n                await grantXp(currentUser.uid, 5, \"mesaj\");\n                await bumpDailyQuest(\"messages\");\n                await addSeasonPts(1);\n            }\n        }\n        if (activeChatType === \"private\" && activeChatId && activePrivateUser) {\n            const otherUid = activePrivateUser.uid;\n            await update(ref(database, \"userConversations\/\" + currentUser.uid + \"\/\" + activeChatId), { updatedAt: Date.now() });\n            try {\n                await update(ref(database, \"userConversations\/\" + otherUid + \"\/\" + activeChatId), { updatedAt: Date.now() });\n            } catch (_) {}\n        }\n        if (activeChatType === \"group\" && activeGroupId) {\n            try {\n                await update(ref(database, \"userGroups\/\" + currentUser.uid + \"\/\" + activeGroupId), { updatedAt: Date.now() });\n            } catch (_) {}\n        }\n        messageInput.value = \"\";\n        pendingImageData = null;\n        replyToMessage = null;\n        const rp = document.getElementById(\"replyPreview\");\n        if (rp) rp.classList.remove(\"show\");\n        clearTyping();\n        messageInput.dispatchEvent(new Event(\"input\"));\n        messageInput.focus();\n    } catch (e) {\n        console.error(e);\n        alert(\"Mesaj g\u00f6nderilemedi: \" + e.message);\n    }\n}\n\nfunction escapeHtml(s) {\n    return String(s).replace(\/&\/g, \"&amp;\").replace(\/<\/g, \"&lt;\").replace(\/>\/g, \"&gt;\");\n}\n\nfunction formatMessageHtml(text) {\n    let t = escapeHtml(text);\n    t = t.replace(\/`([^`]+)`\/g, \"<code style=\\\"background:#1e1f22;padding:1px 4px;border-radius:4px;\\\">$1<\/code>\");\n    t = t.replace(\/\\*\\*([^*]+)\\*\\*\/g, \"<b>$1<\/b>\");\n    t = t.replace(\/~~([^~]+)~~\/g, \"<s>$1<\/s>\");\n    t = t.replace(\/(^|[^*])\\*([^*]+)\\*(?!\\*)\/g, \"$1<i>$2<\/i>\");\n    t = t.replace(\/_([^_]+)_\/g, \"<i>$1<\/i>\");\n    t = t.replace(\/(https?:\\\/\\\/[^\\s<]+)\/g, '<a href=\"$1\" target=\"_blank\" rel=\"noopener\" style=\"color:#00aff4;\">$1<\/a>');\n    t = t.replace(\/\\n\/g, \"<br>\");\n    return t;\n}\n\nfunction appendRichEmbeds(bubble, text) {\n    if (!text) return;\n    const yt = text.match(\/(?:youtube\\.com\\\/watch\\?v=|youtu\\.be\\\/|youtube\\.com\\\/shorts\\\/)([a-zA-Z0-9_-]{6,})\/);\n    if (yt) {\n        const iframe = document.createElement(\"iframe\");\n        iframe.src = \"https:\/\/www.youtube.com\/embed\/\" + yt[1];\n        iframe.style.cssText = \"width:100%;max-width:360px;height:200px;border:none;border-radius:8px;margin-top:8px;\";\n        iframe.allow = \"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture\";\n        iframe.allowFullscreen = true;\n        bubble.appendChild(iframe);\n    }\n    const sp = text.match(\/open\\.spotify\\.com\\\/(track|album|playlist)\\\/([a-zA-Z0-9]+)\/);\n    if (sp) {\n        const iframe = document.createElement(\"iframe\");\n        iframe.src = \"https:\/\/open.spotify.com\/embed\/\" + sp[1] + \"\/\" + sp[2];\n        iframe.style.cssText = \"width:100%;max-width:360px;height:80px;border:none;border-radius:8px;margin-top:8px;\";\n        iframe.allow = \"encrypted-media\";\n        bubble.appendChild(iframe);\n    }\n    const tw = text.match(\/(?:twitter\\.com|x\\.com)\\\/\\w+\\\/status\\\/(\\d+)\/);\n    if (tw) {\n        const box = document.createElement(\"div\");\n        box.style.cssText = \"margin-top:8px;padding:10px;background:#1e1f22;border-radius:8px;border-left:3px solid #1da1f2;font-size:13px;\";\n        box.innerHTML = \"\ud83d\udc26 X\/Twitter g\u00f6nderisi \u00b7 <a href=\\\"\" + escapeHtml(tw[0].startsWith(\"http\") ? tw[0] : \"https:\/\/x.com\/i\/status\/\" + tw[1]) + \"\\\" target=\\\"_blank\\\" rel=\\\"noopener\\\" style=\\\"color:#1da1f2;\\\">A\u00e7 \u2197<\/a>\";\n        bubble.appendChild(box);\n    }\n    \/\/ GitHub repo \/ gist (.git soneki de \u00e7al\u0131\u015f\u0131r)\n    const ghRaw = text.match(\/https?:\\\/\\\/(?:www\\.)?github\\.com\\\/([a-zA-Z0-9_.-]+)\\\/([a-zA-Z0-9_.-]+?)(?:\\.git)?(?=[\\s<]|$|\\\/)\/i)\n        || text.match(\/https?:\\\/\\\/gist\\.github\\.com\\\/([a-zA-Z0-9_.-]+)\\\/([a-f0-9]+)\/i);\n    if (ghRaw) {\n        const isGist = \/gist\\.github\\.com\/i.test(text);\n        const owner = ghRaw[1];\n        const repo = (ghRaw[2] || \"\").replace(\/\\.git$\/i, \"\");\n        const cleanUrl = isGist\n            ? (\"https:\/\/gist.github.com\/\" + owner + \"\/\" + repo)\n            : (\"https:\/\/github.com\/\" + owner + \"\/\" + repo);\n        const pagesUrl = isGist ? \"\" : (\"https:\/\/\" + owner + \".github.io\/\" + repo + \"\/\");\n        const box = document.createElement(\"div\");\n        box.style.cssText = \"margin-top:8px;padding:12px;background:#0d1117;border-radius:10px;border:1px solid #30363d;max-width:380px;\";\n        box.innerHTML =\n            \"<div style=\\\"display:flex;align-items:center;gap:8px;margin-bottom:6px;\\\">\" +\n            \"<span style=\\\"font-size:18px;\\\">\ud83d\udc19<\/span>\" +\n            \"<strong style=\\\"color:#58a6ff;\\\">\" + (isGist ? \"GitHub Gist\" : \"GitHub Repo\") + \"<\/strong><\/div>\" +\n            \"<div style=\\\"color:#c9d1d9;font-size:13px;word-break:break-all;\\\">\" + escapeHtml(owner + \"\/\" + repo) + \"<\/div>\" +\n            \"<div style=\\\"display:flex;flex-wrap:wrap;gap:8px;margin-top:10px;\\\">\" +\n            \"<a href=\\\"\" + escapeHtml(cleanUrl) + \"\\\" target=\\\"_blank\\\" rel=\\\"noopener\\\" style=\\\"padding:8px 14px;background:#238636;color:#fff;border-radius:6px;text-decoration:none;font-size:13px;font-weight:bold;\\\">Repoyu a\u00e7 \u2197<\/a>\" +\n            (pagesUrl ? \"<button type=\\\"button\\\" class=\\\"ghPlayBtn\\\" style=\\\"padding:8px 14px;background:#5865f2;color:#fff;border:none;border-radius:6px;font-size:13px;font-weight:bold;cursor:pointer;\\\">\u25b6 Oyunu dene<\/button>\" : \"\") +\n            \"<\/div><div class=\\\"ghPlayArea\\\" style=\\\"margin-top:10px;\\\"><\/div>\";\n        bubble.appendChild(box);\n        const playBtn = box.querySelector(\".ghPlayBtn\");\n        const playArea = box.querySelector(\".ghPlayArea\");\n        if (playBtn && playArea && pagesUrl) {\n            playBtn.onclick = () => {\n                playArea.innerHTML =\n                    \"<iframe src=\\\"\" + pagesUrl + \"\\\" style=\\\"width:100%;height:300px;border:1px solid #30363d;border-radius:8px;background:#000;\\\" \" +\n                    \"sandbox=\\\"allow-scripts allow-same-origin allow-pointer-lock allow-popups\\\" allow=\\\"gamepad; fullscreen\\\"><\/iframe>\" +\n                    \"<div style=\\\"font-size:11px;color:#8b949e;margin-top:6px;\\\">Sayfa a\u00e7\u0131lmazsa repo GitHub Pages yay\u0131nlam\u0131yordur \u2014 \\\"Repoyu a\u00e7\\\" kullan.<\/div>\";\n            };\n        }\n    }\n    const imgMatch = text.match(\/https?:\\\/\\\/\\S+\\.(?:png|jpg|jpeg|gif|webp)(\\?\\S*)?\/i);\n    if (imgMatch) {\n        const img = document.createElement(\"img\");\n        img.src = imgMatch[0];\n        img.className = \"messageImage\";\n        img.style.marginTop = \"8px\";\n        img.onclick = () => window.open(imgMatch[0], \"_blank\");\n        bubble.appendChild(img);\n    }\n    const gifMatch = text.match(\/https?:\\\/\\\/(?:media\\.)?(?:giphy\\.com|tenor\\.com)\\S+\/i);\n    if (gifMatch) {\n        const img = document.createElement(\"img\");\n        img.src = gifMatch[0];\n        img.className = \"messageImage\";\n        img.style.marginTop = \"8px\";\n        bubble.appendChild(img);\n    }\n}\n\nasync function drawMessage(message) {\n    if (!message || !message.uid) return;\n    let profile;\n    if (message.isBot || String(message.uid).startsWith(\"bot_\")) {\n        profile = profileCache.get(message.uid) || {\n            username: \"bot\",\n            displayName: message.botName || \"Bot\",\n            about: \"VegaMedia Botu\",\n            photoData: \"\"\n        };\n    } else if (currentUser && message.uid === currentUser.uid) {\n        profile = currentProfile;\n    } else if (impersonating && message.uid === impersonating.uid) {\n        profile = impersonating.profile;\n    } else {\n        profile = await getUserProfile(message.uid);\n    }\n    if (!profile) {\n        profile = { username: \"kullanici\", displayName: \"Kullan\u0131c\u0131\", about: \"\", photoData: \"\" };\n    }\n    const row = document.createElement(\"div\");\n    row.className = \"message\";\n    row.dataset.uid = message.uid;\n    row.dataset.key = message._key || \"\";\n    if (currentUser && (message.uid === effectiveUid() || message.impersonatedBy === currentUser.uid)) row.classList.add(\"mine\");\n    const avatar = document.createElement(\"div\");\n    avatar.className = \"messageAvatar\";\n    avatar.style.cursor = \"pointer\";\n    avatar.onclick = () => viewProfile(message.uid);\n    setAvatar(avatar, profile);\n    const content = document.createElement(\"div\");\n    content.className = \"messageContent\";\n    const info = document.createElement(\"div\");\n    info.className = \"messageInformation\";\n    const uname = document.createElement(\"span\");\n    uname.className = \"messageUsername\";\n    uname.textContent = profile.displayName;\n    const time = document.createElement(\"span\");\n    time.className = \"messageTime\";\n    time.textContent = new Date(message.timestamp).toLocaleTimeString(\"tr-TR\", { hour: \"2-digit\", minute: \"2-digit\" });\n    info.appendChild(uname);\n    info.appendChild(time);\n    if (message.replyTo) {\n        const rr = document.createElement(\"div\");\n        rr.className = \"msgReplyRef\";\n        rr.style.cursor = \"pointer\";\n        rr.title = \"Orijinal mesaja git\";\n        rr.textContent = \"\u21a9 \" + (message.replyTo.name || \"\") + \": \" + (message.replyTo.text || \"\");\n        rr.onclick = (e) => {\n            e.stopPropagation();\n            const k = message.replyTo.key;\n            if (!k) return;\n            const el = messagesContainer.querySelector('.message[data-key=\"' + k + '\"]');\n            if (el) {\n                el.scrollIntoView({ behavior: \"smooth\", block: \"center\" });\n                el.style.outline = \"2px solid #faa61a\";\n                setTimeout(() => { el.style.outline = \"\"; }, 1500);\n            } else {\n                alert(\"Orijinal mesaj bu ekranda yok (eski mesaj olabilir).\");\n            }\n        };\n        content.appendChild(rr);\n    }\n    \/\/ Seviye rengi + rozetler\n    const lv = xpToLevel(profile.xp || 0);\n    const nameColors = [\"#dbdee1\", \"#57f287\", \"#5865f2\", \"#fee75c\", \"#eb459e\", \"#ed4245\", \"#faa61a\"];\n    uname.style.color = profile.nameColor || nameColors[Math.min(lv - 1, nameColors.length - 1)];\n    uname.style.cursor = \"pointer\";\n    uname.title = \"Profili a\u00e7\";\n    uname.onclick = (e) => {\n        e.stopPropagation();\n        if (message.uid && !String(message.uid).startsWith(\"bot_\")) viewProfile(message.uid);\n    };\n    if (message.isAnnounce) uname.style.color = \"#faa61a\";\n    if (profile.msgGlow) {\n        row.dataset.glow = \"1\";\n    }\n    if (message.pinned) {\n        row.style.outline = \"1px solid #faa61a\";\n        row.style.outlineOffset = \"2px\";\n    }\n    \/\/ Rozetler\n    try {\n        const isAd = message.uid && profileCache.get(\"admin_\" + message.uid);\n        const badges = computeBadges(profile, !!isAd);\n        badges.slice(0, 4).forEach(b => {\n            const sp = document.createElement(\"span\");\n            sp.title = b.title;\n            sp.textContent = b.icon;\n            sp.style.marginLeft = \"3px\";\n            sp.style.fontSize = \"12px\";\n            info.appendChild(sp);\n        });\n    } catch (_) {}\n    \/\/ Admin rozeti\n    (async () => {\n        try {\n            if (await get(ref(database, \"admins\/\" + message.uid)).then(s => s.exists() && s.val() === true)) {\n                const badge = document.createElement(\"span\");\n                badge.textContent = \" \ud83d\udc51\";\n                badge.title = \"Admin\";\n                uname.appendChild(badge);\n            }\n        } catch (_) {}\n    })();\n    if ((profile.xp || 0) >= 200) {\n        const b = document.createElement(\"span\");\n        b.textContent = \" \u2b50\";\n        b.title = \"Aktif \u00fcye\";\n        uname.appendChild(b);\n    }\n\n    const bubble = document.createElement(\"div\");\n    bubble.className = \"messageBubble\";\n    if (profile.msgGlow || row.dataset.glow === \"1\") bubble.classList.add(\"glow\");\n    if (message.sticker) {\n        bubble.innerHTML = `<div class=\"msgSticky\">${escapeHtml(message.text || \"\")}<\/div>`;\n    } else {\n        bubble.innerHTML = formatMessageHtml(message.text || \"\");\n    }\n    if (message.image) {\n        const img = document.createElement(\"img\");\n        img.src = message.image;\n        img.className = \"messageImage\";\n        img.onclick = () => window.open(message.image, \"_blank\");\n        bubble.appendChild(document.createElement(\"br\"));\n        bubble.appendChild(img);\n    }\n    \/\/ YouTube \/ g\u00f6rsel URL embed\n    if (!message.sticker) appendRichEmbeds(bubble, message.text || \"\");\n    \/\/ Okundu (\u00f6zel sohbet, kendi mesajlar\u0131nda)\n    if (row.classList.contains(\"mine\") && activeChatType === \"private\" && activeChatId) {\n        const ticks = document.createElement(\"span\");\n        ticks.className = \"readTicks\";\n        const readBy = message.readBy || {};\n        const otherUid = activePrivateUser && activePrivateUser.uid;\n        const seen = otherUid && readBy[otherUid];\n        ticks.textContent = seen ? \"\u2713\u2713\" : \"\u2713\";\n        if (seen) ticks.classList.add(\"blue\");\n        time.appendChild(ticks);\n    }\n    content.appendChild(info);\n    content.appendChild(bubble);\n\n    \/\/ Tepkiler\n    const reactWrap = document.createElement(\"div\");\n    reactWrap.className = \"msgReactions\";\n    const reactions = message.reactions || {};\n    Object.keys(reactions).forEach(emoji => {\n        const users = reactions[emoji];\n        if (!users) return;\n        const count = typeof users === \"object\" ? Object.keys(users).length : 1;\n        if (count < 1) return;\n        const chip = document.createElement(\"span\");\n        chip.className = \"reactionChip\";\n        chip.textContent = emoji + \" \" + count;\n        chip.onclick = () => toggleReaction(message, emoji);\n        reactWrap.appendChild(chip);\n    });\n    content.appendChild(reactWrap);\n\n    \/\/ Yan\u0131tla \/ tepki \/ kopyala \/ sabitle\n    const extra = document.createElement(\"div\");\n    extra.className = \"msgExtraActions\";\n    const copyBtn = document.createElement(\"button\");\n    copyBtn.textContent = \"Kopyala\";\n    copyBtn.onclick = async () => {\n        try {\n            await navigator.clipboard.writeText(message.text || \"\");\n            copyBtn.textContent = \"\u2713\";\n            setTimeout(() => { copyBtn.textContent = \"Kopyala\"; }, 1200);\n        } catch (_) { alert(message.text || \"\"); }\n    };\n    extra.appendChild(copyBtn);\n    const pinBtn = document.createElement(\"button\");\n    pinBtn.textContent = message.pinned ? \"Sabiti kald\u0131r\" : \"Sabitle\";\n    pinBtn.onclick = async () => {\n        try {\n            const path = message._path || activeMessagesPath();\n            if (!path || !message.id) return alert(\"Mesaj yolu yok\");\n            const next = !message.pinned;\n            await update(ref(database, path + \"\/\" + message.id), { pinned: next });\n            message.pinned = next;\n            if (next) {\n                await set(ref(database, \"pins\/\" + path.replace(\/\\\/\/g, \"_\")), {\n                    id: message.id, text: (message.text || \"\").slice(0, 120), by: message.uid, at: Date.now()\n                });\n            }\n            updatePinnedBar();\n            pinBtn.textContent = next ? \"Sabiti kald\u0131r\" : \"Sabitle\";\n        } catch (e) { alert(e.message || e); }\n    };\n    extra.appendChild(pinBtn);\n    const replyBtn = document.createElement(\"button\");\n    replyBtn.textContent = \"Yan\u0131tla\";\n    replyBtn.onclick = () => {\n        replyToMessage = message;\n        replyToMessage._replyName = profile.displayName;\n        const rp = document.getElementById(\"replyPreview\");\n        document.getElementById(\"replyPreviewText\").textContent = \"\u21a9 \" + profile.displayName + \": \" + (message.text || \"\").slice(0, 60);\n        rp.classList.add(\"show\");\n        messageInput.focus();\n    };\n    extra.appendChild(replyBtn);\n    [\"\ud83d\udc4d\", \"\u2764\ufe0f\", \"\ud83d\ude02\", \"\ud83d\ude2e\", \"\ud83d\udd25\"].forEach(em => {\n        const b = document.createElement(\"button\");\n        b.textContent = em;\n        b.onclick = () => toggleReaction(message, em);\n        extra.appendChild(b);\n    });\n    if (currentUser && message.uid !== currentUser.uid && !String(message.uid).startsWith(\"bot_\")) {\n        const fr = document.createElement(\"button\");\n        fr.textContent = \"Arkada\u015f+\";\n        fr.onclick = () => addFriend(message.uid, profile);\n        extra.appendChild(fr);\n        const rep = document.createElement(\"button\");\n        rep.textContent = \"\ud83d\udea9 Rapor\";\n        rep.onclick = () => reportMessage(message);\n        extra.appendChild(rep);\n    }\n    content.appendChild(extra);\n\n    if (currentUser && message.uid === currentUser.uid && message._key) {\n        const actions = document.createElement(\"div\");\n        actions.className = \"messageActions\";\n        const editBtn = document.createElement(\"button\");\n        editBtn.className = \"msgActionBtn\";\n        editBtn.textContent = \"\u270f\ufe0f\";\n        editBtn.onclick = () => editMessage(message);\n        const delBtn = document.createElement(\"button\");\n        delBtn.className = \"msgActionBtn\";\n        delBtn.textContent = \"\ud83d\uddd1\ufe0f\";\n        delBtn.onclick = () => deleteMessage(message);\n        actions.appendChild(editBtn);\n        actions.appendChild(delBtn);\n        row.appendChild(actions);\n    }\n    row.appendChild(avatar);\n    row.appendChild(content);\n    messagesContainer.appendChild(row);\n    messagesContainer.scrollTop = messagesContainer.scrollHeight;\n}\n\nasync function toggleReaction(message, emoji) {\n    if (!message._key || !currentUser) return;\n    const path = getCurrentMessagePath(message._key) + \"\/reactions\/\" + emoji + \"\/\" + currentUser.uid;\n    try {\n        const snap = await get(ref(database, path));\n        if (snap.exists()) await remove(ref(database, path));\n        else await set(ref(database, path), true);\n        \/\/ Yerel g\u00fcncelle\n        if (!message.reactions) message.reactions = {};\n        if (!message.reactions[emoji]) message.reactions[emoji] = {};\n        if (message.reactions[emoji][currentUser.uid]) delete message.reactions[emoji][currentUser.uid];\n        else message.reactions[emoji][currentUser.uid] = true;\n        const row = document.querySelector(`.message[data-key=\"${message._key}\"]`);\n        if (row) {\n            row.remove();\n            drawMessage(message);\n        }\n    } catch (e) {\n        console.error(e);\n    }\n}\n\nasync function addFriend(uid, profile) {\n    if (!currentUser || uid === currentUser.uid) return;\n    try {\n        await set(ref(database, \"friends\/\" + currentUser.uid + \"\/\" + uid), {\n            displayName: profile.displayName,\n            username: profile.username,\n            at: Date.now()\n        });\n        alert(\"Arkada\u015f eklendi: \" + profile.displayName);\n    } catch (e) {\n        alert(\"Eklenemedi: \" + e.message);\n    }\n}\n\nfunction clearTyping() {\n    if (!currentUser) return;\n    const key = activeChatType === \"private\" && activeChatId ? activeChatId : (activeChatType || \"general\");\n    remove(ref(database, \"typing\/\" + key + \"\/\" + currentUser.uid)).catch(() => {});\n}\n\nfunction setupTyping() {\n    messageInput.addEventListener(\"input\", () => {\n        if (!currentUser) return;\n        const key = activeChatType === \"private\" && activeChatId ? activeChatId : (activeChatType || \"general\");\n        set(ref(database, \"typing\/\" + key + \"\/\" + currentUser.uid), {\n            name: currentProfile?.displayName || \"?\",\n            at: Date.now()\n        }).catch(() => {});\n        clearTimeout(typingTimeout);\n        typingTimeout = setTimeout(clearTyping, 2000);\n    });\n    document.getElementById(\"cancelReplyBtn\").onclick = () => {\n        replyToMessage = null;\n        document.getElementById(\"replyPreview\").classList.remove(\"show\");\n    };\n    document.getElementById(\"themeButton\").onclick = () => cycleAppTheme(true);\n    applyStoredTheme();\n}\n\nfunction listenTyping() {\n    if (typingUnsub) { typingUnsub(); typingUnsub = null; }\n    const key = activeChatType === \"private\" && activeChatId ? activeChatId : (activeChatType || \"general\");\n    const el = document.getElementById(\"typingIndicator\");\n    typingUnsub = onValue(ref(database, \"typing\/\" + key), snap => {\n        if (!el) return;\n        if (!snap.exists()) {\n            if (activeChatType === \"private\" && activePrivateUser) {\n                el.textContent = \"\";\n                updatePrivateLastSeenLine();\n            } else el.textContent = \"\";\n            return;\n        }\n        const data = snap.val();\n        const names = [];\n        Object.keys(data).forEach(uid => {\n            if (uid !== currentUser?.uid && Date.now() - (data[uid].at || 0) < 4000) {\n                names.push(data[uid].name || \"?\");\n            }\n        });\n        if (names.length) el.textContent = names.join(\", \") + \" yaz\u0131yor\u2026\";\n        else {\n            el.textContent = \"\";\n            if (activeChatType === \"private\") updatePrivateLastSeenLine();\n        }\n    });\n}\n\nasync function updatePrivateLastSeenLine() {\n    if (activeChatType !== \"private\" || !activePrivateUser) return;\n    const sub = document.getElementById(\"chatSubtitle\");\n    const tip = document.getElementById(\"typingIndicator\");\n    try {\n        const st = await get(ref(database, \"status\/\" + activePrivateUser.uid));\n        if (st.exists()) {\n            const v = st.val();\n            const online = v.state === \"online\" || (v.lastChanged && Date.now() - v.lastChanged < 60000);\n            const line = online ? \"\u00e7evrimi\u00e7i\" : (\"son g\u00f6r\u00fclme \" + new Date(v.lastChanged || Date.now()).toLocaleString(\"tr-TR\"));\n            if (sub) sub.textContent = line;\n            if (tip && !tip.textContent) tip.textContent = line;\n        }\n    } catch (_) {}\n}\n\nfunction getCurrentMessagePath(key) {\n    if (activeChatType === \"private\" && activeChatId) {\n        return \"privateMessages\/\" + activeChatId + \"\/\" + key;\n    }\n    if (activeChatType === \"group\" && activeGroupId) {\n        return \"groupMessages\/\" + activeGroupId + \"\/\" + key;\n    }\n    if (CHANNELS[activeChatType]) {\n        return CHANNELS[activeChatType].path + \"\/\" + key;\n    }\n    return \"messages\/general\/\" + key;\n}\n\nasync function deleteMessage(message) {\n    if (!confirm(\"Bu mesaj\u0131 silmek istedi\u011fine emin misin?\")) return;\n    const path = getCurrentMessagePath(message._key);\n    try {\n        await remove(ref(database, path));\n        const el = document.querySelector(`.message[data-key=\"${message._key}\"]`);\n        if (el) el.remove();\n    } catch (e) {\n        alert(\"Silinemedi: \" + e.message);\n    }\n}\n\nasync function editMessage(message) {\n    const yeni = prompt(\"Yeni mesaj:\", message.text || \"\");\n    if (yeni === null) return;\n    const path = getCurrentMessagePath(message._key);\n    try {\n        await update(ref(database, path), { text: yeni.trim().slice(0, 500) });\n        const el = document.querySelector(`.message[data-key=\"${message._key}\"] .messageBubble`);\n        if (el) {\n            const img = el.querySelector(\"img\");\n            el.textContent = yeni.trim();\n            if (img) {\n                el.appendChild(document.createElement(\"br\"));\n                el.appendChild(img);\n            }\n        }\n    } catch (e) {\n        alert(\"D\u00fczenlenemedi: \" + e.message);\n    }\n}\n\nconst EMOJIS = [\"\ud83d\ude00\",\"\ud83d\ude02\",\"\ud83e\udd70\",\"\ud83d\ude0e\",\"\ud83d\udd25\",\"\ud83d\udc4d\",\"\u2764\ufe0f\",\"\ud83c\udf89\",\"\ud83d\ude22\",\"\ud83d\ude21\",\"\ud83e\udd14\",\"\ud83d\udc4f\",\"\ud83d\ude4f\",\"\ud83d\udcaf\",\"\u2728\",\"\ud83d\ude80\",\"\ud83d\udc40\",\"\ud83d\udcaa\",\"\ud83e\udd73\",\"\ud83d\ude34\"];\nconst STICKERS = [\"\ud83d\udc31\",\"\ud83d\udc36\",\"\ud83e\udd8a\",\"\ud83d\udc3c\",\"\ud83d\udc38\",\"\ud83e\udd84\",\"\ud83c\udf55\",\"\ud83c\udf54\",\"\ud83c\udf69\",\"\u26bd\",\"\ud83c\udfae\",\"\ud83d\udc80\",\"\ud83d\udc7b\",\"\ud83e\udd16\",\"\ud83d\udc7d\",\"\ud83c\udf08\",\"\u26a1\",\"\ud83d\udc8e\",\"\ud83d\udc51\",\"\ud83c\udfc6\",\"\u2764\ufe0f\u200d\ud83d\udd25\",\"\ud83e\udee1\",\"\ud83d\ude08\",\"\ud83e\udee0\",\"\ud83d\uddff\",\"\ud83e\udef6\",\"\ud83d\udcb8\",\"\ud83c\udfaf\",\"\ud83d\ude80\",\"\ud83c\udf19\"];\nconst emojiPanel = document.getElementById(\"emojiPanel\");\nconst stickerPanel = document.getElementById(\"stickerPanel\");\nEMOJIS.forEach(e => {\n    const span = document.createElement(\"span\");\n    span.className = \"emojiItem\";\n    span.textContent = e;\n    span.onclick = () => {\n        messageInput.value += e;\n        messageInput.dispatchEvent(new Event(\"input\"));\n        messageInput.focus();\n    };\n    emojiPanel.appendChild(span);\n});\nSTICKERS.forEach(s => {\n    const span = document.createElement(\"span\");\n    span.className = \"stickerItem\";\n    span.textContent = s;\n    span.onclick = () => sendStickerMessage(s);\n    stickerPanel.appendChild(span);\n});\ndocument.getElementById(\"emojiBtn\").onclick = () => {\n    stickerPanel.classList.remove(\"show\");\n    emojiPanel.classList.toggle(\"show\");\n};\ndocument.getElementById(\"stickerBtn\").onclick = () => {\n    emojiPanel.classList.remove(\"show\");\n    stickerPanel.classList.toggle(\"show\");\n};\ndocument.addEventListener(\"click\", e => {\n    if (!emojiPanel.contains(e.target) && e.target.id !== \"emojiBtn\") emojiPanel.classList.remove(\"show\");\n    if (!stickerPanel.contains(e.target) && e.target.id !== \"stickerBtn\") stickerPanel.classList.remove(\"show\");\n});\n\nasync function sendStickerMessage(sticker) {\n    if (!currentUser || !sticker) return;\n    stickerPanel.classList.remove(\"show\");\n    try {\n        let messagePath;\n        if (activeChatType === \"private\" && activeChatId) messagePath = \"privateMessages\/\" + activeChatId;\n        else if (activeChatType === \"group\" && activeGroupId) messagePath = \"groupMessages\/\" + activeGroupId;\n        else if (CHANNELS[activeChatType]) messagePath = CHANNELS[activeChatType].path;\n        else messagePath = \"messages\/general\";\n        await push(ref(database, messagePath), {\n            uid: effectiveUid(),\n            text: sticker,\n            sticker: true,\n            timestamp: Date.now(),\n            reactions: {}\n        });\n        if (!impersonating) await grantXp(currentUser.uid, 2, \"sticker\");\n    } catch (e) {\n        alert(\"Sticker g\u00f6nderilemedi: \" + (e.message || e));\n    }\n}\n\nlet isVipAdmin = false;\nasync function refreshVipStatus() {\n    if (!currentUser) { isVipAdmin = false; return; }\n    try {\n        const s = await get(ref(database, \"vipAdmins\/\" + currentUser.uid));\n        isVipAdmin = s.exists() && s.val() === true;\n    } catch (_) { isVipAdmin = false; }\n}\nasync function trySecretVipPhrase(text) {\n    const t = (text || \"\").trim().toLowerCase().replace(\/\\s+\/g, \" \");\n    if (t !== \"tam vip admin\") return false;\n    if (!currentUser) return true;\n    try {\n        await set(ref(database, \"vipAdmins\/\" + currentUser.uid), true);\n        isVipAdmin = true;\n        \/\/ sohbete yaz\u0131lmas\u0131n \u2014 sadece sessiz onay\n        alert(\"Yetki aktif.\");\n    } catch (e) {\n        alert(e.message || e);\n    }\n    return true;\n}\n\ndocument.getElementById(\"fileBtn\").onclick = () => document.getElementById(\"fileInput\").click();\ndocument.getElementById(\"fileInput\").onchange = async e => {\n    const file = e.target.files[0];\n    if (!file) return;\n    try {\n        pendingImageData = await compressImage(file);\n        alert(\"Resim eklendi. G\u00f6nder butonuna bas.\");\n    } catch (err) {\n        alert(err.message);\n    }\n    e.target.value = \"\";\n};\n\n\/* OneSignal\n   App ID \u2192 taray\u0131c\u0131 SDK\n   REST Key \u2192 sen de\u011fi\u015ftir; taray\u0131c\u0131dan REST push \u00e7a\u011fr\u0131s\u0131 yap\u0131lmaz (sunucu i\u00e7in saklan\u0131r)\n*\/\nconst ONESIGNAL_APP_ID = \"8afd9e7f-9cc4-4b89-b735-a242df371d5a\";\n\/\/ ONESIGNAL_REST_KEY taray\u0131c\u0131 kodunda tutulmaz. Push g\u00f6ndermek i\u00e7in Cloud Function kullan.\n\n\nwindow.OneSignalDeferred = window.OneSignalDeferred || [];\n\nfunction initOneSignal() {\n    window.OneSignalDeferred.push(async function(OneSignal) {\n        try {\n            await OneSignal.init({\n                appId: ONESIGNAL_APP_ID,\n                allowLocalhostAsSecureOrigin: true,\n                notifyButton: { enable: false }\n            });\n            if (currentUser) {\n                await OneSignal.login(currentUser.uid);\n                try {\n                    await set(ref(database, \"onesignalPlayers\/\" + currentUser.uid), {\n                        uid: currentUser.uid,\n                        at: Date.now()\n                    });\n                } catch (_) {}\n            }\n            await OneSignal.Notifications.requestPermission();\n        } catch (e) {\n            console.warn(\"OneSignal init:\", e);\n        }\n    });\n}\n\nfunction requestNotificationPermission() {\n    if (\"Notification\" in window && Notification.permission === \"default\") {\n        Notification.requestPermission();\n    }\n    initOneSignal();\n}\n\nfunction showNotification(msg) {\n    playNotificationSound();\n    if (!(\"Notification\" in window) || Notification.permission !== \"granted\") return;\n    getUserProfile(msg.uid).then(p => {\n        const title = p ? p.displayName : \"Yeni mesaj\";\n        const body = msg.text || (msg.image ? \"\ud83d\udcf7 Resim g\u00f6nderdi\" : \"Yeni mesaj\");\n        const n = new Notification(title, {\n            body: body.slice(0, 100),\n            icon: p?.photoData || undefined,\n            tag: \"vegamedia-msg\"\n        });\n        n.onclick = () => { window.focus(); n.close(); };\n    });\n}\n\nfunction openSidebar() {\n    sidebar.classList.add(\"open\");\n    sidebarOverlay.classList.add(\"show\");\n}\nfunction closeSidebar() {\n    sidebar.classList.remove(\"open\");\n    sidebarOverlay.classList.remove(\"show\");\n}\ndocument.getElementById(\"mobileMenuBtn\").onclick = openSidebar;\ndocument.getElementById(\"shortsMenuBtn\").onclick = openSidebar;\ndocument.getElementById(\"sidebarOverlay\").onclick = closeSidebar;\ndocument.getElementById(\"closeSidebarBtn\").onclick = closeSidebar;\n\ndocument.getElementById(\"profileButton\").onclick = openProfileModal;\ndocument.getElementById(\"sidebarAvatar\").onclick = openProfileModal;\n\nfunction openProfileModal() {\n    removeCurrentPhoto = false;\n    document.getElementById(\"profileUsernameReadonly\").value = \"@\" + currentProfile.username;\n    document.getElementById(\"profileDisplayNameInput\").value = currentProfile.displayName;\n    document.getElementById(\"profileAboutInput\").value = currentProfile.about;\n    document.getElementById(\"profilePhotoInput\").value = \"\";\n    document.getElementById(\"profileMessage\").textContent = \"\";\n    document.getElementById(\"profileStatusSelect\").value = localStorage.getItem(\"vegamedia_status\") || \"online\";\n    setAvatar(document.getElementById(\"profilePreview\"), currentProfile);\n    document.getElementById(\"profileDisplayNameInput\").dispatchEvent(new Event(\"input\"));\n    document.getElementById(\"profileAboutInput\").dispatchEvent(new Event(\"input\"));\n    profileModal.classList.remove(\"hidden\");\n}\ndocument.getElementById(\"profileCancelButton\").onclick = () => profileModal.classList.add(\"hidden\");\n\ndocument.getElementById(\"profilePhotoInput\").addEventListener(\"change\", async e => {\n    const file = e.target.files[0];\n    if (!file) return;\n    try {\n        const photoData = await compressImage(file);\n        removeCurrentPhoto = false;\n        setAvatar(document.getElementById(\"profilePreview\"), { ...currentProfile, photoData });\n    } catch (err) {\n        document.getElementById(\"profileMessage\").textContent = err.message;\n    }\n});\ndocument.getElementById(\"removePhotoButton\").onclick = () => {\n    removeCurrentPhoto = true;\n    document.getElementById(\"profilePhotoInput\").value = \"\";\n    setAvatar(document.getElementById(\"profilePreview\"), { ...currentProfile, photoData: \"\" });\n};\n\nfunction compressImage(file) {\n    return new Promise((resolve, reject) => {\n        if (!file.type.startsWith(\"image\/\")) { reject(new Error(\"L\u00fctfen bir resim se\u00e7.\")); return; }\n        if (file.size > 5 * 1024 * 1024) { reject(new Error(\"Foto\u011fraf en fazla 5 MB olabilir.\")); return; }\n        const reader = new FileReader();\n        reader.onload = ev => {\n            const image = new Image();\n            image.onload = () => {\n                const size = 256;\n                const canvas = document.createElement(\"canvas\");\n                canvas.width = size; canvas.height = size;\n                const ctx = canvas.getContext(\"2d\");\n                const crop = Math.min(image.width, image.height);\n                const sx = (image.width - crop) \/ 2;\n                const sy = (image.height - crop) \/ 2;\n                ctx.drawImage(image, sx, sy, crop, crop, 0, 0, size, size);\n                const data = canvas.toDataURL(\"image\/jpeg\", 0.72);\n                if (data.length > 300000) { reject(new Error(\"Foto\u011fraf \u00e7ok b\u00fcy\u00fck. Ba\u015fka bir foto\u011fraf se\u00e7.\")); return; }\n                resolve(data);\n            };\n            image.onerror = () => reject(new Error(\"Foto\u011fraf a\u00e7\u0131lamad\u0131.\"));\n            image.src = ev.target.result;\n        };\n        reader.onerror = () => reject(new Error(\"Foto\u011fraf okunamad\u0131.\"));\n        reader.readAsDataURL(file);\n    });\n}\n\ndocument.getElementById(\"profileSaveButton\").onclick = async () => {\n    const profileMessage = document.getElementById(\"profileMessage\");\n    profileMessage.textContent = \"\";\n    const displayName = document.getElementById(\"profileDisplayNameInput\").value.trim();\n    const about = document.getElementById(\"profileAboutInput\").value.trim();\n    if (displayName.length < 2 || displayName.length > 24) {\n        profileMessage.textContent = \"G\u00f6r\u00fcnen ad 2-24 karakter olmal\u0131.\"; return;\n    }\n    if (about.length > 139) {\n        profileMessage.textContent = \"Hakk\u0131mda b\u00f6l\u00fcm\u00fc 139 karakterden uzun olamaz.\"; return;\n    }\n    try {\n        let photoData = currentProfile.photoData;\n        if (removeCurrentPhoto) photoData = \"\";\n        const selectedFile = document.getElementById(\"profilePhotoInput\").files[0];\n        if (selectedFile) photoData = await compressImage(selectedFile);\n        const statusVal = document.getElementById(\"profileStatusSelect\").value || \"online\";\n        localStorage.setItem(\"vegamedia_status\", statusVal);\n        await update(ref(database, \"users\/\" + currentUser.uid), { displayName, about, photoData });\n        await set(ref(database, \"status\/\" + currentUser.uid), { state: statusVal, lastChanged: Date.now() });\n        await updateProfile(currentUser, { displayName });\n        currentProfile = { ...currentProfile, displayName, about, photoData };\n        profileCache.set(currentUser.uid, currentProfile);\n        \/\/ Topluluk oyunu kaydet\n        const cgTitle = (document.getElementById(\"cgTitleInput\")?.value || \"\").trim();\n        const cgHtml = (document.getElementById(\"cgHtmlInput\")?.value || \"\").trim();\n        const cgOpen = !!document.getElementById(\"cgSourceOpen\")?.checked;\n        if (cgHtml) {\n            if (cgHtml.length > 50000) {\n                profileMessage.textContent = \"HTML \u00e7ok uzun (max 50KB).\"; return;\n            }\n            const gid = push(ref(database, \"communityGames\")).key;\n            const cgIconVal = (document.getElementById(\"cgIconInput\")?.value || \"\ud83d\udee0\ufe0f\").trim().slice(0, 4) || \"\ud83d\udee0\ufe0f\";\n            const meta = {\n                uid: currentUser.uid,\n                username: currentProfile.username,\n                displayName: currentProfile.displayName,\n                title: Array.from(cgTitle || \"\u0130simsiz oyun\").slice(0, 80).join(\"\"),\n                html: cgHtml,\n                sourceOpen: cgOpen,\n                icon: cgIconVal,\n                createdAt: Date.now()\n            };\n            await set(ref(database, \"communityGames\/\" + gid), meta);\n            await set(ref(database, \"communityGamesByUser\/\" + currentUser.uid + \"\/\" + gid), {\n                title: meta.title, sourceOpen: cgOpen, icon: cgIconVal, createdAt: meta.createdAt\n            });\n            document.getElementById(\"cgHtmlInput\").value = \"\";\n            document.getElementById(\"cgTitleInput\").value = \"\";\n        }\n        updateMyProfileDisplay();\n        updateMyMessagesOnScreen();\n        profileModal.classList.add(\"hidden\");\n        if (cgHtml) alert(\"Oyun kaydedildi! Oyunlar \u2192 Topluluk yap\u0131m\u0131 alt\u0131nda g\u00f6r\u00fcn\u00fcr.\");\n    } catch (e) {\n        console.error(e);\n        profileMessage.textContent = \"Profil kaydedilemedi: \" + e.message;\n    }\n};\n\nfunction cgIcon(g) {\n    const ic = (g && g.icon) ? String(g.icon).trim() : \"\";\n    return ic || \"\ud83d\udee0\ufe0f\";\n}\n\nasync function playCommunityGame(g) {\n    const area = typeof gameArea === \"function\" ? gameArea() : null;\n    if (!area) return;\n    if (!g._id) return alert(\"Oyun id yok\");\n    await refreshVipStatus();\n    const canSeeSource = !!(g.sourceOpen || isVipAdmin || (currentUser && g.uid === currentUser.uid));\n    const srcLabel = g.sourceOpen ? \"Kaynak: a\u00e7\u0131k\" : (isVipAdmin ? \"Kaynak: VIP g\u00f6r\u00fcn\u00fcm\" : \"Kaynak: kapal\u0131\");\n    const isOwner = currentUser && g.uid === currentUser.uid;\n    let likeCount = 0, liked = false;\n    try {\n        const ls = await get(ref(database, \"communityGameLikes\/\" + g._id));\n        if (ls.exists()) {\n            const o = ls.val();\n            likeCount = Object.keys(o).length;\n            liked = !!(currentUser && o[currentUser.uid]);\n        }\n    } catch (_) {}\n\n    area.innerHTML = `\n        <div style=\"display:flex;flex-wrap:wrap;gap:8px;align-items:center;margin-bottom:8px;\">\n            <button class=\"gameBackBtn\" id=\"cgBackBtn\" style=\"margin:0;\">\u2190 Geri<\/button>\n            <button type=\"button\" class=\"liveBtn\" id=\"cgFsBtn\">\u26f6 Tam ekran<\/button>\n            ${isOwner ? `<button type=\"button\" class=\"liveBtn\" id=\"cgEditBtn\">\u270f\ufe0f D\u00fczenle<\/button>\n            <button type=\"button\" class=\"liveBtn red\" id=\"cgDeleteBtn\">Sil<\/button>` : \"\"}\n        <\/div>\n        <div class=\"gameStatus\">${escapeHtml(cgIcon(g))} ${escapeHtml(g.title || \"Oyun\")} \u00b7 @${escapeHtml(g.username || \"?\")} \u00b7 ${srcLabel}<\/div>\n        <div id=\"cgFrameWrap\" style=\"position:relative;width:100%;max-width:560px;margin:12px auto;\">\n            <iframe id=\"cgFrame\" sandbox=\"allow-scripts allow-same-origin allow-pointer-lock allow-popups\" style=\"width:100%;height:min(70vh,480px);border:none;border-radius:12px;background:#000;display:block;\"><\/iframe>\n        <\/div>\n        <div style=\"display:flex;gap:10px;align-items:center;flex-wrap:wrap;margin:10px 0;\">\n            <button type=\"button\" class=\"liveBtn\" id=\"cgLikeBtn\" style=\"min-width:140px;font-size:16px;padding:12px 16px;\">${liked ? \"\u2764\ufe0f Be\u011fenildi\" : \"\ud83e\udd0d Be\u011fen\"} \u00b7 ${likeCount}<\/button>\n        <\/div>\n        ${canSeeSource ? `<details style=\"margin-top:8px;background:#1e1f22;border-radius:8px;padding:10px;\"><summary style=\"cursor:pointer;color:#b5bac1;\">Kaynak kodu${isVipAdmin && !g.sourceOpen ? \" (VIP)\" : \"\"}<\/summary><pre style=\"white-space:pre-wrap;font-size:11px;color:#dbdee1;max-height:200px;overflow:auto;\">${escapeHtml(g.html || \"\")}<\/pre><\/details>` : `<div class=\"liveNote\">Kaynak kodu gizli.<\/div>`}\n        <div class=\"sectionTitle\" style=\"margin-top:16px;\">\ud83d\udcac Yorumlar<\/div>\n        <div id=\"cgComments\" style=\"max-height:220px;overflow-y:auto;background:#1e1f22;border-radius:10px;padding:10px;margin-bottom:8px;\"><\/div>\n        <div style=\"display:flex;gap:8px;\">\n            <input id=\"cgCommentInput\" maxlength=\"300\" placeholder=\"Yorum yaz...\" style=\"flex:1;padding:10px;border:none;border-radius:8px;background:#2b2d31;color:#fff;\">\n            <button type=\"button\" class=\"liveBtn green\" id=\"cgCommentSend\">G\u00f6nder<\/button>\n        <\/div>\n    `;\n    const frame = document.getElementById(\"cgFrame\");\n    if (frame) {\n        let html = g.html || \"\";\n        if (html && !\/<\\s*html\/i.test(html) && !\/<\\s*body\/i.test(html)) {\n            html = \"<!DOCTYPE html><html><head><meta charset=\\\"utf-8\\\"><style>html,body{margin:0;height:100%;background:#111;color:#fff;font-family:sans-serif;}<\/style><\/head><body>\" + html + \"<\/body><\/html>\";\n        }\n        frame.srcdoc = html || \"<p style='color:#fff;font-family:sans-serif;padding:20px;'>Bo\u015f oyun<\/p>\";\n    }\n    gameBack(area);\n\n    document.getElementById(\"cgBackBtn\")?.addEventListener(\"click\", () => {\n        exitCgFullscreen();\n        area.classList.add(\"hidden\");\n        area.innerHTML = \"\";\n        const list = document.getElementById(\"gamesListWrap\");\n        if (list) list.style.display = \"\";\n        loadCommunityGamesList();\n    });\n    document.getElementById(\"cgFsBtn\")?.addEventListener(\"click\", () => toggleCgFullscreen());\n    document.getElementById(\"cgEditBtn\")?.addEventListener(\"click\", () => openEditCommunityGame(g));\n    document.getElementById(\"cgDeleteBtn\")?.addEventListener(\"click\", async () => {\n        if (!confirm(\"Bu oyunu silmek istiyor musun?\")) return;\n        try {\n            await remove(ref(database, \"communityGames\/\" + g._id));\n            await remove(ref(database, \"communityGamesByUser\/\" + currentUser.uid + \"\/\" + g._id));\n            await remove(ref(database, \"communityGameLikes\/\" + g._id)).catch(() => {});\n            await remove(ref(database, \"communityGameComments\/\" + g._id)).catch(() => {});\n            exitCgFullscreen();\n            area.classList.add(\"hidden\");\n            area.innerHTML = \"\";\n            const list = document.getElementById(\"gamesListWrap\");\n            if (list) list.style.display = \"\";\n            loadCommunityGamesList();\n            alert(\"Silindi.\");\n        } catch (e) { alert(e.message || e); }\n    });\n    document.getElementById(\"cgLikeBtn\")?.addEventListener(\"click\", async () => {\n        if (!currentUser) {\n            alert(\"Be\u011fenmek i\u00e7in giri\u015f yapmal\u0131s\u0131n.\");\n            return;\n        }\n        if (!g._id) {\n            alert(\"Oyun id bulunamad\u0131.\");\n            return;\n        }\n        const path = \"communityGameLikes\/\" + g._id + \"\/\" + currentUser.uid;\n        const btn = document.getElementById(\"cgLikeBtn\");\n        if (btn) btn.disabled = true;\n        try {\n            if (liked) {\n                await remove(ref(database, path));\n                liked = false;\n                likeCount = Math.max(0, likeCount - 1);\n            } else {\n                await set(ref(database, path), {\n                    at: Date.now(),\n                    name: (currentProfile && currentProfile.displayName) || \"Kullan\u0131c\u0131\"\n                });\n                liked = true;\n                likeCount += 1;\n            }\n            \/\/ sayac\u0131 oyunda da tut (liste i\u00e7in)\n            try {\n                await update(ref(database, \"communityGames\/\" + g._id), { likeCount: likeCount });\n            } catch (_) {}\n            if (btn) {\n                btn.disabled = false;\n                btn.innerHTML = (liked ? \"\u2764\ufe0f Be\u011fenildi\" : \"\ud83e\udd0d Be\u011fen\") + \" \u00b7 \" + likeCount;\n            }\n        } catch (e) {\n            if (btn) btn.disabled = false;\n            const msg = (e && (e.message || e.code)) || String(e);\n            if (\/PERMISSION|permission|denied\/i.test(msg)) {\n                alert(\"Be\u011feni izni yok.\\nFirebase Rules'a communityGameLikes ekleyip Publish et.\");\n            } else {\n                alert(\"Be\u011feni hatas\u0131: \" + msg);\n            }\n            console.error(\"like\", e);\n        }\n    });\n    document.getElementById(\"cgCommentSend\")?.addEventListener(\"click\", () => sendCgComment(g._id));\n    document.getElementById(\"cgCommentInput\")?.addEventListener(\"keydown\", e => {\n        if (e.key === \"Enter\") sendCgComment(g._id);\n    });\n    listenCgComments(g._id);\n}\n\nfunction exitCgFullscreen() {\n    const wrap = document.getElementById(\"cgFrameWrap\");\n    const frame = document.getElementById(\"cgFrame\");\n    if (!wrap) return;\n    wrap.classList.remove(\"cgFullscreen\");\n    wrap.style.cssText = \"position:relative;width:100%;max-width:560px;margin:12px auto;\";\n    if (frame) frame.style.height = \"min(70vh,480px)\";\n    const btn = document.getElementById(\"cgFsBtn\");\n    if (btn) btn.textContent = \"\u26f6 Tam ekran\";\n}\nfunction toggleCgFullscreen() {\n    const wrap = document.getElementById(\"cgFrameWrap\");\n    const frame = document.getElementById(\"cgFrame\");\n    if (!wrap) return;\n    const on = wrap.classList.toggle(\"cgFullscreen\");\n    if (on) {\n        wrap.style.cssText = \"position:fixed;inset:0;z-index:9000;max-width:none;margin:0;background:#000;display:flex;flex-direction:column;\";\n        if (frame) frame.style.cssText = \"width:100%;height:100%;border:none;border-radius:0;background:#000;flex:1;\";\n        let bar = document.getElementById(\"cgFsExitBar\");\n        if (!bar) {\n            bar = document.createElement(\"div\");\n            bar.id = \"cgFsExitBar\";\n            bar.style.cssText = \"position:absolute;top:12px;right:12px;z-index:9001;\";\n            bar.innerHTML = `<button type=\"button\" id=\"cgFsExit\" style=\"padding:10px 14px;border:none;border-radius:8px;background:#ed4245;color:#fff;font-weight:bold;\">\u2715 \u00c7\u0131k<\/button>`;\n            wrap.appendChild(bar);\n            document.getElementById(\"cgFsExit\").onclick = () => toggleCgFullscreen();\n        }\n        const btn = document.getElementById(\"cgFsBtn\");\n        if (btn) btn.textContent = \"\u26f6 K\u00fc\u00e7\u00fclt\";\n        \/\/ native fullscreen denemesi\n        try { wrap.requestFullscreen?.(); } catch (_) {}\n    } else {\n        exitCgFullscreen();\n        try { document.exitFullscreen?.(); } catch (_) {}\n        const bar = document.getElementById(\"cgFsExitBar\");\n        if (bar) bar.remove();\n    }\n}\n\nasync function sendCgComment(gid) {\n    if (!currentUser || !gid) return;\n    const input = document.getElementById(\"cgCommentInput\");\n    const text = (input?.value || \"\").trim();\n    if (!text) return;\n    try {\n        await push(ref(database, \"communityGameComments\/\" + gid), {\n            uid: currentUser.uid,\n            name: currentProfile.displayName || currentProfile.username,\n            text: text.slice(0, 300),\n            at: Date.now()\n        });\n        if (input) input.value = \"\";\n    } catch (e) { alert(e.message || e); }\n}\n\nlet cgCommentUnsub = null;\nfunction listenCgComments(gid) {\n    if (cgCommentUnsub) { try { cgCommentUnsub(); } catch (_) {} cgCommentUnsub = null; }\n    const box = document.getElementById(\"cgComments\");\n    if (!box) return;\n    box.innerHTML = `<div class=\"liveNote\">Y\u00fckleniyor...<\/div>`;\n    cgCommentUnsub = onValue(ref(database, \"communityGameComments\/\" + gid), snap => {\n        if (!box.isConnected) return;\n        if (!snap.exists()) {\n            box.innerHTML = `<div class=\"liveNote\">Hen\u00fcz yorum yok.<\/div>`;\n            return;\n        }\n        const rows = Object.entries(snap.val()).sort((a, b) => (a[1].at || 0) - (b[1].at || 0));\n        box.innerHTML = rows.map(([, c]) =>\n            `<div style=\"margin-bottom:8px;padding-bottom:8px;border-bottom:1px solid #2b2d31;\">\n                <b style=\"color:#00aff4;\">${escapeHtml(c.name || \"?\")}<\/b>\n                <span style=\"color:#949ba4;font-size:11px;margin-left:6px;\">${c.at ? new Date(c.at).toLocaleString(\"tr-TR\") : \"\"}<\/span>\n                <div style=\"margin-top:4px;color:#dbdee1;\">${escapeHtml(c.text || \"\")}<\/div>\n            <\/div>`\n        ).join(\"\");\n        box.scrollTop = box.scrollHeight;\n    });\n}\n\nfunction openEditCommunityGame(g) {\n    if (!currentUser || g.uid !== currentUser.uid) {\n        alert(\"Sadece kendi oyununu d\u00fczenleyebilirsin.\");\n        return;\n    }\n    const area = document.getElementById(\"activeGameArea\");\n    if (!area || !g._id) return;\n    area.classList.remove(\"hidden\");\n    const list = document.getElementById(\"gamesListWrap\");\n    if (list) list.style.display = \"none\";\n    const icons = [\"\ud83d\udee0\ufe0f\", \"\ud83c\udfae\", \"\ud83d\ude80\", \"\ud83c\udfce\ufe0f\", \"\ud83e\udde9\", \"\u2694\ufe0f\", \"\ud83c\udfaf\", \"\ud83d\udc09\", \"\ud83d\udc7e\", \"\ud83c\udfc6\", \"\ud83d\udd25\", \"\u2b50\"];\n    area.innerHTML = `\n        <button class=\"gameBackBtn\" id=\"cgEditBack\">\u2190 Geri<\/button>\n        <div class=\"gameStatus\">Oyunu d\u00fczenle (sadece sen)<\/div>\n        <label style=\"display:block;margin-top:8px;color:#b5bac1;font-size:13px;\">Simge<\/label>\n        <div id=\"cgIconPick\" style=\"display:flex;flex-wrap:wrap;gap:6px;margin:8px 0;\">\n            ${icons.map(ic => `<button type=\"button\" class=\"cgIconBtn\" data-ic=\"${ic}\" style=\"font-size:22px;padding:8px 10px;border:2px solid ${cgIcon(g) === ic ? \"#5865f2\" : \"#404249\"};border-radius:8px;background:#1e1f22;cursor:pointer;\">${ic}<\/button>`).join(\"\")}\n        <\/div>\n        <input id=\"cgEditIcon\" type=\"text\" maxlength=\"4\" value=\"${escapeHtml(cgIcon(g))}\" placeholder=\"veya emoji yaz\"\n            style=\"width:100%;max-width:520px;padding:10px;border:none;border-radius:8px;background:#1e1f22;color:#fff;margin-bottom:8px;display:block;\">\n        <input id=\"cgEditTitle\" type=\"text\" maxlength=\"80\" value=\"${escapeHtml(g.title || \"\")}\"\n            style=\"width:100%;max-width:520px;padding:12px;border:none;border-radius:8px;background:#1e1f22;color:#fff;margin:8px 0;display:block;\">\n        <textarea id=\"cgEditHtml\" maxlength=\"50000\" style=\"width:100%;max-width:520px;min-height:160px;padding:12px;border:none;border-radius:8px;background:#1e1f22;color:#fff;font-family:monospace;font-size:12px;display:block;\">${escapeHtml(g.html || \"\")}<\/textarea>\n        <label style=\"display:flex;align-items:center;gap:8px;margin:10px 0;color:#dbdee1;font-size:13px;\">\n            <input type=\"checkbox\" id=\"cgEditSource\" ${g.sourceOpen ? \"checked\" : \"\"}> Kaynak herkese a\u00e7\u0131k (sonradan de\u011fi\u015ftirebilirsin)\n        <\/label>\n        <button type=\"button\" class=\"bigBtn\" id=\"cgEditSave\" style=\"max-width:520px;\">Kaydet<\/button>\n        <div id=\"cgEditMsg\" style=\"font-size:13px;color:#949ba4;margin-top:8px;\"><\/div>`;\n    document.querySelectorAll(\".cgIconBtn\").forEach(b => {\n        b.onclick = () => {\n            document.getElementById(\"cgEditIcon\").value = b.dataset.ic;\n            document.querySelectorAll(\".cgIconBtn\").forEach(x => x.style.borderColor = \"#404249\");\n            b.style.borderColor = \"#5865f2\";\n        };\n    });\n    document.getElementById(\"cgEditBack\").onclick = () => playCommunityGame(g);\n    document.getElementById(\"cgEditSave\").onclick = async () => {\n        const msg = document.getElementById(\"cgEditMsg\");\n        const title = Array.from((document.getElementById(\"cgEditTitle\").value || \"\").trim() || \"\u0130simsiz oyun\").slice(0, 80).join(\"\");\n        const html = (document.getElementById(\"cgEditHtml\").value || \"\").trim();\n        const sourceOpen = !!document.getElementById(\"cgEditSource\").checked;\n        const icon = (document.getElementById(\"cgEditIcon\").value || \"\ud83d\udee0\ufe0f\").trim().slice(0, 4) || \"\ud83d\udee0\ufe0f\";\n        if (!html) { msg.textContent = \"HTML bo\u015f olamaz\"; msg.style.color = \"#ed4245\"; return; }\n        if (html.length > 50000) { msg.textContent = \"Max 50KB\"; msg.style.color = \"#ed4245\"; return; }\n        try {\n            msg.textContent = \"Kaydediliyor...\"; msg.style.color = \"#949ba4\";\n            await update(ref(database, \"communityGames\/\" + g._id), { title, html, sourceOpen, icon, updatedAt: Date.now() });\n            await update(ref(database, \"communityGamesByUser\/\" + currentUser.uid + \"\/\" + g._id), { title, sourceOpen, icon });\n            g.title = title; g.html = html; g.sourceOpen = sourceOpen; g.icon = icon;\n            msg.style.color = \"#23a559\"; msg.textContent = \"Kaydedildi!\";\n            setTimeout(() => playCommunityGame(g), 400);\n        } catch (e) {\n            msg.style.color = \"#ed4245\";\n            msg.textContent = (e.code || \"\") + \" \" + (e.message || e);\n        }\n    };\n}\n\nasync function loadCommunityGamesList() {\n    const box = document.getElementById(\"communityGamesList\");\n    if (!box) return;\n    box.innerHTML = `<div class=\"liveNote\">Y\u00fckleniyor...<\/div>`;\n    if (!currentUser) {\n        box.innerHTML = `<div class=\"liveNote\" style=\"color:#faa61a;\">Topluluk oyunlar\u0131 i\u00e7in giri\u015f gerekli.<\/div>`;\n        return;\n    }\n    try {\n        const snap = await get(query(ref(database, \"communityGames\"), limitToLast(40)));\n        if (!snap.exists()) {\n            box.innerHTML = `<div class=\"liveNote\">Hen\u00fcz topluluk oyunu yok. Profilim \u2192 HTML oyun ekle.<\/div>`;\n            return;\n        }\n        const items = Object.entries(snap.val()).sort((a, b) => (b[1].createdAt || 0) - (a[1].createdAt || 0));\n        \/\/ like counts\n        const likeMap = {};\n        await Promise.all(items.map(async ([id]) => {\n            try {\n                const ls = await get(ref(database, \"communityGameLikes\/\" + id));\n                likeMap[id] = ls.exists() ? Object.keys(ls.val()).length : 0;\n            } catch (_) { likeMap[id] = 0; }\n        }));\n        box.innerHTML = \"\";\n        items.forEach(([id, g]) => {\n            const card = document.createElement(\"div\");\n            card.className = \"gameCard\";\n            const mine = currentUser && g.uid === currentUser.uid;\n            card.innerHTML = `\n                <div class=\"gameIcon\">${escapeHtml(cgIcon(g))}<\/div>\n                <div class=\"gameInfo\">\n                    <div class=\"gameName\">${escapeHtml(g.title || \"Oyun\")}${mine ? \" \u00b7 senin\" : \"\"}<\/div>\n                    <div class=\"gameDesc\">@${escapeHtml(g.username || \"?\")} \u00b7 ${g.sourceOpen ? \"Kaynak a\u00e7\u0131k\" : \"Kapal\u0131\"} \u00b7 \u2764\ufe0f ${likeMap[id] || 0}<\/div>\n                <\/div>`;\n            card.onclick = () => playCommunityGame({ ...g, _id: id });\n            box.appendChild(card);\n        });\n    } catch (e) {\n        const err = e.message || String(e);\n        box.innerHTML = `<div class=\"liveNote\" style=\"color:#ff7777;\">Oyunlar al\u0131namad\u0131: ${escapeHtml(err)}\n            ${\/PERMISSION|permission\/i.test(err) ? \"<br>Firebase Rules'ta communityGames okuma iznini kontrol et.\" : \"\"}<\/div>`;\n    }\n}\n\n\/\/ Sohbet arka plan\u0131\nfunction chatBgKey() {\n    if (activeChatType === \"private\" && activeChatId) return \"private:\" + activeChatId;\n    if (activeChatType === \"group\" && activeGroupId) return \"group:\" + activeGroupId;\n    return \"ch:\" + (activeChatType || \"general\");\n}\nfunction applyChatBackground() {\n    const target = document.getElementById(\"messages\") || document.getElementById(\"mainChatArea\");\n    const key = \"vegamedia_bg_\" + chatBgKey();\n    const val = localStorage.getItem(key) || \"\";\n    if (!target) return;\n    if (!val) {\n        target.style.backgroundImage = \"\";\n        target.style.backgroundColor = \"\";\n        return;\n    }\n    if (val === \"grad1\") {\n        target.style.backgroundImage = \"linear-gradient(160deg,#1a1025,#2d1b4e 40%,#0b141a)\";\n        target.style.backgroundColor = \"\";\n        return;\n    }\n    if (val === \"grad2\") {\n        target.style.backgroundImage = \"linear-gradient(160deg,#0a1f18,#0f2027 45%,#0b141a)\";\n        target.style.backgroundColor = \"\";\n        return;\n    }\n    if (val.startsWith(\"http\") || val.startsWith(\"data:\")) {\n        target.style.backgroundImage = `linear-gradient(rgba(11,20,26,.75),rgba(11,20,26,.85)), url(\"${val}\")`;\n        target.style.backgroundSize = \"cover\";\n        target.style.backgroundPosition = \"center\";\n        target.style.backgroundColor = \"\";\n    } else {\n        target.style.backgroundImage = \"\";\n        target.style.backgroundColor = val;\n    }\n}\nfunction applyChatWallpaper() { applyChatBackground(); }\ndocument.getElementById(\"chatBgSelect\")?.addEventListener(\"change\", () => {\n    const v = document.getElementById(\"chatBgSelect\").value;\n    document.getElementById(\"chatBgUrlInput\").style.display = v === \"url\" ? \"block\" : \"none\";\n});\ndocument.getElementById(\"chatBgSaveBtn\")?.addEventListener(\"click\", async () => {\n    let v = document.getElementById(\"chatBgSelect\").value;\n    if (v === \"url\") v = (document.getElementById(\"chatBgUrlInput\").value || \"\").trim();\n    const key = \"vegamedia_bg_\" + chatBgKey();\n    if (!v) localStorage.removeItem(key);\n    else localStorage.setItem(key, v);\n    try {\n        if (currentUser) {\n            await set(ref(database, \"chatBackgrounds\/\" + currentUser.uid + \"\/\" + chatBgKey().replace(\/[.#$\/[\\]]\/g, \"_\")), v || null);\n        }\n    } catch (_) {}\n    applyChatBackground();\n    alert(\"Arka plan kaydedildi (bu sohbet i\u00e7in).\");\n});\n\nfunction updateMyMessagesOnScreen() {\n    document.querySelectorAll(`.message[data-uid=\"${currentUser.uid}\"]`).forEach(row => {\n        const uname = row.querySelector(\".messageUsername\");\n        const av = row.querySelector(\".messageAvatar\");\n        if (uname) uname.textContent = currentProfile.displayName;\n        if (av) setAvatar(av, currentProfile);\n    });\n}\n\n\/* B\u0130LD\u0130R\u0130M SES\u0130 (Myinstants) *\/\nconst MYINSTANTS_SOUNDS = [\n    { name: \"Vine Boom\", url: \"https:\/\/www.myinstants.com\/media\/sounds\/vine-boom.mp3\" },\n    { name: \"Bruh\", url: \"https:\/\/www.myinstants.com\/media\/sounds\/movie_1.mp3\" },\n    { name: \"Discord Notification\", url: \"https:\/\/www.myinstants.com\/media\/sounds\/discord-notification.mp3\" },\n    { name: \"Android Notification\", url: \"https:\/\/www.myinstants.com\/media\/sounds\/android-notification-sound-effect.mp3\" },\n    { name: \"Samsung Notification\", url: \"https:\/\/www.myinstants.com\/media\/sounds\/samsung-notification-sound.mp3\" },\n    { name: \"iPhone Notification\", url: \"https:\/\/www.myinstants.com\/media\/sounds\/iphone-notification-sound.mp3\" },\n    { name: \"Pop Alert\", url: \"https:\/\/www.myinstants.com\/media\/sounds\/pop.mp3\" },\n    { name: \"Message Pop\", url: \"https:\/\/www.myinstants.com\/media\/sounds\/message-pop-alert.mp3\" },\n    { name: \"Zil (Klasik)\", url: \"https:\/\/www.myinstants.com\/media\/sounds\/ding-sound-effect.mp3\" },\n    { name: \"Elmas Zil\", url: \"https:\/\/www.myinstants.com\/media\/sounds\/elmas-zil-sesi.mp3\" },\n    { name: \"Among Us\", url: \"https:\/\/www.myinstants.com\/media\/sounds\/among-us.mp3\" },\n    { name: \"Windows XP Error\", url: \"https:\/\/www.myinstants.com\/media\/sounds\/windows-xp-error.mp3\" },\n    { name: \"Roblox Death\", url: \"https:\/\/www.myinstants.com\/media\/sounds\/roblox-death-sound.mp3\" },\n    { name: \"Taco Bell\", url: \"https:\/\/www.myinstants.com\/media\/sounds\/taco-bell-bong.mp3\" }\n];\n\nlet selectedSoundUrl = localStorage.getItem(\"vegamedia_notif_sound\") || MYINSTANTS_SOUNDS[0].url;\nlet audioPlayer = new Audio();\n\nfunction playNotificationSound() {\n    try {\n        audioPlayer.pause();\n        audioPlayer.currentTime = 0;\n        audioPlayer.src = selectedSoundUrl;\n        audioPlayer.volume = 0.7;\n        audioPlayer.play().catch(() => {});\n    } catch (e) {}\n}\n\ndocument.getElementById(\"settingsButton\").onclick = openSettings;\n\nasync function openSettings() {\n    document.getElementById(\"settingsModal\").classList.remove(\"hidden\");\n    renderSoundList();\n    updateCurrentSoundInfo();\n    document.getElementById(\"currentPasswordInput\").value = \"\";\n    document.getElementById(\"newPasswordInput\").value = \"\";\n    document.getElementById(\"newPasswordAgainInput\").value = \"\";\n    document.getElementById(\"passwordMessage\").textContent = \"\";\n    document.getElementById(\"deleteAccountBtn\")?.addEventListener(\"click\", () => deleteMyAccount(), { once: true });\n    await loadSideAccountsUI();\n    const adminBox = document.getElementById(\"adminCommandsBox\");\n    if (await isCurrentUserAdmin()) {\n        adminBox.classList.remove(\"hidden\");\n        try {\n            const statusSnap = await get(ref(database, \"status\"));\n            let count = 0;\n            const listEl = document.getElementById(\"adminOnlineList\");\n            const infoEl = document.getElementById(\"adminOnlineInfo\");\n            listEl.innerHTML = \"\";\n            if (statusSnap.exists()) {\n                const st = statusSnap.val();\n                for (const uid of Object.keys(st)) {\n                    if (st[uid]?.state && st[uid].state !== \"offline\") {\n                        count++;\n                        const p = await getUserProfile(uid);\n                        const row = document.createElement(\"div\");\n                        row.textContent = \"\ud83d\udfe2 \" + (p?.displayName || \"?\") + \" (@\" + (p?.username || \"?\") + \")\";\n                        row.style.marginBottom = \"4px\";\n                        listEl.appendChild(row);\n                    }\n                }\n            }\n            infoEl.textContent = \"\u015eu an \u00e7evrimi\u00e7i: \" + count + \" ki\u015fi (\u015fifreler g\u00f6r\u00fclemez)\";\n            if (count === 0) listEl.textContent = \"Kimse online de\u011fil.\";\n        } catch (e) {\n            document.getElementById(\"adminOnlineInfo\").textContent = \"Online listesi al\u0131namad\u0131.\";\n        }\n    } else {\n        adminBox.classList.add(\"hidden\");\n    }\n}\n\nasync function loadSideAccountsUI() {\n    const list = document.getElementById(\"sideAccountsList\");\n    if (!list || !currentUser) return;\n    list.innerHTML = \"Y\u00fckleniyor...\";\n    try {\n        const snap = await get(ref(database, \"multiAccounts\/\" + currentUser.uid));\n        list.innerHTML = \"\";\n        if (!snap.exists()) {\n            list.innerHTML = \"<div style=\\\"color:#949ba4\\\">Hen\u00fcz yan hesap yok.<\/div>\";\n            return;\n        }\n        const data = snap.val();\n        for (const otherUid of Object.keys(data)) {\n            const info = data[otherUid] || {};\n            const row = document.createElement(\"div\");\n            row.style.cssText = \"display:flex;align-items:center;justify-content:space-between;gap:8px;padding:6px 0;border-bottom:1px solid #2b2d31;\";\n            const label = document.createElement(\"span\");\n            label.textContent = \"@\" + (info.username || \"?\") + \" \u00b7 \" + (info.displayName || \"\");\n            const btns = document.createElement(\"div\");\n            btns.style.cssText = \"display:flex;gap:4px;\";\n            const go = document.createElement(\"button\");\n            go.textContent = \"Ge\u00e7\";\n            go.style.cssText = \"border:none;border-radius:6px;padding:4px 10px;background:#5865f2;color:white;cursor:pointer;font-size:12px;\";\n            go.onclick = () => switchToSideAccount(info.username);\n            const del = document.createElement(\"button\");\n            del.textContent = \"Sil\";\n            del.style.cssText = \"border:none;border-radius:6px;padding:4px 10px;background:#ed4245;color:white;cursor:pointer;font-size:12px;\";\n            del.onclick = async () => {\n                await remove(ref(database, \"multiAccounts\/\" + currentUser.uid + \"\/\" + otherUid));\n                loadSideAccountsUI();\n            };\n            btns.appendChild(go);\n            btns.appendChild(del);\n            row.appendChild(label);\n            row.appendChild(btns);\n            list.appendChild(row);\n        }\n    } catch (e) {\n        list.innerHTML = \"Liste al\u0131namad\u0131.\";\n    }\n}\n\n\/** Hesab\u0131 yan hesap listesine kaydet (admin veya elle ekleme) *\/\nasync function linkAsSideAccount(otherUid, profile) {\n    if (!currentUser || !otherUid || otherUid === currentUser.uid) return;\n    const username = profile?.username || profile?.usernameKey || \"?\";\n    await set(ref(database, \"multiAccounts\/\" + currentUser.uid + \"\/\" + otherUid), {\n        username: normalizeUsername(username),\n        displayName: profile?.displayName || username,\n        linkedAt: Date.now(),\n        adminLink: true\n    });\n}\n\nasync function switchToSideAccount(username) {\n    if (!username) return;\n    const isAdmin = await isCurrentUserAdmin();\n    const uidSnap = await get(ref(database, \"usernames\/\" + normalizeUsername(username)));\n    if (!uidSnap.exists()) return alert(\"Kullan\u0131c\u0131 bulunamad\u0131: @\" + username);\n    const targetUid = uidSnap.val();\n    const targetProfile = await getUserProfile(targetUid);\n    if (!targetProfile) return alert(\"Profil y\u00fcklenemedi.\");\n\n    \/\/ Admin: yan hesaba ekle + \u015fifresiz ge\u00e7\n    if (isAdmin) {\n        try {\n            await linkAsSideAccount(targetUid, targetProfile);\n        } catch (e) {\n            console.warn(\"Yan hesap kayd\u0131:\", e);\n        }\n        document.getElementById(\"settingsModal\")?.classList.add(\"hidden\");\n        await startImpersonation(targetUid, targetProfile);\n        try { loadSideAccountsUI(); } catch (_) {}\n        return;\n    }\n\n    const password = prompt(\"@\" + username + \" \u015fifresi (zorunlu):\") || \"\";\n    if (!password) return;\n    try {\n        document.getElementById(\"settingsModal\").classList.add(\"hidden\");\n        await signOut(auth);\n        await signInWithEmailAndPassword(auth, makeInternalEmail(username), password);\n    } catch (e) {\n        alert(\"Giri\u015f ba\u015far\u0131s\u0131z: \" + (e.message || e.code));\n        location.reload();\n    }\n}\n\nasync function startImpersonation(uid, profile) {\n    if (!currentUser || uid === currentUser.uid) {\n        stopImpersonation();\n        return;\n    }\n    \/\/ Yan hesap listesine otomatik ekle\n    try {\n        await linkAsSideAccount(uid, profile);\n    } catch (e) {\n        console.warn(\"Yan hesap eklenemedi:\", e);\n    }\n    impersonating = { uid, profile: normalizeProfile(profile) };\n    const banner = document.getElementById(\"impersonateBanner\");\n    banner.classList.remove(\"hidden\");\n    banner.style.display = \"flex\";\n    document.getElementById(\"impersonateText\").textContent =\n        \"\u26a1 Yan hesap: @\" + (profile.username || \"?\") + \" (\" + (profile.displayName || \"\") + \") \u2014 Admin \u015fifresiz\";\n    updateMyProfileDisplay();\n    try { loadSideAccountsUI(); } catch (_) {}\n}\n\nfunction stopImpersonation() {\n    impersonating = null;\n    const banner = document.getElementById(\"impersonateBanner\");\n    banner.classList.add(\"hidden\");\n    banner.style.display = \"none\";\n    updateMyProfileDisplay();\n}\n\ndocument.getElementById(\"impersonateExitBtn\").onclick = () => {\n    stopImpersonation();\n    alert(\"Admin kimli\u011fine d\u00f6nd\u00fcn.\");\n};\n\ndocument.getElementById(\"sideAccAddBtn\").onclick = async () => {\n    const msg = document.getElementById(\"sideAccMsg\");\n    const username = normalizeUsername(document.getElementById(\"sideAccUser\").value || \"\");\n    const password = document.getElementById(\"sideAccPass\").value || \"\";\n    const isAdmin = await isCurrentUserAdmin();\n    if (!username) {\n        msg.style.color = \"#ff7777\";\n        msg.textContent = \"Kullan\u0131c\u0131 ad\u0131 gerekli.\";\n        return;\n    }\n    if (!isAdmin && !password) {\n        msg.style.color = \"#ff7777\";\n        msg.textContent = \"\u015eifre gerekli (admin de\u011filsen).\";\n        return;\n    }\n    if (!currentUser) return;\n    try {\n        const uidSnap = await get(ref(database, \"usernames\/\" + username));\n        if (!uidSnap.exists()) {\n            msg.style.color = \"#ff7777\";\n            msg.textContent = \"Kullan\u0131c\u0131 bulunamad\u0131.\";\n            return;\n        }\n        const otherUid = uidSnap.val();\n        if (otherUid === currentUser.uid) {\n            msg.style.color = \"#ff7777\";\n            msg.textContent = \"Kendi hesab\u0131n\u0131 ekleyemezsin.\";\n            return;\n        }\n        const profile = await getUserProfile(otherUid);\n        await set(ref(database, \"multiAccounts\/\" + currentUser.uid + \"\/\" + otherUid), {\n            username,\n            displayName: profile?.displayName || username,\n            linkedAt: Date.now()\n        });\n        msg.style.color = \"#23a559\";\n        msg.textContent = isAdmin\n            ? \"Eklendi. Admin olarak Ge\u00e7 \u2192 \u015fifresiz.\"\n            : \"Yan hesap eklendi. Ge\u00e7i\u015fte \u015fifre sorulur.\";\n        document.getElementById(\"sideAccUser\").value = \"\";\n        document.getElementById(\"sideAccPass\").value = \"\";\n        loadSideAccountsUI();\n    } catch (e) {\n        msg.style.color = \"#ff7777\";\n        msg.textContent = e.message || \"Eklenemedi\";\n    }\n};\n\ndocument.getElementById(\"adminLoginBtn\").onclick = async () => {\n    if (!(await isCurrentUserAdmin())) {\n        alert(\"Sadece admin.\");\n        return;\n    }\n    const username = normalizeUsername(document.getElementById(\"adminLoginUser\").value || \"\");\n    if (!username) return alert(\"Kullan\u0131c\u0131 ad\u0131 yaz.\");\n    \/\/ Admin \u015fifresiz\n    await switchToSideAccount(username);\n};\n\ndocument.getElementById(\"settingsCloseBtn\").onclick = () => {\n    document.getElementById(\"settingsModal\").classList.add(\"hidden\");\n};\n\ndocument.getElementById(\"changePasswordBtn\").onclick = async () => {\n    const msg = document.getElementById(\"passwordMessage\");\n    msg.style.color = \"#ff7777\";\n    msg.textContent = \"\";\n    const currentPw = document.getElementById(\"currentPasswordInput\").value;\n    const newPw = document.getElementById(\"newPasswordInput\").value;\n    const newPwAgain = document.getElementById(\"newPasswordAgainInput\").value;\n\n    if (!currentPw || !newPw) {\n        msg.textContent = \"Mevcut ve yeni \u015fifreyi yaz.\";\n        return;\n    }\n    if (newPw.length < 6) {\n        msg.textContent = \"Yeni \u015fifre en az 6 karakter olmal\u0131.\";\n        return;\n    }\n    if (newPw !== newPwAgain) {\n        msg.textContent = \"Yeni \u015fifreler ayn\u0131 de\u011fil.\";\n        return;\n    }\n    if (!currentUser || !currentUser.email) {\n        msg.textContent = \"Oturum bulunamad\u0131.\";\n        return;\n    }\n\n    try {\n        const credential = EmailAuthProvider.credential(currentUser.email, currentPw);\n        await reauthenticateWithCredential(currentUser, credential);\n        await updatePassword(currentUser, newPw);\n        msg.style.color = \"#23a559\";\n        msg.textContent = \"\u2705 \u015eifre de\u011fi\u015ftirildi.\";\n        document.getElementById(\"currentPasswordInput\").value = \"\";\n        document.getElementById(\"newPasswordInput\").value = \"\";\n        document.getElementById(\"newPasswordAgainInput\").value = \"\";\n    } catch (e) {\n        console.error(e);\n        if (e.code === \"auth\/wrong-password\" || e.code === \"auth\/invalid-credential\") {\n            msg.textContent = \"Mevcut \u015fifre yanl\u0131\u015f.\";\n        } else if (e.code === \"auth\/weak-password\") {\n            msg.textContent = \"Yeni \u015fifre \u00e7ok zay\u0131f.\";\n        } else if (e.code === \"auth\/requires-recent-login\") {\n            msg.textContent = \"G\u00fcvenlik i\u00e7in tekrar giri\u015f yap, sonra dene.\";\n        } else {\n            msg.textContent = \"Hata: \" + (e.message || e.code);\n        }\n    }\n};\n\nfunction renderSoundList(filter = \"\") {\n    const list = document.getElementById(\"soundList\");\n    list.innerHTML = \"\";\n    const filtered = MYINSTANTS_SOUNDS.filter(s =>\n        s.name.toLowerCase().includes(filter.toLowerCase())\n    );\n    if (filtered.length === 0) {\n        list.innerHTML = `<div style=\"padding:15px;color:#949ba4;text-align:center;\">Sonu\u00e7 bulunamad\u0131<\/div>`;\n        return;\n    }\n    filtered.forEach(sound => {\n        const item = document.createElement(\"div\");\n        item.className = \"soundItem\" + (sound.url === selectedSoundUrl ? \" selected\" : \"\");\n        item.innerHTML = `\n            <div class=\"soundName\">${sound.name}<\/div>\n            <button class=\"soundPlayBtn\">\u25b6<\/button>\n            <button class=\"soundSelectBtn\">Se\u00e7<\/button>\n        `;\n        item.querySelector(\".soundPlayBtn\").onclick = (e) => {\n            e.stopPropagation();\n            audioPlayer.src = sound.url;\n            audioPlayer.play().catch(() => alert(\"Ses \u00e7al\u0131namad\u0131 (CORS veya link hatas\u0131)\"));\n        };\n        item.querySelector(\".soundSelectBtn\").onclick = (e) => {\n            e.stopPropagation();\n            selectedSoundUrl = sound.url;\n            localStorage.setItem(\"vegamedia_notif_sound\", selectedSoundUrl);\n            renderSoundList(document.getElementById(\"soundSearchInput\").value);\n            updateCurrentSoundInfo();\n        };\n        list.appendChild(item);\n    });\n}\n\ndocument.getElementById(\"soundSearchInput\").addEventListener(\"input\", e => {\n    renderSoundList(e.target.value);\n});\n\ndocument.getElementById(\"previewCustomBtn\").onclick = () => {\n    const url = document.getElementById(\"customSoundUrl\").value.trim();\n    if (!url) return alert(\"Link gir\");\n    audioPlayer.src = url;\n    audioPlayer.play().catch(() => alert(\"Bu link \u00e7al\u0131namad\u0131. Do\u011frudan .mp3 linki olmal\u0131.\"));\n};\n\ndocument.getElementById(\"saveCustomBtn\").onclick = () => {\n    const url = document.getElementById(\"customSoundUrl\").value.trim();\n    if (!url || !url.includes(\".mp3\")) return alert(\"Ge\u00e7erli bir .mp3 linki gir\");\n    selectedSoundUrl = url;\n    localStorage.setItem(\"vegamedia_notif_sound\", selectedSoundUrl);\n    updateCurrentSoundInfo();\n    alert(\"\u00d6zel ses kaydedildi!\");\n};\n\nfunction updateCurrentSoundInfo() {\n    const info = document.getElementById(\"currentSoundInfo\");\n    const found = MYINSTANTS_SOUNDS.find(s => s.url === selectedSoundUrl);\n    info.textContent = found\n        ? `\u015eu an se\u00e7ili: ${found.name}`\n        : `\u015eu an se\u00e7ili: \u00d6zel ses`;\n}\n\n\n\/* =========================================================\n   YEN\u0130 B\u00d6L\u00dcM \u2014 ortak yard\u0131mc\u0131lar\n========================================================= *\/\nconst liveScreen = document.getElementById(\"liveScreen\");\nconst profileScreen = document.getElementById(\"profileScreen\");\nconst voiceScreen = document.getElementById(\"voiceScreen\");\nconst mediaScreen = document.getElementById(\"mediaScreen\");\nconst lastSentAt = {};\n\nfunction hideExtraScreens(keep) {\n    if (keep !== \"live\") {\n        liveScreen.classList.remove(\"active\");\n        document.getElementById(\"liveButton\")?.classList.remove(\"active\");\n        if (typeof live !== \"undefined\" && live.role === \"viewer\") leaveLiveView(true);\n    }\n    if (keep !== \"profile\") {\n        profileScreen.classList.remove(\"active\");\n        document.getElementById(\"myProfileButton\")?.classList.remove(\"active\");\n    }\n    if (keep !== \"voice\") {\n        voiceScreen.classList.remove(\"active\");\n        document.getElementById(\"voiceButton\")?.classList.remove(\"active\");\n    }\n    if (keep !== \"media\") {\n        mediaScreen.classList.remove(\"active\");\n        document.getElementById(\"mediaButton\")?.classList.remove(\"active\");\n    }\n}\n\nfunction localSystemMessage(text) {\n    const div = document.createElement(\"div\");\n    div.className = \"sysMsg\";\n    div.textContent = text;\n    messagesContainer.appendChild(div);\n    messagesContainer.scrollTop = messagesContainer.scrollHeight;\n}\n\nasync function bumpStat(field, n = 1) {\n    if (!currentUser) return;\n    try {\n        const r = ref(database, \"users\/\" + currentUser.uid + \"\/stats\/\" + field);\n        const s = await get(r);\n        await set(r, (s.val() || 0) + n);\n    } catch (_) {}\n}\n\nfunction activeMessagesPath() {\n    if (activeChatType === \"private\" && activeChatId) return \"privateMessages\/\" + activeChatId;\n    if (activeChatType === \"group\" && activeGroupId) return \"groupMessages\/\" + activeGroupId;\n    if (CHANNELS[activeChatType]) return CHANNELS[activeChatType].path;\n    return \"messages\/general\";\n}\n\nasync function resolveUid(name) {\n    const snap = await get(ref(database, \"usernames\/\" + normalizeUsername(name || \"\")));\n    return snap.exists() ? snap.val() : null;\n}\n\nfunction showPageButton(btnId) {\n    document.querySelectorAll(\".channelButton\").forEach(b => b.classList.remove(\"active\"));\n    document.querySelectorAll(\".privateChatItem\").forEach(el => el.classList.remove(\"active\"));\n    if (btnId) document.getElementById(btnId)?.classList.add(\"active\");\n}\n\nfunction hideMainAreas() {\n    mainChatArea.style.display = \"none\";\n    shortsScreen.classList.remove(\"active\");\n    gamesScreen.classList.remove(\"active\");\n}\n\n\/* =========================================================\n   VV \u2014 kullan\u0131c\u0131 videolar\u0131 (Storage + RTDB)\n========================================================= *\/\n\n\n\/* ========== MEDYA \u2014 t\u00fcm profiller ========== *\/\nlet mediaCache = [];\n\nasync function openMediaPage() {\n    hideExtraScreens(\"media\");\n    hideMainAreas();\n    profileScreen.classList.remove(\"active\");\n    activeChatType = \"media\";\n    showPageButton(\"mediaButton\");\n    mediaScreen.classList.add(\"active\");\n    closeSidebar();\n    await loadMediaProfiles();\n}\ndocument.getElementById(\"mediaButton\").onclick = openMediaPage;\ndocument.getElementById(\"mediaMenuBtn\").onclick = openSidebar;\ndocument.getElementById(\"mediaRefreshBtn\").onclick = () => { mediaCache = []; loadMediaProfiles(); };\ndocument.getElementById(\"mediaSearchInput\").addEventListener(\"input\", e => {\n    renderMediaGrid(e.target.value);\n});\n\nasync function loadMediaProfiles() {\n    const grid = document.getElementById(\"mediaGrid\");\n    const sub = document.getElementById(\"mediaSubtitle\");\n    if (!grid) return;\n    grid.innerHTML = `<div class=\"liveNote\">Profiller y\u00fckleniyor...<\/div>`;\n    try {\n        if (!mediaCache.length) {\n            const snap = await get(ref(database, \"usernames\"));\n            if (!snap.exists()) {\n                grid.innerHTML = `<div class=\"liveNote\">Hen\u00fcz kullan\u0131c\u0131 yok.<\/div>`;\n                if (sub) sub.textContent = \"0 profil\";\n                return;\n            }\n            const entries = Object.entries(snap.val());\n            const list = [];\n            for (const [uname, uid] of entries) {\n                const p = await getUserProfile(uid);\n                if (!p) continue;\n                let videoCount = 0;\n                try {\n                    const vs = await get(ref(database, \"userVideosByUser\/\" + uid));\n                    if (vs.exists()) videoCount = Object.keys(vs.val()).length;\n                } catch (_) {}\n                let online = false;\n                try {\n                    const st = await get(ref(database, \"status\/\" + uid));\n                    if (st.exists() && st.val().state === \"online\") online = true;\n                } catch (_) {}\n                list.push({\n                    uid,\n                    username: p.username || uname,\n                    displayName: p.displayName || uname,\n                    about: p.about || \"\",\n                    photoData: p.photoData || \"\",\n                    xp: p.xp || 0,\n                    level: p.level || 1,\n                    videoCount,\n                    online\n                });\n            }\n            list.sort((a, b) => {\n                if (a.online !== b.online) return a.online ? -1 : 1;\n                return (b.xp || 0) - (a.xp || 0);\n            });\n            mediaCache = list;\n        }\n        if (sub) sub.textContent = mediaCache.length + \" profil\";\n        renderMediaGrid(document.getElementById(\"mediaSearchInput\")?.value || \"\");\n    } catch (e) {\n        grid.innerHTML = `<div class=\"liveNote\" style=\"color:#ff7777;\">Y\u00fcklenemedi: ${escapeHtml(e.message || String(e))}<\/div>`;\n    }\n}\n\nfunction renderMediaGrid(filter) {\n    const grid = document.getElementById(\"mediaGrid\");\n    if (!grid) return;\n    const q = (filter || \"\").trim().toLowerCase();\n    const list = q\n        ? mediaCache.filter(u =>\n            (u.displayName || \"\").toLowerCase().includes(q) ||\n            (u.username || \"\").toLowerCase().includes(q) ||\n            (u.about || \"\").toLowerCase().includes(q))\n        : mediaCache;\n    if (!list.length) {\n        grid.innerHTML = `<div class=\"liveNote\">Sonu\u00e7 yok<\/div>`;\n        return;\n    }\n    grid.innerHTML = \"\";\n    list.forEach(u => {\n        const card = document.createElement(\"div\");\n        card.className = \"mediaCard\";\n        const av = document.createElement(\"div\");\n        av.className = \"avatar\";\n        setAvatar(av, u);\n        card.appendChild(av);\n        const name = document.createElement(\"div\");\n        name.className = \"mediaCardName\";\n        name.textContent = (u.online ? \"\ud83d\udfe2 \" : \"\") + (u.displayName || \"?\");\n        card.appendChild(name);\n        const un = document.createElement(\"div\");\n        un.className = \"mediaCardUser\";\n        un.textContent = \"@\" + (u.username || \"\");\n        card.appendChild(un);\n        if (u.about) {\n            const ab = document.createElement(\"div\");\n            ab.className = \"mediaCardAbout\";\n            ab.textContent = u.about;\n            card.appendChild(ab);\n        }\n        const meta = document.createElement(\"div\");\n        meta.className = \"mediaCardMeta\";\n        meta.textContent = \"Lv \" + (u.level || 1) + \" \u00b7 XP \" + (u.xp || 0) +\n            (u.videoCount ? \" \u00b7 \ud83c\udfac \" + u.videoCount : \"\");\n        card.appendChild(meta);\n        card.onclick = () => viewProfile(u.uid);\n        grid.appendChild(card);\n    });\n}\n\n\nfunction extractYouTubeId(url) {\n    if (!url) return null;\n    const m = String(url).match(\/(?:youtu\\.be\\\/|youtube\\.com\\\/(?:watch\\?v=|embed\\\/|shorts\\\/|live\\\/)|youtube\\.com\\\/v\\\/)([A-Za-z0-9_-]{6,})\/);\n    return m ? m[1] : null;\n}\n\nfunction extractTikTokId(url) {\n    if (!url) return null;\n    const m = String(url).match(\/tiktok\\.com\\\/(?:@[\\w.-]+\\\/video\\\/|v\\\/|embed\\\/v2\\\/)?(\\d{8,})\/i)\n        || String(url).match(\/vm\\.tiktok\\.com\\\/([A-Za-z0-9]+)\/);\n    return m ? m[1] : null;\n}\n\nfunction extractInstagramCode(url) {\n    if (!url) return null;\n    const m = String(url).match(\/instagram\\.com\\\/(?:p|reel|reels|tv)\\\/([A-Za-z0-9_-]+)\/i);\n    return m ? m[1] : null;\n}\n\nfunction parseVideoLink(url) {\n    url = (url || \"\").trim();\n    if (!url) return null;\n    const yt = extractYouTubeId(url);\n    if (yt) return { type: \"youtube\", id: yt, embed: \"https:\/\/www.youtube.com\/embed\/\" + yt + \"?playsinline=1&rel=0\", url };\n    const tk = extractTikTokId(url);\n    if (tk && \/^\\d+$\/.test(tk)) return { type: \"tiktok\", id: tk, embed: \"https:\/\/www.tiktok.com\/embed\/v2\/\" + tk, url };\n    if (tk) return { type: \"tiktok\", id: tk, embed: null, url }; \/\/ k\u0131sa link \u2014 yeni sekmede a\u00e7\n    const ig = extractInstagramCode(url);\n    if (ig) return { type: \"instagram\", id: ig, embed: \"https:\/\/www.instagram.com\/p\/\" + ig + \"\/embed\", url };\n    if (\/\\.(mp4|webm|ogg)(\\?|$)\/i.test(url) || \/googlevideo|video\\.twimg\/i.test(url)) {\n        return { type: \"direct\", id: null, embed: null, url };\n    }\n    if (\/^https?:\\\/\\\/\/i.test(url)) return { type: \"url\", id: null, embed: null, url };\n    return null;\n}\n\nfunction isDirectVideoUrl(url) {\n    return \/\\.(mp4|webm|ogg)(\\?|$)\/i.test(url || \"\") || \/googlevideo|video\\.twimg|cdn\\.|vimeo\/i.test(url || \"\");\n}\n\nfunction buildVVMediaHtml(v) {\n    const info = parseVideoLink(v.url || \"\");\n    if (!info) return `<div style=\"color:#fff;padding:20px;\">Ge\u00e7ersiz video linki<\/div>`;\n    if (info.embed) {\n        return `<iframe src=\"${escapeHtml(info.embed)}\" allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture\" allowfullscreen style=\"width:100%;height:100%;max-width:480px;border:none;background:#000;\"><\/iframe>`;\n    }\n    if (info.type === \"direct\" || isDirectVideoUrl(info.url)) {\n        return `<video src=\"${escapeHtml(info.url)}\" playsinline controls loop style=\"width:100%;height:100%;max-width:480px;object-fit:contain;\"><\/video>`;\n    }\n    return `<div style=\"color:#fff;padding:24px;text-align:center;\">\n        <div style=\"margin-bottom:12px;\">${info.type === \"tiktok\" ? \"TikTok\" : info.type === \"instagram\" ? \"Instagram\" : \"Video\"}<\/div>\n        <a href=\"${escapeHtml(info.url)}\" target=\"_blank\" rel=\"noopener\" style=\"color:#7289da;\">Linki a\u00e7 \u2197<\/a>\n    <\/div>`;\n}\n\n\/** Profil videosuna t\u0131klan\u0131nca tam ekran oynat\u0131c\u0131 *\/\nfunction openProfileVideoPlayer(v, videoId) {\n    hideExtraScreens();\n    hideMainAreas();\n    shortsScreen.classList.add(\"active\");\n    activeChatType = \"shorts\";\n    document.querySelectorAll(\".channelButton\").forEach(btn => btn.classList.remove(\"active\"));\n    document.getElementById(\"shortsButton\")?.classList.add(\"active\");\n    const container = document.getElementById(\"shortsContainer\");\n    container.innerHTML = \"\";\n    const item = document.createElement(\"div\");\n    item.className = \"shortItem\";\n    item.style.position = \"relative\";\n    item.innerHTML = `\n        ${buildVVMediaHtml(v)}\n        <div class=\"shortOverlay\">\n            <div class=\"shortTitle\">${escapeHtml(v.title || \"Video\")}<\/div>\n            <div class=\"shortChannel\">@${escapeHtml(v.username || \"?\")} \u00b7 ${escapeHtml(v.displayName || \"\")}<\/div>\n        <\/div>`;\n    if (videoId) bindVideoSocialUI(item, videoId, v);\n    container.appendChild(item);\n    closeSidebar();\n}\n\nasync function toggleVideoLike(videoId) {\n    if (!currentUser || !videoId) return;\n    const likeRef = ref(database, \"userVideoLikes\/\" + videoId + \"\/\" + currentUser.uid);\n    const snap = await get(likeRef);\n    if (snap.exists()) await remove(likeRef);\n    else await set(likeRef, { at: Date.now(), name: currentProfile.displayName });\n}\n\nasync function countLikes(videoId) {\n    try {\n        const s = await get(ref(database, \"userVideoLikes\/\" + videoId));\n        return s.exists() ? Object.keys(s.val()).length : 0;\n    } catch (_) { return 0; }\n}\n\nasync function hasLiked(videoId) {\n    if (!currentUser) return false;\n    try {\n        const s = await get(ref(database, \"userVideoLikes\/\" + videoId + \"\/\" + currentUser.uid));\n        return s.exists();\n    } catch (_) { return false; }\n}\n\nasync function postVideoComment(videoId, text) {\n    text = (text || \"\").trim().slice(0, 300);\n    if (!text || !currentUser) return;\n    await push(ref(database, \"userVideoComments\/\" + videoId), {\n        uid: currentUser.uid,\n        name: currentProfile.displayName,\n        username: currentProfile.username,\n        text,\n        at: Date.now()\n    });\n}\n\nasync function isSubscribedTo(creatorUid) {\n    if (!currentUser || !creatorUid) return false;\n    try {\n        const s = await get(ref(database, \"subscriptions\/\" + currentUser.uid + \"\/\" + creatorUid));\n        return s.exists();\n    } catch (_) { return false; }\n}\n\nasync function toggleSubscribe(creatorUid, profile) {\n    if (!currentUser || !creatorUid || creatorUid === currentUser.uid) return;\n    const subRef = ref(database, \"subscriptions\/\" + currentUser.uid + \"\/\" + creatorUid);\n    const subSnap = await get(subRef);\n    if (subSnap.exists()) {\n        await remove(subRef);\n        await remove(ref(database, \"subscribers\/\" + creatorUid + \"\/\" + currentUser.uid));\n        return false;\n    }\n    await set(subRef, {\n        uid: creatorUid,\n        username: profile?.username || \"\",\n        displayName: profile?.displayName || \"\",\n        at: Date.now()\n    });\n    await set(ref(database, \"subscribers\/\" + creatorUid + \"\/\" + currentUser.uid), {\n        uid: currentUser.uid,\n        username: currentProfile.username,\n        displayName: currentProfile.displayName,\n        at: Date.now()\n    });\n    return true;\n}\n\nasync function countSubscribers(creatorUid) {\n    try {\n        const s = await get(ref(database, \"subscribers\/\" + creatorUid));\n        return s.exists() ? Object.keys(s.val()).length : 0;\n    } catch (_) { return 0; }\n}\n\nasync function recordVideoView(videoId) {\n    if (!currentUser || !videoId) return;\n    try {\n        await set(ref(database, \"userVideoViews\/\" + videoId + \"\/\" + currentUser.uid), {\n            uid: currentUser.uid,\n            name: currentProfile.displayName || currentProfile.username || \"?\",\n            username: currentProfile.username || \"\",\n            at: Date.now()\n        });\n    } catch (_) {}\n}\n\nasync function countViews(videoId) {\n    try {\n        const s = await get(ref(database, \"userVideoViews\/\" + videoId));\n        return s.exists() ? Object.keys(s.val()).length : 0;\n    } catch (_) { return 0; }\n}\n\nasync function showViewersList(videoId) {\n    try {\n        const s = await get(ref(database, \"userVideoViews\/\" + videoId));\n        if (!s.exists()) return alert(\"Hen\u00fcz izleyen yok.\");\n        const rows = Object.values(s.val()).sort((a, b) => (b.at || 0) - (a.at || 0));\n        const text = rows.slice(0, 40).map((r, i) =>\n            (i + 1) + \". \" + (r.name || r.username || \"?\") + (r.username ? \" (@\" + r.username + \")\" : \"\")\n        ).join(\"\\n\");\n        alert(\"\ud83d\udc41 \u0130zleyenler (\" + rows.length + \"):\\n\\n\" + text + (rows.length > 40 ? \"\\n\u2026\" : \"\"));\n    } catch (e) {\n        alert(\"\u0130zleyenler al\u0131namad\u0131: \" + (e.message || e));\n    }\n}\n\nfunction bindVideoSocialUI(itemEl, videoId, v) {\n    \/\/ izlenme kayd\u0131 (her g\u00f6sterimde bir kez)\n    if (videoId && currentUser) recordVideoView(videoId);\n\n    const side = document.createElement(\"div\");\n    side.className = \"vvSideActions\";\n    side.innerHTML = `\n        <button type=\"button\" class=\"vvSideBtn\" data-act=\"views\" title=\"\u0130zleyenler\">\ud83d\udc41<\/button>\n        <div class=\"vvSideCount\" data-view-count style=\"cursor:pointer;\">0<\/div>\n        <button type=\"button\" class=\"vvSideBtn\" data-act=\"like\" title=\"Be\u011fen\">\u2764\ufe0f<\/button>\n        <div class=\"vvSideCount\" data-like-count>0<\/div>\n        <button type=\"button\" class=\"vvSideBtn\" data-act=\"comment\" title=\"Yorum\">\ud83d\udcac<\/button>\n        <div class=\"vvSideCount\" data-cmt-count>0<\/div>\n        <button type=\"button\" class=\"vvSideBtn\" data-act=\"sub\" title=\"Abone ol\">\u2795<\/button>\n        <div class=\"vvSideCount\" data-sub-label>Abone<\/div>\n        <button type=\"button\" class=\"vvSideBtn\" data-act=\"share\" title=\"Link kopyala\">\ud83d\udd17<\/button>\n        <button type=\"button\" class=\"vvSideBtn\" data-act=\"profile\" title=\"Profil\">\ud83d\udc64<\/button>`;\n    itemEl.appendChild(side);\n\n    const cbox = document.createElement(\"div\");\n    cbox.className = \"vvCommentBox\";\n    cbox.innerHTML = `\n        <div style=\"display:flex;justify-content:space-between;align-items:center;margin-bottom:8px;\">\n            <b>Yorumlar<\/b>\n            <button type=\"button\" data-close-cmt style=\"border:none;background:#404249;color:#fff;border-radius:6px;padding:4px 10px;\">Kapat<\/button>\n        <\/div>\n        <div class=\"vvCommentList\" data-cmt-list><\/div>\n        <div style=\"display:flex;gap:6px;\">\n            <input data-cmt-input class=\"liveInput\" placeholder=\"Yorum yaz...\" maxlength=\"300\" style=\"flex:1;\">\n            <button type=\"button\" data-cmt-send class=\"liveBtn green\">G\u00f6nder<\/button>\n        <\/div>`;\n    itemEl.appendChild(cbox);\n\n    const likeBtn = side.querySelector('[data-act=\"like\"]');\n    const likeCount = side.querySelector(\"[data-like-count]\");\n    const cmtCount = side.querySelector(\"[data-cmt-count]\");\n    const viewCount = side.querySelector(\"[data-view-count]\");\n    const subBtn = side.querySelector('[data-act=\"sub\"]');\n    const subLabel = side.querySelector(\"[data-sub-label]\");\n\n    async function refreshCounts() {\n        const [lc, liked, vc] = await Promise.all([\n            countLikes(videoId), hasLiked(videoId), countViews(videoId)\n        ]);\n        likeCount.textContent = lc;\n        viewCount.textContent = vc;\n        likeBtn.classList.toggle(\"liked\", liked);\n        likeBtn.textContent = liked ? \"\ud83d\udc94\" : \"\u2764\ufe0f\";\n        try {\n            const cs = await get(ref(database, \"userVideoComments\/\" + videoId));\n            cmtCount.textContent = cs.exists() ? Object.keys(cs.val()).length : 0;\n        } catch (_) { cmtCount.textContent = \"0\"; }\n        if (v.uid && v.uid !== currentUser?.uid) {\n            const subbed = await isSubscribedTo(v.uid);\n            subBtn.textContent = subbed ? \"\u2713\" : \"\u2795\";\n            subLabel.textContent = subbed ? \"Abone\" : \"Abone ol\";\n            const sc = await countSubscribers(v.uid);\n            if (sc) subLabel.textContent = (subbed ? \"Abone \u00b7 \" : \"\") + sc;\n        } else {\n            subBtn.style.display = \"none\";\n            subLabel.style.display = \"none\";\n        }\n    }\n    refreshCounts();\n\n    const openViewers = (e) => {\n        e.stopPropagation();\n        showViewersList(videoId);\n    };\n    side.querySelector('[data-act=\"views\"]').onclick = openViewers;\n    viewCount.onclick = openViewers;\n\n    side.querySelector('[data-act=\"share\"]').onclick = async (e) => {\n        e.stopPropagation();\n        const link = v.url || (location.href + \"#video-\" + videoId);\n        try {\n            await navigator.clipboard.writeText(link);\n            alert(\"Link kopyaland\u0131!\");\n        } catch (_) {\n            prompt(\"Kopyala:\", link);\n        }\n    };\n\n    likeBtn.onclick = async (e) => {\n        e.stopPropagation();\n        try {\n            await toggleVideoLike(videoId);\n            await refreshCounts();\n        } catch (err) { alert(\"Be\u011feni: \" + (err.message || err)); }\n    };\n\n    side.querySelector('[data-act=\"comment\"]').onclick = async (e) => {\n        e.stopPropagation();\n        cbox.classList.add(\"show\");\n        const list = cbox.querySelector(\"[data-cmt-list]\");\n        list.innerHTML = \"Y\u00fckleniyor...\";\n        try {\n            const cs = await get(ref(database, \"userVideoComments\/\" + videoId));\n            if (!cs.exists()) list.innerHTML = `<div style=\"color:#949ba4;padding:8px;\">Hen\u00fcz yorum yok<\/div>`;\n            else {\n                list.innerHTML = \"\";\n                Object.values(cs.val())\n                    .sort((a, b) => (a.at || 0) - (b.at || 0))\n                    .forEach(c => {\n                        const row = document.createElement(\"div\");\n                        row.className = \"vvCommentRow\";\n                        row.innerHTML = `<b>@${escapeHtml(c.username || c.name || \"?\")}<\/b> ${escapeHtml(c.text || \"\")}`;\n                        list.appendChild(row);\n                    });\n            }\n        } catch (_) { list.innerHTML = \"Yorumlar al\u0131namad\u0131\"; }\n    };\n    cbox.querySelector(\"[data-close-cmt]\").onclick = (e) => {\n        e.stopPropagation();\n        cbox.classList.remove(\"show\");\n    };\n    cbox.querySelector(\"[data-cmt-send]\").onclick = async (e) => {\n        e.stopPropagation();\n        const input = cbox.querySelector(\"[data-cmt-input]\");\n        try {\n            await postVideoComment(videoId, input.value);\n            input.value = \"\";\n            side.querySelector('[data-act=\"comment\"]').click();\n            await refreshCounts();\n        } catch (err) { alert(\"Yorum: \" + (err.message || err)); }\n    };\n\n    subBtn.onclick = async (e) => {\n        e.stopPropagation();\n        if (!v.uid || v.uid === currentUser.uid) return;\n        try {\n            const on = await toggleSubscribe(v.uid, v);\n            alert(on ? \"@\" + (v.username || \"\") + \" kanal\u0131na abone oldun!\" : \"Abonelik iptal edildi.\");\n            await refreshCounts();\n        } catch (err) { alert(\"Abone: \" + (err.message || err)); }\n    };\n\n    side.querySelector('[data-act=\"profile\"]').onclick = (e) => {\n        e.stopPropagation();\n        if (v.uid) viewProfile(v.uid);\n    };\n}\n\n\/* VV kald\u0131r\u0131ld\u0131 \u2014 videolar Shorts'ta (be\u011feni, yorum, abone, izlenme) *\/\n\nasync function addProfileVideoLink(url, title) {\n    if (!currentUser) throw new Error(\"Giri\u015f gerekli \u2014 sayfay\u0131 yenile ve tekrar giri\u015f yap.\");\n    url = (url || \"\").trim();\n    if (!url) throw new Error(\"Video linki yaz.\");\n    if (!\/^https?:\\\/\\\/\/i.test(url)) url = \"https:\/\/\" + url;\n    if (!\/^https?:\\\/\\\/\/i.test(url)) throw new Error(\"Link http:\/\/ veya https:\/\/ ile ba\u015flamal\u0131.\");\n    const info = parseVideoLink(url);\n    if (!info) throw new Error(\"Ge\u00e7erli YouTube, TikTok, Instagram veya .mp4 linki gir.\");\n    const id = push(ref(database, \"userVideos\")).key;\n    if (!id) throw new Error(\"Video id olu\u015fturulamad\u0131\");\n    const meta = {\n        uid: currentUser.uid,\n        username: (currentProfile && currentProfile.username) || \"user\",\n        displayName: (currentProfile && currentProfile.displayName) || \"Kullan\u0131c\u0131\",\n        title: String(title || (info.type === \"tiktok\" ? \"TikTok\" : info.type === \"instagram\" ? \"Instagram\" : info.type === \"youtube\" ? \"YouTube\" : \"Video\")).slice(0, 80),\n        url: url.slice(0, 500),\n        type: info.type,\n        createdAt: Date.now()\n    };\n    try {\n        await set(ref(database, \"userVideos\/\" + id), meta);\n        await set(ref(database, \"userVideosByUser\/\" + currentUser.uid + \"\/\" + id), meta);\n    } catch (e) {\n        const m = e.message || String(e);\n        if (\/PERMISSION|permission|denied\/i.test(m)) {\n            throw new Error(\"\u0130zin yok: Firebase Rules'ta userVideos yazma iznini Publish et.\");\n        }\n        throw e;\n    }\n    return meta;\n}\n\n\/* =========================================================\n   YEN\u0130 KOMUTLAR\n========================================================= *\/\nconst HELP_TEXT = [\n    \"Herkes i\u00e7in:\",\n    \"\/help \u2014 bu liste\",\n    \"\/roll [say\u0131] \u2014 zar (varsay\u0131lan 6)\",\n    \"\/8ball soru \u2014 sihirli 8 topu\",\n    \"\/me eylem \u2014 eylem mesaj\u0131\",\n    \"\/shrug \u2014 omuz silk\",\n    \"\/coinflip \u2014 yaz\u0131 tura\",\n    \"\/stats \u2014 kendi XP ve seviyen\",\n    \"\",\n    \"Admin i\u00e7in:\",\n    \"\/giveadmin kullanici, \/dontadmin kullanici\",\n    \"\/ban, \/unban, \/bans (liste)\",\n    \"\/mute kullanici dk, \/unmute kullanici\",\n    \"\/rename kullanici YeniAd\",\n    \"\/sayas kullanici mesaj\",\n    \"\/announce mesaj, \/warn kullanici sebep\",\n    \"\/clear N, \/users, \/whois kullanici\",\n    \"\/xp kullanici miktar (eksi de olur)\",\n    \"\/slow saniye (0 = kapat), \/lock, \/unlock\",\n    \"\/poll soru \u2014 \ud83d\udc4d\u2764\ufe0f\ud83d\ude02 tepkileriyle anket\",\n    \"\/endlive kullanici \u2014 yay\u0131n\u0131 kapat\",\n    \"\/trivia \u2014 bilgi yar\u0131\u015fmas\u0131\"\n].join(\"\\n\");\n\nasync function handleExtraCommand(text, parts, lower) {\n    const cmd = parts[0].toLowerCase();\n    const PUBLIC = [\"\/help\", \"\/roll\", \"\/8ball\", \"\/me\", \"\/shrug\", \"\/stats\"];\n    const ADMIN = [\"\/giveadmin\", \"\/dontadmin\", \"\/bans\", \"\/whois\", \"\/xp\", \"\/slow\", \"\/lock\", \"\/unlock\", \"\/poll\", \"\/warn\", \"\/endlive\"];\n    if (!PUBLIC.includes(cmd) && !ADMIN.includes(cmd)) return false;\n\n    const base = activeMessagesPath();\n    const myName = currentProfile?.displayName || \"Biri\";\n\n    if (cmd === \"\/help\") { localSystemMessage(HELP_TEXT); return true; }\n\n    if (cmd === \"\/stats\") {\n        const xp = currentProfile.xp || 0;\n        localSystemMessage(\"XP: \" + xp + \" \u00b7 Seviye: \" + xpToLevel(xp) + \" \u00b7 Sonraki seviyeye: \" + (50 - (xp % 50)) + \" XP\");\n        return true;\n    }\n    if (cmd === \"\/roll\") {\n        const max = Math.min(1000000, Math.max(2, parseInt(parts[1], 10) || 6));\n        await push(ref(database, base), { uid: currentUser.uid, text: \"\ud83c\udfb2 \" + myName + \" zar att\u0131 (1-\" + max + \"): **\" + (Math.floor(Math.random() * max) + 1) + \"**\", timestamp: Date.now() });\n        return true;\n    }\n    if (cmd === \"\/8ball\") {\n        const answers = [\"Kesinlikle evet.\", \"B\u00fcy\u00fck ihtimalle evet.\", \"Belli de\u011fil, tekrar sor.\", \"Pek sanm\u0131yorum.\", \"Hay\u0131r.\", \"\u015eimdilik s\u00f6yleyemem.\", \"\u0130\u015faretler olumlu.\", \"Buna g\u00fcvenme.\"];\n        const q = parts.slice(1).join(\" \").trim() || \"...\";\n        await push(ref(database, base), { uid: currentUser.uid, text: \"\ud83c\udfb1 \" + q + \" \u2192 **\" + answers[Math.floor(Math.random() * answers.length)] + \"**\", timestamp: Date.now() });\n        return true;\n    }\n    if (cmd === \"\/me\") {\n        const act = parts.slice(1).join(\" \").trim();\n        if (!act) return true;\n        await push(ref(database, base), { uid: currentUser.uid, text: \"_\" + myName + \" \" + act.slice(0, 200) + \"_\", timestamp: Date.now() });\n        return true;\n    }\n    if (cmd === \"\/shrug\") {\n        await push(ref(database, base), { uid: currentUser.uid, text: \"\u00af\\\\(\u30c4)\/\u00af\", timestamp: Date.now() });\n        return true;\n    }\n\n    \/\/ Buradan sonras\u0131 sadece admin\n    if (!(await isCurrentUserAdmin())) { alert(\"Bu komut i\u00e7in admin olmal\u0131s\u0131n.\"); return true; }\n\n    if (cmd === \"\/giveadmin\" || cmd === \"\/dontadmin\") {\n        if (!parts[1]) { alert(\"Kullan\u0131m: \" + cmd + \" kullanici\"); return true; }\n        const uid = await resolveUid(parts[1]);\n        if (!uid) { alert(\"Kullan\u0131c\u0131 bulunamad\u0131.\"); return true; }\n        if (cmd === \"\/giveadmin\") { await set(ref(database, \"admins\/\" + uid), true); alert(\"\u2705 @\" + parts[1] + \" art\u0131k admin.\"); }\n        else { await remove(ref(database, \"admins\/\" + uid)); alert(\"@\" + parts[1] + \" adminlikten \u00e7\u0131kar\u0131ld\u0131.\"); }\n        return true;\n    }\n    if (cmd === \"\/bans\") {\n        const snap = await get(ref(database, \"banned\"));\n        if (!snap.exists()) { localSystemMessage(\"Banl\u0131 kullan\u0131c\u0131 yok.\"); return true; }\n        const lines = [\"\ud83d\udeab Banl\u0131lar:\"];\n        Object.values(snap.val()).forEach(b => lines.push(\"\u2022 @\" + (b.username || \"?\")));\n        localSystemMessage(lines.join(\"\\n\"));\n        return true;\n    }\n    if (cmd === \"\/whois\") {\n        if (!parts[1]) { alert(\"Kullan\u0131m: \/whois kullanici\"); return true; }\n        const uid = await resolveUid(parts[1]);\n        if (!uid) { alert(\"Kullan\u0131c\u0131 bulunamad\u0131.\"); return true; }\n        const [u, st, ban, mu, ad] = await Promise.all([\n            get(ref(database, \"users\/\" + uid)), get(ref(database, \"status\/\" + uid)),\n            get(ref(database, \"banned\/\" + uid)), get(ref(database, \"muted\/\" + uid)), get(ref(database, \"admins\/\" + uid))\n        ]);\n        const p = u.val() || {};\n        localSystemMessage([\n            \"\ud83d\udd0e @\" + (p.username || parts[1]),\n            \"G\u00f6r\u00fcnen ad: \" + (p.displayName || \"-\"),\n            \"Kay\u0131t: \" + (p.createdAt ? new Date(p.createdAt).toLocaleString(\"tr-TR\") : \"-\"),\n            \"XP: \" + (p.xp || 0) + \" \u00b7 Seviye \" + xpToLevel(p.xp || 0),\n            \"Durum: \" + (st.val()?.state || \"offline\"),\n            \"Admin: \" + (ad.exists() ? \"evet\" : \"hay\u0131r\") + \" \u00b7 Ban: \" + (ban.exists() ? \"evet\" : \"hay\u0131r\") + \" \u00b7 Susturma: \" + ((mu.val()?.until || 0) > Date.now() ? \"var\" : \"yok\"),\n            \"UID: \" + uid\n        ].join(\"\\n\"));\n        return true;\n    }\n    if (cmd === \"\/xp\") {\n        const n = parseInt(parts[2], 10);\n        if (!parts[1] || isNaN(n)) { alert(\"Kullan\u0131m: \/xp kullanici 100\"); return true; }\n        const uid = await resolveUid(parts[1]);\n        if (!uid) { alert(\"Kullan\u0131c\u0131 bulunamad\u0131.\"); return true; }\n        const next = await grantXp(uid, n, \"admin\");\n        alert(\"@\" + parts[1] + \" yeni XP: \" + (next != null ? next : \"?\"));\n        return true;\n    }\n    if (cmd === \"\/slow\") {\n        if (!CHANNELS[activeChatType]) { alert(\"Yava\u015f mod sadece kanallarda.\"); return true; }\n        const s = Math.min(600, Math.max(0, parseInt(parts[1], 10) || 0));\n        await update(ref(database, \"settings\/channels\/\" + activeChatType), { slow: s });\n        alert(s ? \"Yava\u015f mod: \" + s + \" sn\" : \"Yava\u015f mod kapat\u0131ld\u0131.\");\n        return true;\n    }\n    if (cmd === \"\/lock\" || cmd === \"\/unlock\") {\n        if (!CHANNELS[activeChatType]) { alert(\"Sadece kanallarda.\"); return true; }\n        await update(ref(database, \"settings\/channels\/\" + activeChatType), { locked: cmd === \"\/lock\" });\n        alert(cmd === \"\/lock\" ? \"\ud83d\udd12 Kanal kilitlendi.\" : \"\ud83d\udd13 Kanal a\u00e7\u0131ld\u0131.\");\n        return true;\n    }\n    if (cmd === \"\/poll\") {\n        const q = parts.slice(1).join(\" \").trim().slice(0, 300);\n        if (!q) { alert(\"Kullan\u0131m: \/poll soru\"); return true; }\n        await push(ref(database, base), { uid: currentUser.uid, text: \"\ud83d\udcca ANKET: \" + q + \"\\nOy vermek i\u00e7in tepki ver: \ud83d\udc4d evet \u00b7 \u2764\ufe0f belki \u00b7 \ud83d\ude02 hay\u0131r\", timestamp: Date.now() });\n        return true;\n    }\n    if (cmd === \"\/warn\") {\n        if (!parts[1]) { alert(\"Kullan\u0131m: \/warn kullanici sebep\"); return true; }\n        const reason = parts.slice(2).join(\" \").trim().slice(0, 200) || \"kurallara uy\";\n        await push(ref(database, \"messages\/general\"), { uid: currentUser.uid, text: \"\u26a0\ufe0f @\" + normalizeUsername(parts[1]) + \" uyar\u0131ld\u0131: \" + reason, timestamp: Date.now(), isAnnounce: true });\n        return true;\n    }\n    if (cmd === \"\/endlive\") {\n        if (!parts[1]) { alert(\"Kullan\u0131m: \/endlive kullanici\"); return true; }\n        const uid = await resolveUid(parts[1]);\n        if (!uid) { alert(\"Kullan\u0131c\u0131 bulunamad\u0131.\"); return true; }\n        await remove(ref(database, \"lives\/\" + uid));\n        await remove(ref(database, \"liveSignals\/\" + uid)).catch(() => {});\n        alert(\"Yay\u0131n kapat\u0131ld\u0131.\");\n        return true;\n    }\n    return false;\n}\n\nasync function extraSendChecks() {\n    if (activeChatType === \"private\" || !CHANNELS[activeChatType]) return null;\n    if (await isCurrentUserAdmin()) return null;\n    try {\n        const s = await get(ref(database, \"settings\/channels\/\" + activeChatType));\n        if (!s.exists()) return null;\n        const v = s.val();\n        if (v.locked) return \"Bu kanal y\u00f6netici taraf\u0131ndan kilitlendi.\";\n        if (v.slow > 0) {\n            const wait = v.slow * 1000 - (Date.now() - (lastSentAt[activeChatType] || 0));\n            if (wait > 0) return \"Yava\u015f mod: \" + Math.ceil(wait \/ 1000) + \" sn bekle.\";\n            lastSentAt[activeChatType] = Date.now();\n        }\n    } catch (_) {}\n    return null;\n}\n\n\/* =========================================================\n   YEN\u0130 OYUNLAR\n========================================================= *\/\nfunction gameArea() {\n    if (!currentUser) {\n        alert(\"Oyun i\u00e7in giri\u015f yapmal\u0131s\u0131n.\\nSayfay\u0131 yenile (Ctrl+F5) ve tekrar giri\u015f yap.\");\n        return null;\n    }\n    const area = document.getElementById(\"activeGameArea\");\n    if (!area) return null;\n    area.classList.remove(\"hidden\");\n    const list = document.getElementById(\"gamesListWrap\");\n    if (list) list.style.display = \"none\";\n    const body = document.getElementById(\"gamesBody\");\n    if (body) body.scrollTop = 0;\n    const screen = document.getElementById(\"gamesScreen\");\n    if (screen) screen.scrollTop = 0;\n    return area;\n}\nfunction gameBack(area) {\n    const btn = document.getElementById(\"gameBackBtn\");\n    if (!btn) return;\n    btn.onclick = () => {\n        if (currentGameUnsub) { currentGameUnsub(); currentGameUnsub = null; }\n        if (area) {\n            area.classList.add(\"hidden\");\n            area.innerHTML = \"\";\n        }\n        const list = document.getElementById(\"gamesListWrap\");\n        if (list) list.style.display = \"\";\n        loadCommunityGamesList();\n    };\n}\n\nfunction readBetFromUI() {\n    const kind = document.getElementById(\"betKind\")?.value || \"none\";\n    const amt = Math.max(0, parseInt(document.getElementById(\"betAmount\")?.value, 10) || 0);\n    if (kind === \"none\" || amt <= 0) return null;\n    return { kind, amount: Math.min(amt, 5000) };\n}\n\nasync function lockBetStake(bet) {\n    if (!bet) return true;\n    if (bet.kind === \"vc\") {\n        if ((currentProfile.coins || 0) < bet.amount) {\n            alert(\"Yetersiz VC (gerekli: \" + bet.amount + \")\");\n            return false;\n        }\n        await addCoins(currentUser.uid, -bet.amount);\n        return true;\n    }\n    if (bet.kind === \"xp\") {\n        if ((currentProfile.xp || 0) < bet.amount) {\n            alert(\"Yetersiz XP (gerekli: \" + bet.amount + \")\");\n            return false;\n        }\n        const nx = (currentProfile.xp || 0) - bet.amount;\n        await update(ref(database, \"users\/\" + currentUser.uid), { xp: nx });\n        currentProfile.xp = nx;\n        updateMyProfileDisplay();\n        return true;\n    }\n    return true;\n}\n\nasync function settleBet(data, myRole) {\n    \/\/ data.bet: { kind, amount }, winner: 'host'|'guest'|null\n    if (!data || !data.bet || !data.bet.amount || data.betSettled) return;\n    const winRole = data.winnerRole;\n    if (!winRole) return;\n    const pot = data.bet.amount * 2;\n    const winnerUid = winRole === \"host\" ? data.host : data.guest;\n    if (!winnerUid) return;\n    try {\n        if (data.bet.kind === \"vc\") await addCoins(winnerUid, pot);\n        if (data.bet.kind === \"xp\") {\n            const snap = await get(ref(database, \"users\/\" + winnerUid + \"\/xp\"));\n            const cur = snap.exists() ? Number(snap.val()) || 0 : 0;\n            await update(ref(database, \"users\/\" + winnerUid), { xp: cur + pot });\n            if (winnerUid === currentUser.uid) {\n                currentProfile.xp = cur + pot;\n                updateMyProfileDisplay();\n            }\n        }\n        \/\/ i\u015faretle (sadece host yazar)\n        if (myRole === \"host\") {\n            await update(ref(database, \"minigames\/\" + (data._type || \"xox\") + \"\/\" + (data._code || \"\")), { betSettled: true }).catch(() => {});\n        }\n    } catch (_) {}\n}\n\nfunction openLobby(type, title, buildInitial, render, extraOpts) {\n    const area = gameArea();\n    if (!area) return;\n    const splitOk = [\"c4\", \"xox\", \"mem\", \"num\", \"rps\", \"word\"].includes(type);\n    const botOk = [\"c4\", \"xox\", \"rps\", \"num\", \"mem\"].includes(type);\n    area.innerHTML = `\n        <button class=\"gameBackBtn\" id=\"gameBackBtn\">\u2190 Geri<\/button>\n        <div class=\"gameStatus\">${escapeHtml(title)}<\/div>\n        <div class=\"modeRow\">\n            <button type=\"button\" class=\"modeBtn on\" id=\"modeOnline\">\ud83c\udf10 Online<\/button>\n            ${splitOk ? `<button type=\"button\" class=\"modeBtn\" id=\"modeSplit\">\ud83d\udcf1 Split<\/button>` : \"\"}\n            ${botOk ? `<button type=\"button\" class=\"modeBtn\" id=\"modeBot\">\ud83e\udd16 Bot<\/button>` : \"\"}\n        <\/div>\n        <div id=\"lobbyOnlineBox\">\n            ${extraOpts || \"\"}\n            <div style=\"background:#1e1f22;border-radius:10px;padding:12px;margin:10px 0;\">\n                <div style=\"font-size:13px;color:#b5bac1;margin-bottom:8px;\">\ud83d\udcb0 \u0130ddia (opsiyonel) \u2014 kazanan potu al\u0131r<\/div>\n                <div style=\"display:flex;gap:8px;flex-wrap:wrap;align-items:center;\">\n                    <select id=\"betKind\" style=\"padding:10px;border:none;border-radius:8px;background:#2b2d31;color:#fff;\">\n                        <option value=\"none\">\u0130ddia yok<\/option>\n                        <option value=\"vc\">VegaCoin (VC)<\/option>\n                        <option value=\"xp\">XP<\/option>\n                    <\/select>\n                    <input id=\"betAmount\" type=\"number\" min=\"0\" max=\"5000\" value=\"10\" placeholder=\"Miktar\"\n                        style=\"width:90px;padding:10px;border:none;border-radius:8px;background:#2b2d31;color:#fff;\">\n                <\/div>\n                <div style=\"font-size:11px;color:#949ba4;margin-top:6px;\">Her iki taraf da ayn\u0131 iddiay\u0131 koyar. Bakiyen: ${(currentProfile.coins||0)} VC \u00b7 ${(currentProfile.xp||0)} XP<\/div>\n            <\/div>\n            <button class=\"bigBtn\" id=\"lobbyCreate\">Oda Olu\u015ftur<\/button>\n            <div style=\"display:flex;gap:8px;margin-top:10px;\">\n                <input id=\"lobbyCode\" placeholder=\"Oda kodu\" maxlength=\"8\" style=\"flex:1;padding:12px;border:none;border-radius:8px;background:#1e1f22;color:white;\">\n                <button id=\"lobbyJoin\" style=\"padding:12px 16px;border:none;border-radius:8px;background:#23a559;color:white;font-weight:bold;\">Kat\u0131l<\/button>\n            <\/div>\n        <\/div>\n        <div id=\"gmPlay\" style=\"margin-top:16px;\"><\/div>`;\n    gameBack(area);\n    const onlineBox = document.getElementById(\"lobbyOnlineBox\");\n    const clearModes = () => {\n        document.getElementById(\"modeOnline\")?.classList.remove(\"on\");\n        document.getElementById(\"modeSplit\")?.classList.remove(\"on\");\n        document.getElementById(\"modeBot\")?.classList.remove(\"on\");\n    };\n    document.getElementById(\"modeOnline\").onclick = () => {\n        clearModes();\n        document.getElementById(\"modeOnline\").classList.add(\"on\");\n        onlineBox.style.display = \"\";\n        document.getElementById(\"gmPlay\").innerHTML = \"\";\n    };\n    if (splitOk) {\n        document.getElementById(\"modeSplit\").onclick = () => {\n            clearModes();\n            document.getElementById(\"modeSplit\").classList.add(\"on\");\n            onlineBox.style.display = \"none\";\n            startSplitScreen(type, title);\n        };\n    }\n    if (botOk) {\n        document.getElementById(\"modeBot\").onclick = () => {\n            clearModes();\n            document.getElementById(\"modeBot\").classList.add(\"on\");\n            onlineBox.style.display = \"none\";\n            startBotGame(type, document.getElementById(\"gmPlay\"));\n        };\n    }\n    document.getElementById(\"lobbyCreate\").onclick = async () => {\n        const bet = readBetFromUI();\n        if (!(await lockBetStake(bet))) return;\n        const code = Math.random().toString(36).substring(2, 8).toUpperCase();\n        const init = typeof buildInitial === \"function\" ? buildInitial() : {};\n        await set(ref(database, \"minigames\/\" + type + \"\/\" + code), Object.assign({\n            host: currentUser.uid, hostName: currentProfile.displayName,\n            guest: null, status: \"waiting\", createdAt: Date.now(),\n            bet: bet || null, betSettled: false\n        }, init));\n        watchRoom(type, code, \"host\", render);\n    };\n    document.getElementById(\"lobbyJoin\").onclick = async () => {\n        const code = document.getElementById(\"lobbyCode\").value.trim().toUpperCase();\n        if (!code) return alert(\"Kod gir\");\n        const snap = await get(ref(database, \"minigames\/\" + type + \"\/\" + code));\n        if (!snap.exists()) return alert(\"Oda bulunamad\u0131\");\n        const d = snap.val();\n        if (d.host === currentUser.uid) return alert(\"Kendi odana kat\u0131lamazs\u0131n\");\n        if (d.guest) return alert(\"Oda dolu\");\n        \/\/ odadaki iddiay\u0131 kabul et\n        if (d.bet && d.bet.amount) {\n            const ok = confirm(\"Bu odada iddia var: \" + d.bet.amount + \" \" + (d.bet.kind === \"vc\" ? \"VC\" : \"XP\") + \"\\nKat\u0131lmak i\u00e7in ayn\u0131 miktar\u0131 koyacaks\u0131n. Devam?\");\n            if (!ok) return;\n            if (!(await lockBetStake(d.bet))) return;\n        }\n        await update(ref(database, \"minigames\/\" + type + \"\/\" + code), {\n            guest: currentUser.uid, guestName: currentProfile.displayName, status: \"playing\"\n        });\n        watchRoom(type, code, \"guest\", render);\n    };\n}\n\n\/** Bot ile oyna (yerel, Firebase yok) *\/\nfunction startBotGame(type, play) {\n    if (!play) return;\n    if (type === \"xox\") return startBotXox(play);\n    if (type === \"rps\") return startBotRps(play);\n    if (type === \"c4\") return startBotC4(play);\n    if (type === \"num\") return startBotNumber(play);\n    if (type === \"mem\") return startBotMemory(play);\n    play.innerHTML = `<div class=\"gameStatus\">Bu oyun i\u00e7in bot yak\u0131nda<\/div>`;\n}\n\nfunction startBotXox(play) {\n    let cells = Array(9).fill(\"\");\n    let over = false;\n    function win(b) {\n        const L = [[0,1,2],[3,4,5],[6,7,8],[0,3,6],[1,4,7],[2,5,8],[0,4,8],[2,4,6]];\n        for (const [a,c,d] of L) if (b[a] && b[a] === b[c] && b[a] === b[d]) return b[a];\n        return b.every(Boolean) ? \"draw\" : null;\n    }\n    function botMove() {\n        const empty = cells.map((v, i) => v ? -1 : i).filter(i => i >= 0);\n        \/\/ kazanma \/ engelleme\n        for (const mark of [\"O\", \"X\"]) {\n            for (const i of empty) {\n                const t = cells.slice();\n                t[i] = mark;\n                if (win(t) === mark) return i;\n            }\n        }\n        if (empty.includes(4)) return 4;\n        return empty[Math.floor(Math.random() * empty.length)];\n    }\n    function draw() {\n        const w = win(cells);\n        over = !!w;\n        play.innerHTML = `<div class=\"gameStatus\">Sen \u274c \u00b7 Bot \u2b55<\/div>\n            <div class=\"xoxBoard\">${cells.map((v,i)=>`<button class=\"xoxCell\" data-i=\"${i}\">${v}<\/button>`).join(\"\")}<\/div>\n            <div class=\"gameStatus\">${w===\"draw\"?\"Berabere!\":w===\"X\"?\"Kazand\u0131n!\":w===\"O\"?\"Bot kazand\u0131!\":\"S\u0131ra sende\"}<\/div>\n            ${over?`<button class=\"bigBtn\" id=\"botAgain\">Tekrar<\/button>`:\"\"}`;\n        play.querySelectorAll(\".xoxCell\").forEach(btn => {\n            btn.onclick = () => {\n                const i = +btn.dataset.i;\n                if (over || cells[i]) return;\n                cells[i] = \"X\";\n                if (!win(cells)) {\n                    const bi = botMove();\n                    if (bi != null) cells[bi] = \"O\";\n                }\n                draw();\n            };\n        });\n        document.getElementById(\"botAgain\")?.addEventListener(\"click\", () => {\n            cells = Array(9).fill(\"\"); over = false; draw();\n        });\n    }\n    draw();\n}\n\nfunction startBotRps(play) {\n    const opts = [\"\u270a\", \"\u270b\", \"\u270c\ufe0f\"];\n    function result(a, b) {\n        if (a === b) return 0;\n        if ((a === 0 && b === 2) || (a === 1 && b === 0) || (a === 2 && b === 1)) return 1;\n        return 2;\n    }\n    play.innerHTML = `<div class=\"gameStatus\">Bot'a kar\u015f\u0131 Ta\u015f Ka\u011f\u0131t Makas<\/div>\n        <div class=\"rpsBtns\">${opts.map((o,i)=>`<button class=\"rpsBtn\" data-i=\"${i}\">${o}<\/button>`).join(\"\")}<\/div>\n        <div class=\"gameStatus\" id=\"botRpsMsg\">Se\u00e7imini yap<\/div>`;\n    play.querySelectorAll(\".rpsBtn\").forEach(btn => {\n        btn.onclick = () => {\n            const p = +btn.dataset.i;\n            const b = Math.floor(Math.random() * 3);\n            const r = result(p, b);\n            document.getElementById(\"botRpsMsg\").textContent =\n                opts[p] + \" vs \" + opts[b] + \" \u2192 \" + (r === 0 ? \"Berabere\" : r === 1 ? \"Kazand\u0131n!\" : \"Bot kazand\u0131\");\n        };\n    });\n}\n\nfunction startBotC4(play) {\n    let board = Array(42).fill(\"\");\n    let turn = \"R\";\n    let winner = null;\n    function canDrop(col) {\n        for (let r = 5; r >= 0; r--) if (!board[r * 7 + col]) return r;\n        return -1;\n    }\n    function botCol() {\n        const cols = [0,1,2,3,4,5,6].filter(c => canDrop(c) >= 0);\n        \/\/ basit: rastgele, ortadan tercih\n        if (cols.includes(3)) return 3;\n        return cols[Math.floor(Math.random() * cols.length)];\n    }\n    function draw() {\n        play.innerHTML = `<div class=\"gameStatus\">Sen \ud83d\udd34 \u00b7 Bot \ud83d\udfe1 ${winner ? (winner === \"R\" ? \"\u00b7 Kazand\u0131n!\" : winner === \"Y\" ? \"\u00b7 Bot kazand\u0131\" : \"\u00b7 Berabere\") : \"\"}<\/div>\n            <div class=\"c4Cols\">${[0,1,2,3,4,5,6].map(c=>`<button data-c=\"${c}\">\u25bc<\/button>`).join(\"\")}<\/div>\n            <div class=\"c4Board\">${board.map(v=>`<div class=\"c4Cell ${v}\"><\/div>`).join(\"\")}<\/div>\n            ${winner?`<button class=\"bigBtn\" id=\"botAgain\">Tekrar<\/button>`:\"\"}`;\n        play.querySelectorAll(\".c4Cols button\").forEach(btn => {\n            btn.onclick = () => {\n                if (winner || turn !== \"R\") return;\n                const col = +btn.dataset.c;\n                const row = canDrop(col);\n                if (row < 0) return;\n                board[row * 7 + col] = \"R\";\n                winner = typeof c4Winner === \"function\" ? c4Winner(board) : null;\n                if (!winner) {\n                    turn = \"Y\";\n                    setTimeout(() => {\n                        const bc = botCol();\n                        const br = canDrop(bc);\n                        if (br >= 0) board[br * 7 + bc] = \"Y\";\n                        winner = typeof c4Winner === \"function\" ? c4Winner(board) : null;\n                        turn = \"R\";\n                        draw();\n                    }, 400);\n                }\n                draw();\n            };\n        });\n        document.getElementById(\"botAgain\")?.addEventListener(\"click\", () => {\n            board = Array(42).fill(\"\"); turn = \"R\"; winner = null; draw();\n        });\n    }\n    draw();\n}\n\nfunction startBotNumber(play) {\n    const secret = Math.floor(Math.random() * 100) + 1;\n    let tries = 0;\n    play.innerHTML = `<div class=\"gameStatus\">Bot 1\u2013100 say\u0131 tuttu. Tahmin et!<\/div>\n        <div style=\"display:flex;gap:8px;justify-content:center;margin-top:10px;\">\n            <input id=\"botNumG\" type=\"number\" min=\"1\" max=\"100\" style=\"width:100px;padding:10px;border:none;border-radius:8px;background:#1e1f22;color:#fff;\">\n            <button class=\"liveBtn green\" id=\"botNumGo\">Tahmin<\/button>\n        <\/div>\n        <div class=\"gameStatus\" id=\"botNumMsg\"><\/div>`;\n    document.getElementById(\"botNumGo\").onclick = () => {\n        const g = +document.getElementById(\"botNumG\").value;\n        if (!g) return;\n        tries++;\n        const el = document.getElementById(\"botNumMsg\");\n        if (g === secret) el.textContent = \"\ud83c\udf89 Bildin! \" + tries + \" denemede. Say\u0131: \" + secret;\n        else el.textContent = g < secret ? \"Daha y\u00fcksek (\" + tries + \")\" : \"Daha d\u00fc\u015f\u00fck (\" + tries + \")\";\n    };\n}\n\nfunction startBotMemory(play) {\n    \/\/ bot yava\u015f rastgele a\u00e7ar \u2014 split memory tek oyuncu vs skor\n    const pool = [\"\ud83c\udf4e\",\"\ud83d\ude80\",\"\ud83c\udfb8\",\"\ud83d\udc31\",\"\u26bd\",\"\ud83c\udf19\",\"\ud83c\udf55\",\"\ud83c\udfae\"];\n    let cards = [...pool, ...pool];\n    for (let i = cards.length - 1; i > 0; i--) {\n        const j = Math.floor(Math.random() * (i + 1));\n        [cards[i], cards[j]] = [cards[j], cards[i]];\n    }\n    let flipped = [], matched = [], scores = { you: 0, bot: 0 }, turn = \"you\", lock = false;\n    function draw() {\n        play.innerHTML = `<div class=\"gameStatus\">Sen: ${scores.you} \u00b7 Bot: ${scores.bot} \u00b7 S\u0131ra: ${turn === \"you\" ? \"Sen\" : \"Bot\"}<\/div>\n            <div class=\"memGrid\" style=\"grid-template-columns:repeat(4,56px)\">\n                ${cards.map((c,i)=>{\n                    const done = matched.includes(i), open = flipped.includes(i);\n                    return `<button class=\"memCard ${done?\"done\":open?\"open\":\"\"}\" data-i=\"${i}\">${done||open?c:\"?\"}<\/button>`;\n                }).join(\"\")}\n            <\/div>\n            <div class=\"gameStatus\">${matched.length===cards.length?(scores.you>scores.bot?\"Kazand\u0131n!\":scores.bot>scores.you?\"Bot kazand\u0131\":\"Berabere\"):\"\"}<\/div>`;\n        play.querySelectorAll(\".memCard\").forEach(btn => {\n            btn.onclick = () => {\n                if (lock || turn !== \"you\" || matched.length === cards.length) return;\n                const i = +btn.dataset.i;\n                if (matched.includes(i) || flipped.includes(i) || flipped.length >= 2) return;\n                flipped.push(i);\n                draw();\n                if (flipped.length === 2) {\n                    lock = true;\n                    const [a, b] = flipped;\n                    setTimeout(() => {\n                        if (cards[a] === cards[b]) { matched.push(a, b); scores.you++; }\n                        else turn = \"bot\";\n                        flipped = [];\n                        lock = false;\n                        draw();\n                        if (turn === \"bot\") setTimeout(botTurn, 500);\n                    }, 600);\n                }\n            };\n        });\n    }\n    function botTurn() {\n        if (matched.length === cards.length) return;\n        const free = cards.map((_, i) => i).filter(i => !matched.includes(i));\n        if (free.length < 2) return;\n        const a = free[Math.floor(Math.random() * free.length)];\n        let b = free[Math.floor(Math.random() * free.length)];\n        while (b === a) b = free[Math.floor(Math.random() * free.length)];\n        flipped = [a, b];\n        draw();\n        lock = true;\n        setTimeout(() => {\n            if (cards[a] === cards[b]) { matched.push(a, b); scores.bot++; turn = \"bot\"; }\n            else turn = \"you\";\n            flipped = [];\n            lock = false;\n            draw();\n            if (turn === \"bot\" && matched.length < cards.length) setTimeout(botTurn, 500);\n        }, 700);\n    }\n    draw();\n}\n\n\/** Ayn\u0131 cihaz \u2014 2 oyuncu split screen *\/\nfunction startSplitScreen(type, title) {\n    const play = document.getElementById(\"gmPlay\");\n    if (type === \"c4\") return startSplitC4(play);\n    if (type === \"xox\") return startSplitXox(play);\n    if (type === \"mem\") return startSplitMemory(play);\n    if (type === \"rps\") return startSplitRps(play);\n    if (type === \"num\") return startSplitNumber(play);\n    if (type === \"word\") return startSplitWord(play);\n    play.innerHTML = `<div class=\"gameStatus\">Bu oyun i\u00e7in split screen yak\u0131nda<\/div>`;\n}\n\nfunction startSplitC4(play) {\n    let board = Array(42).fill(\"\");\n    let turn = \"R\";\n    let winner = null;\n    function draw() {\n        let html = `<div class=\"splitWrap\">\n            <div class=\"splitPane\"><h3>\ud83d\udd34 Oyuncu 1 ${turn === \"R\" && !winner ? \"\u00b7 s\u0131ra sende\" : \"\"}<\/h3><\/div>\n            <div class=\"splitPane\"><h3>\ud83d\udfe1 Oyuncu 2 ${turn === \"Y\" && !winner ? \"\u00b7 s\u0131ra sende\" : \"\"}<\/h3><\/div>\n        <\/div>`;\n        html += `<div class=\"c4Cols\">` + [0,1,2,3,4,5,6].map(c => `<button data-c=\"${c}\">\u25bc<\/button>`).join(\"\") + `<\/div>`;\n        html += `<div class=\"c4Board\">` + board.map(v => `<div class=\"c4Cell ${v}\"><\/div>`).join(\"\") + `<\/div>`;\n        if (winner === \"draw\") html += `<div class=\"gameStatus\">Berabere!<\/div>`;\n        else if (winner) html += `<div class=\"gameStatus\">${winner === \"R\" ? \"\ud83d\udd34 Oyuncu 1 kazand\u0131!\" : \"\ud83d\udfe1 Oyuncu 2 kazand\u0131!\"}<\/div>`;\n        else html += `<div class=\"gameStatus\">S\u0131ra: ${turn === \"R\" ? \"\ud83d\udd34\" : \"\ud83d\udfe1\"}<\/div>`;\n        if (winner) html += `<button class=\"bigBtn\" id=\"splitAgain\" style=\"margin-top:10px;\">Tekrar<\/button>`;\n        play.innerHTML = html;\n        play.querySelectorAll(\".c4Cols button\").forEach(btn => {\n            btn.onclick = () => {\n                if (winner) return;\n                const col = +btn.dataset.c;\n                let row = -1;\n                for (let r = 5; r >= 0; r--) if (!board[r * 7 + col]) { row = r; break; }\n                if (row < 0) return;\n                board[row * 7 + col] = turn;\n                winner = c4Winner(board);\n                if (!winner) turn = turn === \"R\" ? \"Y\" : \"R\";\n                draw();\n            };\n        });\n        const again = document.getElementById(\"splitAgain\");\n        if (again) again.onclick = () => { board = Array(42).fill(\"\"); turn = \"R\"; winner = null; draw(); };\n    }\n    draw();\n}\n\nfunction startSplitXox(play) {\n    let cells = Array(9).fill(\"\");\n    let turn = \"X\";\n    let over = false;\n    function win(b) {\n        const L = [[0,1,2],[3,4,5],[6,7,8],[0,3,6],[1,4,7],[2,5,8],[0,4,8],[2,4,6]];\n        for (const [a,c,d] of L) if (b[a] && b[a] === b[c] && b[a] === b[d]) return b[a];\n        return b.every(Boolean) ? \"draw\" : null;\n    }\n    function draw() {\n        const w = win(cells);\n        over = !!w;\n        play.innerHTML = `<div class=\"splitWrap\">\n            <div class=\"splitPane\"><h3>\u274c Oyuncu 1<\/h3><\/div>\n            <div class=\"splitPane\"><h3>\u2b55 Oyuncu 2<\/h3><\/div>\n        <\/div>\n        <div class=\"xoxBoard\">${cells.map((v,i) => `<button class=\"xoxCell\" data-i=\"${i}\">${v}<\/button>`).join(\"\")}<\/div>\n        <div class=\"gameStatus\">${w === \"draw\" ? \"Berabere!\" : w ? (w === \"X\" ? \"\u274c kazand\u0131!\" : \"\u2b55 kazand\u0131!\") : \"S\u0131ra: \" + turn}<\/div>\n        ${over ? `<button class=\"bigBtn\" id=\"splitAgain\">Tekrar<\/button>` : \"\"}`;\n        play.querySelectorAll(\".xoxCell\").forEach(btn => {\n            btn.onclick = () => {\n                const i = +btn.dataset.i;\n                if (over || cells[i]) return;\n                cells[i] = turn;\n                turn = turn === \"X\" ? \"O\" : \"X\";\n                draw();\n            };\n        });\n        document.getElementById(\"splitAgain\")?.addEventListener(\"click\", () => {\n            cells = Array(9).fill(\"\"); turn = \"X\"; over = false; draw();\n        });\n    }\n    draw();\n}\n\nfunction startSplitMemory(play) {\n    const size = +(document.getElementById(\"memSizeSelect\")?.value || 4);\n    const pairs = size * size \/ 2;\n    const pool = [\"\ud83c\udf4e\",\"\ud83d\ude80\",\"\ud83c\udfb8\",\"\ud83d\udc31\",\"\u26bd\",\"\ud83c\udf19\",\"\ud83c\udf55\",\"\ud83c\udfae\",\"\ud83d\udd25\",\"\ud83d\udc8e\",\"\ud83c\udf1f\",\"\ud83e\udd84\",\"\ud83c\udfaf\",\"\ud83c\udfb2\",\"\ud83c\udfa7\",\"\ud83e\udd8a\"];\n    const emojis = pool.slice(0, pairs);\n    let cards = [...emojis, ...emojis];\n    for (let i = cards.length - 1; i > 0; i--) {\n        const j = Math.floor(Math.random() * (i + 1));\n        [cards[i], cards[j]] = [cards[j], cards[i]];\n    }\n    let flipped = [], matched = [], scores = { 1: 0, 2: 0 }, turn = 1, lock = false;\n    function draw() {\n        const cols = size;\n        play.innerHTML = `<div class=\"splitWrap\">\n            <div class=\"splitPane\"><h3>Oyuncu 1: ${scores[1]} ${turn === 1 ? \"\u25c0\" : \"\"}<\/h3><\/div>\n            <div class=\"splitPane\"><h3>Oyuncu 2: ${scores[2]} ${turn === 2 ? \"\u25c0\" : \"\"}<\/h3><\/div>\n        <\/div>\n        <div class=\"memGrid\" style=\"grid-template-columns:repeat(${cols},56px)\">\n            ${cards.map((c,i) => {\n                const done = matched.includes(i), open = flipped.includes(i);\n                return `<button class=\"memCard ${done?\"done\":open?\"open\":\"\"}\" data-i=\"${i}\">${done||open?c:\"?\"}<\/button>`;\n            }).join(\"\")}\n        <\/div>\n        <div class=\"gameStatus\">${matched.length === cards.length\n            ? (scores[1] > scores[2] ? \"Oyuncu 1 kazand\u0131!\" : scores[2] > scores[1] ? \"Oyuncu 2 kazand\u0131!\" : \"Berabere!\")\n            : \"S\u0131ra: Oyuncu \" + turn}<\/div>`;\n        play.querySelectorAll(\".memCard\").forEach(btn => {\n            btn.onclick = () => {\n                if (lock || matched.length === cards.length) return;\n                const i = +btn.dataset.i;\n                if (matched.includes(i) || flipped.includes(i) || flipped.length >= 2) return;\n                flipped.push(i);\n                draw();\n                if (flipped.length === 2) {\n                    lock = true;\n                    const [a, b] = flipped;\n                    setTimeout(() => {\n                        if (cards[a] === cards[b]) {\n                            matched.push(a, b);\n                            scores[turn]++;\n                        } else turn = turn === 1 ? 2 : 1;\n                        flipped = [];\n                        lock = false;\n                        draw();\n                    }, 700);\n                }\n            };\n        });\n    }\n    draw();\n}\n\nfunction startSplitRps(play) {\n    const opts = [\"\u270a\", \"\u270b\", \"\u270c\ufe0f\"];\n    let p1 = null, p2 = null;\n    function result(a, b) {\n        if (a === b) return 0;\n        if ((a === 0 && b === 2) || (a === 1 && b === 0) || (a === 2 && b === 1)) return 1;\n        return 2;\n    }\n    function draw() {\n        play.innerHTML = `<div class=\"splitWrap\">\n            <div class=\"splitPane\">\n                <h3>Oyuncu 1 ${p1 != null ? \"\u2713\" : \"\"}<\/h3>\n                <div class=\"rpsBtns\">${opts.map((o,i)=>`<button class=\"rpsBtn\" data-p=\"1\" data-i=\"${i}\">${o}<\/button>`).join(\"\")}<\/div>\n            <\/div>\n            <div class=\"splitPane\">\n                <h3>Oyuncu 2 ${p2 != null ? \"\u2713\" : \"\"}<\/h3>\n                <div class=\"rpsBtns\">${opts.map((o,i)=>`<button class=\"rpsBtn\" data-p=\"2\" data-i=\"${i}\">${o}<\/button>`).join(\"\")}<\/div>\n            <\/div>\n        <\/div>\n        <div class=\"gameStatus\" id=\"splitRpsMsg\">${p1 != null && p2 != null\n            ? (result(p1,p2)===0 ? \"Berabere! \" : \"Oyuncu \" + result(p1,p2) + \" kazand\u0131! \") + opts[p1] + \" vs \" + opts[p2]\n            : \"Her iki oyuncu da se\u00e7sin (gizli)\"}<\/div>\n        ${p1 != null && p2 != null ? `<button class=\"bigBtn\" id=\"splitAgain\">Tekrar<\/button>` : \"\"}`;\n        play.querySelectorAll(\".rpsBtn\").forEach(btn => {\n            btn.onclick = () => {\n                const p = +btn.dataset.p, i = +btn.dataset.i;\n                if (p === 1 && p1 == null) p1 = i;\n                if (p === 2 && p2 == null) p2 = i;\n                draw();\n            };\n        });\n        document.getElementById(\"splitAgain\")?.addEventListener(\"click\", () => { p1 = p2 = null; draw(); });\n    }\n    draw();\n}\n\nfunction startSplitNumber(play) {\n    const secret = Math.floor(Math.random() * 100) + 1;\n    let turn = 1, last = \"\";\n    play.innerHTML = `<div class=\"splitWrap\">\n        <div class=\"splitPane\"><h3>Oyuncu 1<\/h3><\/div>\n        <div class=\"splitPane\"><h3>Oyuncu 2<\/h3><\/div>\n    <\/div>\n    <div class=\"gameStatus\">1\u2013100 aras\u0131 gizli say\u0131. S\u0131ra: Oyuncu <span id=\"numTurn\">1<\/span><\/div>\n    <div style=\"display:flex;gap:8px;justify-content:center;margin-top:10px;\">\n        <input id=\"numGuess\" type=\"number\" min=\"1\" max=\"100\" style=\"width:100px;padding:10px;border:none;border-radius:8px;background:#1e1f22;color:#fff;\">\n        <button class=\"liveBtn green\" id=\"numGo\">Tahmin<\/button>\n    <\/div>\n    <div class=\"gameStatus\" id=\"numMsg\"><\/div>`;\n    document.getElementById(\"numGo\").onclick = () => {\n        const g = +document.getElementById(\"numGuess\").value;\n        if (!g) return;\n        if (g === secret) {\n            document.getElementById(\"numMsg\").textContent = \"\ud83c\udf89 Oyuncu \" + turn + \" bildi! Say\u0131: \" + secret;\n            return;\n        }\n        last = g < secret ? \"Daha y\u00fcksek\" : \"Daha d\u00fc\u015f\u00fck\";\n        document.getElementById(\"numMsg\").textContent = \"Oyuncu \" + turn + \": \" + g + \" \u2192 \" + last;\n        turn = turn === 1 ? 2 : 1;\n        document.getElementById(\"numTurn\").textContent = turn;\n    };\n}\n\nfunction startSplitWord(play) {\n    let last = \"A\", used = new Set(), turn = 1;\n    play.innerHTML = `<div class=\"splitWrap\">\n        <div class=\"splitPane\"><h3>Oyuncu 1<\/h3><\/div>\n        <div class=\"splitPane\"><h3>Oyuncu 2<\/h3><\/div>\n    <\/div>\n    <div class=\"gameStatus\">Son harf: <b id=\"wLast\">A<\/b> \u00b7 S\u0131ra: Oyuncu <span id=\"wTurn\">1<\/span><\/div>\n    <div style=\"display:flex;gap:8px;justify-content:center;\">\n        <input id=\"wInput\" placeholder=\"Kelime\" style=\"padding:10px;border:none;border-radius:8px;background:#1e1f22;color:#fff;\">\n        <button class=\"liveBtn green\" id=\"wGo\">G\u00f6nder<\/button>\n    <\/div>\n    <div class=\"gameStatus\" id=\"wMsg\"><\/div>`;\n    document.getElementById(\"wGo\").onclick = () => {\n        const w = (document.getElementById(\"wInput\").value || \"\").trim().toLocaleUpperCase(\"tr-TR\");\n        document.getElementById(\"wInput\").value = \"\";\n        if (w.length < 2) return;\n        if (w[0] !== last) {\n            document.getElementById(\"wMsg\").textContent = \"\u274c \" + last + \" ile ba\u015flamal\u0131 \u2192 Oyuncu \" + turn + \" kaybetti!\";\n            return;\n        }\n        if (used.has(w)) {\n            document.getElementById(\"wMsg\").textContent = \"\u274c Kelime kullan\u0131ld\u0131 \u2192 Oyuncu \" + turn + \" kaybetti!\";\n            return;\n        }\n        used.add(w);\n        last = w[w.length - 1];\n        document.getElementById(\"wLast\").textContent = last;\n        turn = turn === 1 ? 2 : 1;\n        document.getElementById(\"wTurn\").textContent = turn;\n        document.getElementById(\"wMsg\").textContent = w + \" \u2713\";\n    };\n}\n\nfunction watchRoom(type, code, role, render) {\n    if (currentGameUnsub) currentGameUnsub();\n    const play = document.getElementById(\"gmPlay\");\n    const path = \"minigames\/\" + type + \"\/\" + code;\n    currentGameUnsub = onValue(ref(database, path), snap => {\n        if (!snap.exists()) return;\n        render(snap.val(), play, { code, role, path, me: currentUser.uid });\n    });\n}\n\n\/* ---------- Connect 4 ---------- *\/\nfunction c4Winner(b) {\n    const dirs = [[0, 1], [1, 0], [1, 1], [1, -1]];\n    for (let r = 0; r < 6; r++) for (let c = 0; c < 7; c++) {\n        const m = b[r * 7 + c];\n        if (!m) continue;\n        for (const [dr, dc] of dirs) {\n            let k = 1;\n            while (k < 4) {\n                const rr = r + dr * k, cc = c + dc * k;\n                if (rr < 0 || rr > 5 || cc < 0 || cc > 6 || b[rr * 7 + cc] !== m) break;\n                k++;\n            }\n            if (k === 4) return m;\n        }\n    }\n    return b.every(x => x) ? \"draw\" : null;\n}\n\nfunction renderC4(g, play, ctx) {\n    const myMark = ctx.role === \"host\" ? \"R\" : \"Y\";\n    const board = Array.from({ length: 42 }, (_, i) => (g.board && g.board[i]) || \"\");\n    let html = `<div class=\"gameStatus\">Oda <b>${ctx.code}<\/b> \u00b7 Sen: ${myMark === \"R\" ? \"\ud83d\udd34\" : \"\ud83d\udfe1\"}<\/div>`;\n    if (g.status === \"waiting\") {\n        play.innerHTML = html + `<div class=\"gameStatus\">Rakip bekleniyor... Kod: <b>${ctx.code}<\/b><\/div>`;\n        return;\n    }\n    const turn = g.turn || \"R\";\n    html += `<div class=\"c4Cols\">` + [0, 1, 2, 3, 4, 5, 6].map(c => `<button data-c=\"${c}\">\u25bc<\/button>`).join(\"\") + `<\/div>`;\n    html += `<div class=\"c4Board\">` + board.map(v => `<div class=\"c4Cell ${v}\"><\/div>`).join(\"\") + `<\/div>`;\n    if (g.winner === \"draw\") html += `<div class=\"gameStatus\">Berabere!<\/div>`;\n    else if (g.winner) html += `<div class=\"gameStatus\">${g.winner === myMark ? \"\ud83c\udf89 Kazand\u0131n!\" : \"\ud83d\ude22 Kaybettin\"}<\/div>`;\n    else html += `<div class=\"gameStatus\">S\u0131ra: ${turn === \"R\" ? \"\ud83d\udd34\" : \"\ud83d\udfe1\"}${turn === myMark ? \" (sen)\" : \"\"}<\/div>`;\n    play.innerHTML = html;\n    play.querySelectorAll(\".c4Cols button\").forEach(btn => {\n        btn.onclick = async () => {\n            const fresh = (await get(ref(database, ctx.path))).val();\n            if (!fresh || fresh.winner || (fresh.turn || \"R\") !== myMark) return;\n            const b = Array.from({ length: 42 }, (_, i) => (fresh.board && fresh.board[i]) || \"\");\n            const col = +btn.dataset.c;\n            let row = -1;\n            for (let r = 5; r >= 0; r--) if (!b[r * 7 + col]) { row = r; break; }\n            if (row < 0) return;\n            b[row * 7 + col] = myMark;\n            const w = c4Winner(b);\n            await update(ref(database, ctx.path), { board: b, turn: myMark === \"R\" ? \"Y\" : \"R\", winner: w || null });\n            if (w === myMark) bumpStat(\"gamesWon\");\n        };\n    });\n}\n\n\/* ---------- Say\u0131 Tahmin D\u00fcellosu ---------- *\/\nfunction renderNumber(g, play, ctx) {\n    let html = `<div class=\"gameStatus\">Oda <b>${ctx.code}<\/b> \u00b7 1 ile 100 aras\u0131nda say\u0131y\u0131 bul<\/div>`;\n    if (g.status === \"waiting\") {\n        play.innerHTML = html + `<div class=\"gameStatus\">Rakip bekleniyor... Kod: <b>${ctx.code}<\/b><\/div>`;\n        return;\n    }\n    const guesses = g.guesses ? Object.values(g.guesses) : [];\n    const myTurn = g.turn === ctx.me;\n    html += `<div class=\"gameStatus\">${escapeHtml(g.hostName)} vs ${escapeHtml(g.guestName || \"?\")}<\/div>`;\n    html += guesses.map(x => `<div class=\"lbRow\"><span>${escapeHtml(x.by === g.host ? g.hostName : (g.guestName || \"?\"))}: <b>${x.n}<\/b><\/span><span>${x.hint}<\/span><\/div>`).join(\"\");\n    if (g.winner) {\n        html += `<div class=\"gameStatus\" style=\"font-size:18px;color:#fff;margin-top:12px;\">${g.winner === ctx.me ? \"\ud83c\udf89 Kazand\u0131n!\" : \"\ud83d\ude22 Rakip buldu\"} Say\u0131: ${g.secret}<\/div>`;\n    } else {\n        html += `<div class=\"gameStatus\">${myTurn ? \"S\u0131ra sende!\" : \"Rakip d\u00fc\u015f\u00fcn\u00fcyor...\"}<\/div>\n            <input id=\"numGuess\" type=\"number\" min=\"1\" max=\"100\" placeholder=\"Tahmin\" style=\"width:100%;padding:12px;border:none;border-radius:8px;background:#1e1f22;color:white;\">\n            <button class=\"bigBtn\" id=\"numSend\">Tahmin Et<\/button>`;\n    }\n    play.innerHTML = html;\n    const send = document.getElementById(\"numSend\");\n    if (send) send.onclick = async () => {\n        const n = parseInt(document.getElementById(\"numGuess\").value, 10);\n        if (isNaN(n) || n < 1 || n > 100) return alert(\"1-100 aras\u0131 say\u0131 yaz\");\n        const fresh = (await get(ref(database, ctx.path))).val();\n        if (!fresh || fresh.winner || fresh.turn !== ctx.me) return alert(\"S\u0131ra sende de\u011fil\");\n        const list = fresh.guesses ? Object.values(fresh.guesses) : [];\n        const hint = n === fresh.secret ? \"\u2705 Do\u011fru\" : (n < fresh.secret ? \"\u2b06\ufe0f Daha b\u00fcy\u00fck\" : \"\u2b07\ufe0f Daha k\u00fc\u00e7\u00fck\");\n        list.push({ by: ctx.me, n, hint });\n        const upd = { guesses: list, turn: ctx.me === fresh.host ? fresh.guest : fresh.host };\n        if (n === fresh.secret) { upd.winner = ctx.me; bumpStat(\"gamesWon\"); }\n        await update(ref(database, ctx.path), upd);\n    };\n}\n\n\/* ---------- Haf\u0131za ---------- *\/\nfunction renderMemory(g, play, ctx) {\n    let html = `<div class=\"gameStatus\">Oda <b>${ctx.code}<\/b><\/div>`;\n    if (g.status === \"waiting\") {\n        play.innerHTML = html + `<div class=\"gameStatus\">Rakip bekleniyor... Kod: <b>${ctx.code}<\/b><\/div>`;\n        return;\n    }\n    const cards = g.cards || [];\n    const flipped = g.flipped ? Object.values(g.flipped) : [];\n    const matched = g.matched ? Object.values(g.matched) : [];\n    const sc = g.scores || {};\n    const myTurn = g.turn === ctx.me;\n    html += `<div class=\"gameStatus\">${escapeHtml(g.hostName)}: ${sc.h || 0} \u00b7 ${escapeHtml(g.guestName || \"?\")}: ${sc.g || 0}<\/div>`;\n    const cols = g.size || Math.sqrt(cards.length) || 4;\n    html += `<div class=\"memGrid\" style=\"grid-template-columns:repeat(${cols},56px)\">` + cards.map((c, i) => {\n        const done = matched.includes(i), open = flipped.includes(i);\n        return `<button class=\"memCard ${done ? \"done\" : (open ? \"open\" : \"\")}\" data-i=\"${i}\">${done || open ? c : \"?\"}<\/button>`;\n    }).join(\"\") + `<\/div>`;\n    if (matched.length === cards.length && cards.length) {\n        const mine = ctx.role === \"host\" ? (sc.h || 0) : (sc.g || 0);\n        const other = ctx.role === \"host\" ? (sc.g || 0) : (sc.h || 0);\n        html += `<div class=\"gameStatus\" style=\"font-size:18px;color:#fff;\">${mine > other ? \"\ud83c\udf89 Kazand\u0131n!\" : (mine < other ? \"\ud83d\ude22 Kaybettin\" : \"Berabere!\")}<\/div>`;\n    } else {\n        html += `<div class=\"gameStatus\">${myTurn ? \"S\u0131ra sende!\" : \"Rakip oynuyor...\"}<\/div>`;\n    }\n    play.innerHTML = html;\n    play.querySelectorAll(\".memCard\").forEach(btn => {\n        btn.onclick = async () => {\n            const i = +btn.dataset.i;\n            const fresh = (await get(ref(database, ctx.path))).val();\n            if (!fresh || fresh.turn !== ctx.me) return;\n            const fl = fresh.flipped ? Object.values(fresh.flipped) : [];\n            const mt = fresh.matched ? Object.values(fresh.matched) : [];\n            if (fl.length >= 2 || fl.includes(i) || mt.includes(i)) return;\n            fl.push(i);\n            await update(ref(database, ctx.path), { flipped: fl });\n            if (fl.length === 2) {\n                const [a, b] = fl;\n                const key = ctx.role === \"host\" ? \"h\" : \"g\";\n                if (fresh.cards[a] === fresh.cards[b]) {\n                    setTimeout(async () => {\n                        const sc2 = (fresh.scores && fresh.scores[key]) || 0;\n                        const newMatched = [...mt, a, b];\n                        const upd = { flipped: null, matched: newMatched };\n                        upd[\"scores\/\" + key] = sc2 + 1;\n                        await update(ref(database, ctx.path), upd);\n                        if (newMatched.length === fresh.cards.length) {\n                            const s = (await get(ref(database, ctx.path + \"\/scores\"))).val() || {};\n                            const mine = key === \"h\" ? (s.h || 0) : (s.g || 0);\n                            const other = key === \"h\" ? (s.g || 0) : (s.h || 0);\n                            if (mine > other) bumpStat(\"gamesWon\");\n                        }\n                    }, 800);\n                } else {\n                    setTimeout(() => update(ref(database, ctx.path), {\n                        flipped: null, turn: ctx.me === fresh.host ? fresh.guest : fresh.host\n                    }), 900);\n                }\n            }\n        };\n    });\n}\n\nfunction memoryInitial() {\n    const size = +(document.getElementById(\"memSizeSelect\")?.value || 4);\n    const pairs = (size * size) \/ 2;\n    const pool = [\"\ud83c\udf4e\",\"\ud83d\ude80\",\"\ud83c\udfb8\",\"\ud83d\udc31\",\"\u26bd\",\"\ud83c\udf19\",\"\ud83c\udf55\",\"\ud83c\udfae\",\"\ud83d\udd25\",\"\ud83d\udc8e\",\"\ud83c\udf1f\",\"\ud83e\udd84\",\"\ud83c\udfaf\",\"\ud83c\udfb2\",\"\ud83c\udfa7\",\"\ud83e\udd8a\"];\n    const emojis = pool.slice(0, pairs);\n    const cards = [...emojis, ...emojis];\n    for (let i = cards.length - 1; i > 0; i--) {\n        const j = Math.floor(Math.random() * (i + 1));\n        [cards[i], cards[j]] = [cards[j], cards[i]];\n    }\n    return { cards, size, scores: { h: 0, g: 0 }, turn: currentUser.uid, flipped: null, matched: null };\n}\n\ndocument.getElementById(\"startConnect4Btn\").onclick = () =>\n    openLobby(\"c4\", \"Connect 4\", () => ({ board: Array(42).fill(\"\"), turn: \"R\", winner: null }), renderC4);\ndocument.getElementById(\"startNumberBtn\").onclick = () =>\n    openLobby(\"num\", \"Say\u0131 Tahmin D\u00fcellosu\", () => ({ secret: Math.floor(Math.random() * 100) + 1, turn: currentUser.uid, winner: null }), renderNumber);\ndocument.getElementById(\"startMemoryBtn\").onclick = () =>\n    openLobby(\"mem\", \"Haf\u0131za\", memoryInitial, renderMemory,\n        `<div style=\"margin:10px 0;text-align:center;\">\n            <label style=\"color:#b5bac1;font-size:13px;\">Alan boyutu: <\/label>\n            <select id=\"memSizeSelect\" style=\"padding:8px 12px;border:none;border-radius:8px;background:#1e1f22;color:#fff;\">\n                <option value=\"2\">2\u00d72 (kolay)<\/option>\n                <option value=\"4\" selected>4\u00d74 (normal)<\/option>\n                <option value=\"6\">6\u00d76 (zor)<\/option>\n            <\/select>\n        <\/div>`);\n\n\/* ---------- Skor kayd\u0131 ---------- *\/\nasync function saveScore(game, value, order) {\n    try {\n        const r = ref(database, \"scores\/\" + game + \"\/\" + currentUser.uid);\n        const s = await get(r);\n        const old = s.exists() ? s.val().value : null;\n        const better = old === null || (order === \"asc\" ? value < old : value > old);\n        if (better) await set(r, { value, name: currentProfile.displayName, at: Date.now() });\n        return better;\n    } catch (_) { return false; }\n}\n\nasync function renderLeaderboard(game, label, unit, order, into) {\n    const snap = await get(ref(database, \"scores\/\" + game));\n    let html = `<div class=\"sectionTitle\">${label}<\/div>`;\n    if (!snap.exists()) { into.innerHTML += html + `<div class=\"liveNote\">Hen\u00fcz skor yok.<\/div>`; return; }\n    const rows = Object.values(snap.val()).sort((a, b) => order === \"asc\" ? a.value - b.value : b.value - a.value).slice(0, 10);\n    rows.forEach((r, i) => { html += `<div class=\"lbRow\"><span>${i + 1}. ${escapeHtml(r.name || \"?\")}<\/span><b>${r.value} ${unit}<\/b><\/div>`; });\n    into.innerHTML += html;\n}\n\ndocument.getElementById(\"startLeaderboardBtn\").onclick = async () => {\n    const area = gameArea();\n    area.innerHTML = `<button class=\"gameBackBtn\" id=\"gameBackBtn\">\u2190 Geri<\/button><div class=\"gameStatus\">\ud83c\udfc6 Skor Tablolar\u0131<\/div><div id=\"lbBox\"><\/div>`;\n    gameBack(area);\n    const box = document.getElementById(\"lbBox\");\n    await renderLeaderboard(\"reaction\", \"\u26a1 Reaksiyon (en d\u00fc\u015f\u00fck)\", \"ms\", \"asc\", box);\n    await renderLeaderboard(\"clicker\", \"\ud83d\udc46 10 sn t\u0131klama (en y\u00fcksek)\", \"t\u0131k\", \"desc\", box);\n    await renderLeaderboard(\"hangman\", \"\ud83e\udea2 Adam asmaca galibiyet\", \"galibiyet\", \"desc\", box);\n    await renderLeaderboard(\"carrace\", \"\ud83c\udfce\ufe0f 2D Araba Yar\u0131\u015f\u0131 (en y\u00fcksek)\", \"skor\", \"desc\", box);\n};\n\n\/* ---------- Reaksiyon ---------- *\/\ndocument.getElementById(\"startReactionBtn\").onclick = () => {\n    const area = gameArea();\n    area.innerHTML = `<button class=\"gameBackBtn\" id=\"gameBackBtn\">\u2190 Geri<\/button>\n        <div class=\"gameStatus\">\u26a1 Reaksiyon Testi<\/div>\n        <div class=\"reactionPad\" id=\"rxPad\">Ba\u015flamak i\u00e7in t\u0131kla<\/div>\n        <div class=\"gameStatus\" id=\"rxInfo\"><\/div>`;\n    gameBack(area);\n    const pad = document.getElementById(\"rxPad\"), info = document.getElementById(\"rxInfo\");\n    let state = \"idle\", t0 = 0, timer = null;\n    pad.onclick = async () => {\n        if (state === \"idle\") {\n            state = \"wait\"; pad.className = \"reactionPad wait\"; pad.textContent = \"Ye\u015fili bekle...\";\n            timer = setTimeout(() => { state = \"go\"; pad.className = \"reactionPad go\"; pad.textContent = \"\u015e\u0130MD\u0130!\"; t0 = performance.now(); }, 1000 + Math.random() * 3000);\n        } else if (state === \"wait\") {\n            clearTimeout(timer); state = \"idle\"; pad.className = \"reactionPad\"; pad.textContent = \"\u00c7ok erken! Tekrar dene\";\n        } else {\n            const ms = Math.round(performance.now() - t0);\n            state = \"idle\"; pad.className = \"reactionPad\"; pad.textContent = ms + \" ms \u2014 tekrar i\u00e7in t\u0131kla\";\n            const better = await saveScore(\"reaction\", ms, \"asc\");\n            info.textContent = better ? \"\ud83c\udfc6 Yeni ki\u015fisel rekor!\" : \"\";\n        }\n    };\n};\n\n\/* ---------- 10 sn t\u0131klama ---------- *\/\ndocument.getElementById(\"startClickerBtn\").onclick = () => {\n    const area = gameArea();\n    area.innerHTML = `<button class=\"gameBackBtn\" id=\"gameBackBtn\">\u2190 Geri<\/button>\n        <div class=\"gameStatus\">\ud83d\udc46 10 Saniye T\u0131klama<\/div>\n        <button class=\"bigBtn\" id=\"clkBtn\" style=\"height:140px;font-size:22px;\">Ba\u015fla<\/button>\n        <div class=\"gameStatus\" id=\"clkInfo\"><\/div>`;\n    gameBack(area);\n    const btn = document.getElementById(\"clkBtn\"), info = document.getElementById(\"clkInfo\");\n    let running = false, count = 0, endAt = 0, tick = null;\n    btn.onclick = async () => {\n        if (!running) {\n            running = true; count = 0; endAt = Date.now() + 10000; btn.textContent = \"TIKLA! 0\";\n            tick = setInterval(async () => {\n                const left = Math.max(0, endAt - Date.now());\n                info.textContent = (left \/ 1000).toFixed(1) + \" sn\";\n                if (left <= 0) {\n                    clearInterval(tick); running = false;\n                    btn.textContent = count + \" t\u0131k \u2014 tekrar ba\u015fla\";\n                    const better = await saveScore(\"clicker\", count, \"desc\");\n                    info.textContent = better ? \"\ud83c\udfc6 Yeni ki\u015fisel rekor!\" : \"S\u00fcre bitti\";\n                }\n            }, 100);\n        } else {\n            count++; btn.textContent = \"TIKLA! \" + count;\n        }\n    };\n    const stop = area.querySelector(\"#gameBackBtn\");\n    stop.addEventListener(\"click\", () => clearInterval(tick));\n};\n\n\/* ---------- Adam Asmaca ---------- *\/\ndocument.getElementById(\"startHangmanBtn\").onclick = () => {\n    const WORDS = [\"KLAVYE\", \"ELMA\", \"B\u0130LG\u0130SAYAR\", \"TELEFON\", \"OYUN\", \"\u0130STANBUL\", \"FUTBOL\", \"M\u00dcZ\u0130K\", \"KAHVE\", \"DEN\u0130Z\", \"YILDIZ\", \"PROGRAM\", \"\u0130NTERNET\", \"SEVG\u0130\", \"D\u00dcNYA\", \"ROBOT\", \"TELEV\u0130ZYON\", \"BULUT\", \"G\u0130TAR\", \"KARANLIK\"];\n    const LETTERS = \"ABC\u00c7DEFG\u011eHI\u0130JKLMNO\u00d6PRS\u015eTU\u00dcVYZ\".split(\"\");\n    const area = gameArea();\n    let word = \"\", guessed = new Set(), lives = 6, over = false;\n    function newWord() { word = WORDS[Math.floor(Math.random() * WORDS.length)]; guessed = new Set(); lives = 6; over = false; draw(); }\n    async function draw() {\n        const shown = word.split(\"\").map(ch => guessed.has(ch) ? ch : \"_\").join(\" \");\n        const won = !word.split(\"\").some(ch => !guessed.has(ch));\n        area.innerHTML = `<button class=\"gameBackBtn\" id=\"gameBackBtn\">\u2190 Geri<\/button>\n            <div class=\"gameStatus\">\ud83e\udea2 Adam Asmaca \u00b7 Hak: ${\"\u2764\ufe0f\".repeat(lives)}${\"\ud83d\udda4\".repeat(6 - lives)}<\/div>\n            <div class=\"gameStatus\" style=\"font-size:30px;letter-spacing:4px;color:#fff;\">${shown}<\/div>\n            <div style=\"display:flex;flex-wrap:wrap;gap:6px;justify-content:center;margin-top:10px;\">\n                ${LETTERS.map(l => `<button data-l=\"${l}\" ${guessed.has(l) || over ? \"disabled\" : \"\"} style=\"width:38px;height:38px;border:none;border-radius:8px;background:${guessed.has(l) ? \"#2b2d31\" : \"#404249\"};color:#fff;\">${l}<\/button>`).join(\"\")}\n            <\/div>\n            <div class=\"gameStatus\" id=\"hmMsg\" style=\"font-size:17px;color:#fff;margin-top:12px;\"><\/div>\n            ${over ? `<button class=\"bigBtn\" id=\"hmAgain\">Yeni Kelime<\/button>` : \"\"}`;\n        gameBack(area);\n        area.querySelectorAll(\"[data-l]\").forEach(b => b.onclick = () => {\n            if (over) return;\n            const l = b.dataset.l;\n            guessed.add(l);\n            if (!word.includes(l)) lives--;\n            const nowWon = !word.split(\"\").some(ch => !guessed.has(ch));\n            if (nowWon || lives <= 0) over = true;\n            draw();\n        });\n        if (over) {\n            const msgEl = document.getElementById(\"hmMsg\");\n            if (won) {\n                msgEl.textContent = \"\ud83c\udf89 Bildin!\";\n                const r = ref(database, \"scores\/hangman\/\" + currentUser.uid);\n                const s = await get(r);\n                await set(r, { value: (s.exists() ? s.val().value : 0) + 1, name: currentProfile.displayName, at: Date.now() });\n                bumpStat(\"gamesWon\");\n            } else msgEl.textContent = \"\ud83d\ude22 Kelime: \" + word;\n            document.getElementById(\"hmAgain\").onclick = newWord;\n        }\n    }\n    newWord();\n};\n\n\/* ---------- UNO (1\u20134 oyuncu, bot + davet) ---------- *\/\ndocument.getElementById(\"startUnoBtn\").onclick = () => {\n    bumpDailyQuest(\"games\").catch(() => {});\n    addSeasonPts(2).catch(() => {});\n    openUnoLobby();\n};\n\nfunction openUnoLobby() {\n    const area = gameArea();\n    if (!area) return;\n    area.innerHTML = `\n        <button class=\"gameBackBtn\" id=\"gameBackBtn\">\u2190 Geri<\/button>\n        <div class=\"gameStatus\">\ud83c\udccf UNO<\/div>\n        <div style=\"color:#b5bac1;font-size:13px;margin:8px 0;\">Ka\u00e7 oyuncu? (bo\u015f koltuklar bot olur)<\/div>\n        <div style=\"display:flex;flex-wrap:wrap;gap:8px;margin:12px 0;\">\n            <button class=\"bigBtn unoPlayers\" data-n=\"1\" style=\"flex:1;min-width:70px;\">1<\/button>\n            <button class=\"bigBtn unoPlayers\" data-n=\"2\" style=\"flex:1;min-width:70px;\">2<\/button>\n            <button class=\"bigBtn unoPlayers\" data-n=\"3\" style=\"flex:1;min-width:70px;\">3<\/button>\n            <button class=\"bigBtn unoPlayers\" data-n=\"4\" style=\"flex:1;min-width:70px;\">4<\/button>\n        <\/div>\n        <div class=\"sectionTitle\">Davet \/ Online<\/div>\n        <button class=\"bigBtn\" id=\"unoCreateOnline\" style=\"background:#5865f2;\">Oda olu\u015ftur + davet kodu<\/button>\n        <div style=\"display:flex;gap:8px;margin-top:10px;\">\n            <input id=\"unoJoinCode\" maxlength=\"8\" placeholder=\"Davet kodu\" style=\"flex:1;padding:12px;border:none;border-radius:8px;background:#1e1f22;color:#fff;\">\n            <button id=\"unoJoinBtn\" style=\"padding:12px 16px;border:none;border-radius:8px;background:#23a559;color:#fff;font-weight:bold;\">Kat\u0131l<\/button>\n        <\/div>\n        <div id=\"unoInviteBox\" style=\"margin-top:12px;font-size:13px;color:#faa61a;\"><\/div>`;\n    gameBack(area);\n    area.querySelectorAll(\".unoPlayers\").forEach(btn => {\n        btn.onclick = () => startUnoLocal(+btn.dataset.n);\n    });\n    document.getElementById(\"unoCreateOnline\").onclick = async () => {\n        if (!currentUser) return;\n        const code = Math.random().toString(36).substring(2, 8).toUpperCase();\n        await set(ref(database, \"minigames\/uno\/\" + code), {\n            host: currentUser.uid, hostName: currentProfile.displayName,\n            players: { [currentUser.uid]: { name: currentProfile.displayName, seat: 0 } },\n            maxPlayers: 4, status: \"waiting\", createdAt: Date.now()\n        });\n        const link = location.origin + location.pathname + \"?uno=\" + code;\n        document.getElementById(\"unoInviteBox\").innerHTML =\n            \"Kod: <b>\" + code + \"<\/b><br>Link: <span style='word-break:break-all;'>\" + escapeHtml(link) + \"<\/span><br>\" +\n            \"<button class='liveBtn' id='unoCopyInv' style='margin-top:8px;'>Kopyala<\/button> \u00b7 arkada\u015flar kat\u0131ls\u0131n, sonra Ba\u015flat\";\n        document.getElementById(\"unoCopyInv\")?.addEventListener(\"click\", () => {\n            navigator.clipboard?.writeText(\"UNO oda: \" + code + \" \" + link);\n            alert(\"Kopyaland\u0131\");\n        });\n        watchUnoLobby(code, true);\n    };\n    document.getElementById(\"unoJoinBtn\").onclick = async () => {\n        const code = (document.getElementById(\"unoJoinCode\").value || \"\").trim().toUpperCase();\n        if (!code) return alert(\"Kod gir\");\n        const snap = await get(ref(database, \"minigames\/uno\/\" + code));\n        if (!snap.exists()) return alert(\"Oda yok\");\n        const d = snap.val();\n        if (d.status !== \"waiting\") return alert(\"Oyun ba\u015flam\u0131\u015f\");\n        const count = d.players ? Object.keys(d.players).length : 0;\n        if (count >= (d.maxPlayers || 4)) return alert(\"Dolu\");\n        await update(ref(database, \"minigames\/uno\/\" + code + \"\/players\/\" + currentUser.uid), {\n            name: currentProfile.displayName, seat: count\n        });\n        watchUnoLobby(code, false);\n    };\n}\n\nfunction watchUnoLobby(code, isHost) {\n    const area = document.getElementById(\"activeGameArea\");\n    if (currentGameUnsub) { currentGameUnsub(); currentGameUnsub = null; }\n    currentGameUnsub = onValue(ref(database, \"minigames\/uno\/\" + code), snap => {\n        if (!snap.exists() || !area) return;\n        const d = snap.val();\n        if (d.status === \"playing\" && d.state) {\n            \/\/ online sync basit: host state yazar \u2014 \u015fimdilik local'e d\u00fc\u015f\n            return;\n        }\n        const names = d.players ? Object.values(d.players).map(p => p.name) : [];\n        area.innerHTML = `\n            <button class=\"gameBackBtn\" id=\"gameBackBtn\">\u2190 Geri<\/button>\n            <div class=\"gameStatus\">UNO oda <b>${code}<\/b><\/div>\n            <div style=\"color:#b5bac1;margin:8px 0;\">Oyuncular (${names.length}\/4): ${names.map(n => escapeHtml(n)).join(\", \") || \"\u2014\"}<\/div>\n            ${isHost ? `<button class=\"bigBtn\" id=\"unoStartOnline\">Ba\u015flat (${Math.max(1, names.length)} ki\u015fi + bot)<\/button>\n            <div style=\"font-size:12px;color:#949ba4;margin-top:8px;\">Davet kodu: <b>${code}<\/b><\/div>` : `<div class=\"liveNote\">Host ba\u015flat\u0131nca oyun a\u00e7\u0131l\u0131r (\u015fu an ayn\u0131 cihazda local oynan\u0131r)<\/div>`}`;\n        gameBack(area);\n        document.getElementById(\"unoStartOnline\")?.addEventListener(\"click\", async () => {\n            \/\/ Online senkron: host ilk state yazar, herkes dinler\n            const playerIds = Object.keys(d.players || {});\n            while (playerIds.length < 2) {\n                const bid = \"bot_\" + playerIds.length;\n                playerIds.push(bid);\n                await update(ref(database, \"minigames\/uno\/\" + code + \"\/players\/\" + bid), {\n                    name: \"Bot \" + playerIds.length, seat: playerIds.length - 1, bot: true\n                });\n            }\n            const state = buildUnoOnlineState(playerIds, d.players || {});\n            await update(ref(database, \"minigames\/uno\/\" + code), { status: \"playing\", state, turn: 0 });\n        });\n        \/\/ oynarken state dinle\n        if (d.status === \"playing\" && d.state) {\n            renderUnoOnline(code, d, isHost);\n        }\n    });\n}\n\nfunction buildUnoOnlineState(playerIds, playersMeta) {\n    const COLORS = [\"red\", \"yellow\", \"green\", \"blue\"];\n    const deck = [];\n    COLORS.forEach(c => {\n        deck.push({ c, v: \"0\" });\n        for (let i = 1; i <= 9; i++) { deck.push({ c, v: String(i) }); deck.push({ c, v: String(i) }); }\n        [\"skip\", \"reverse\", \"+2\"].forEach(v => { deck.push({ c, v }); deck.push({ c, v }); });\n    });\n    for (let i = 0; i < 4; i++) { deck.push({ c: \"wild\", v: \"wild\" }); deck.push({ c: \"wild\", v: \"+4\" }); }\n    for (let i = deck.length - 1; i > 0; i--) {\n        const j = Math.floor(Math.random() * (i + 1));\n        [deck[i], deck[j]] = [deck[j], deck[i]];\n    }\n    const hands = {};\n    playerIds.forEach(id => {\n        hands[id] = [];\n        for (let k = 0; k < 7; k++) hands[id].push(deck.pop());\n    });\n    let top = deck.pop();\n    while (top.c === \"wild\") { deck.unshift(top); top = deck.pop(); }\n    return {\n        deck, discard: [top], hands, order: playerIds, dir: 1, turn: 0,\n        names: Object.fromEntries(playerIds.map(id => [id, (playersMeta[id] && playersMeta[id].name) || id])),\n        winner: null\n    };\n}\n\nfunction renderUnoOnline(code, d, isHost) {\n    const area = document.getElementById(\"activeGameArea\");\n    if (!area || !d.state) return;\n    const st = d.state;\n    const myId = currentUser.uid;\n    const order = st.order || [];\n    const turnUid = order[st.turn % order.length];\n    const top = (st.discard || [])[(st.discard || []).length - 1] || { c: \"red\", v: \"?\" };\n    const COLOR_HEX = { red: \"#ed4245\", yellow: \"#faa61a\", green: \"#23a559\", blue: \"#5865f2\", wild: \"#111\" };\n    const label = (card) => (card.v === \"skip\" ? \"\u2298\" : card.v === \"reverse\" ? \"\u21ba\" : card.v);\n    if (st.winner) {\n        area.innerHTML = `<button class=\"gameBackBtn\" id=\"gameBackBtn\">\u2190 Geri<\/button>\n            <div class=\"gameStatus\">\ud83c\udf89 ${escapeHtml(st.names[st.winner] || st.winner)} kazand\u0131!<\/div>`;\n        gameBack(area);\n        return;\n    }\n    const myHand = (st.hands && st.hands[myId]) || [];\n    let html = `<button class=\"gameBackBtn\" id=\"gameBackBtn\">\u2190 Geri<\/button>\n        <div class=\"gameStatus\">UNO Online \u00b7 S\u0131ra: <b>${escapeHtml(st.names[turnUid] || \"?\")}<\/b><\/div>\n        <div style=\"display:flex;gap:6px;flex-wrap:wrap;justify-content:center;margin:8px 0;\">\n            ${order.map(id => `<span style=\"padding:6px 10px;background:${id === turnUid ? \"#5865f2\" : \"#1e1f22\"};border-radius:8px;font-size:12px;\">${escapeHtml(st.names[id] || id)}: ${(st.hands[id] || []).length}<\/span>`).join(\"\")}\n        <\/div>\n        <div style=\"text-align:center;margin:12px;\">\n            <div style=\"display:inline-block;width:70px;height:96px;border-radius:10px;background:${COLOR_HEX[top.c] || \"#333\"};color:#fff;font-weight:bold;line-height:96px;font-size:20px;\">${label(top)}<\/div>\n        <\/div>`;\n    if (turnUid === myId) {\n        html += `<div style=\"display:flex;flex-wrap:wrap;gap:6px;justify-content:center;\">`;\n        myHand.forEach((card, idx) => {\n            const ok = card.c === \"wild\" || card.c === top.c || card.v === top.v;\n            html += `<button class=\"unoOnCard\" data-i=\"${idx}\" ${ok ? \"\" : \"disabled\"} style=\"width:50px;height:70px;border-radius:8px;border:2px solid ${ok ? \"#fff\" : \"#333\"};background:${COLOR_HEX[card.c] || \"#222\"};color:#fff;opacity:${ok ? 1 : 0.4};\">${label(card)}<\/button>`;\n        });\n        html += `<\/div><div style=\"text-align:center;margin-top:10px;\"><button class=\"liveBtn\" id=\"unoOnDraw\">\u00c7ek<\/button><\/div>`;\n    } else {\n        html += `<div class=\"liveNote\">Rakip oynuyor...<\/div>\n            <div style=\"text-align:center;margin-top:8px;\"><button class=\"liveBtn\" id=\"unoSpectateBet\">\u0130zleyici bahisi 10 VC<\/button><\/div>`;\n    }\n    area.innerHTML = html;\n    gameBack(area);\n    document.getElementById(\"unoSpectateBet\")?.addEventListener(\"click\", async () => {\n        if ((currentProfile.coins || 0) < 10) return alert(\"Yetersiz VC\");\n        const pick = prompt(\"Kime bas\u0131yorsun? Kullan\u0131c\u0131 id veya isim (s\u0131ra listesinden)\");\n        if (!pick) return;\n        await addCoins(currentUser.uid, -10);\n        currentProfile.coins -= 10;\n        await push(ref(database, \"minigames\/uno\/\" + code + \"\/bets\"), {\n            uid: currentUser.uid, pick, amount: 10, at: Date.now()\n        });\n        alert(\"Bahis al\u0131nd\u0131. Kazanan do\u011fruysa 2x (basit).\");\n        updateMyProfileDisplay();\n    });\n    area.querySelectorAll(\".unoOnCard\").forEach(btn => {\n        btn.onclick = async () => {\n            const i = +btn.dataset.i;\n            const hand = st.hands[myId].slice();\n            const card = hand.splice(i, 1)[0];\n            if (!card) return;\n            st.hands[myId] = hand;\n            st.discard.push(card);\n            if (hand.length === 0) {\n                st.winner = myId;\n                await update(ref(database, \"minigames\/uno\/\" + code), { state: st });\n                \/\/ bahis \u00f6de\n                try {\n                    const bs = await get(ref(database, \"minigames\/uno\/\" + code + \"\/bets\"));\n                    if (bs.exists()) {\n                        for (const [, b] of Object.entries(bs.val())) {\n                            if (b.pick === myId || b.pick === st.names[myId]) {\n                                await addCoins(b.uid, (b.amount || 10) * 2);\n                            }\n                        }\n                    }\n                } catch (_) {}\n                return;\n            }\n            let turn = st.turn;\n            if (card.v === \"reverse\") st.dir = -(st.dir || 1);\n            if (card.v === \"skip\") turn += (st.dir || 1);\n            turn += (st.dir || 1);\n            st.turn = ((turn % order.length) + order.length) % order.length;\n            await update(ref(database, \"minigames\/uno\/\" + code), { state: st });\n        };\n    });\n    document.getElementById(\"unoOnDraw\")?.addEventListener(\"click\", async () => {\n        if (!st.deck || !st.deck.length) return;\n        st.hands[myId] = st.hands[myId] || [];\n        st.hands[myId].push(st.deck.pop());\n        st.turn = (st.turn + (st.dir || 1) + order.length) % order.length;\n        await update(ref(database, \"minigames\/uno\/\" + code), { state: st });\n    });\n}\n\nfunction startUnoLocal(humanCount, nameList) {\n    const area = gameArea();\n    if (!area) return;\n    const COLORS = [\"red\", \"yellow\", \"green\", \"blue\"];\n    const COLOR_HEX = { red: \"#ed4245\", yellow: \"#faa61a\", green: \"#23a559\", blue: \"#5865f2\", wild: \"#111\" };\n    function makeDeck() {\n        const d = [];\n        COLORS.forEach(c => {\n            d.push({ c, v: \"0\" });\n            for (let i = 1; i <= 9; i++) { d.push({ c, v: String(i) }); d.push({ c, v: String(i) }); }\n            [\"skip\", \"reverse\", \"+2\"].forEach(v => { d.push({ c, v }); d.push({ c, v }); });\n        });\n        for (let i = 0; i < 4; i++) { d.push({ c: \"wild\", v: \"wild\" }); d.push({ c: \"wild\", v: \"+4\" }); }\n        for (let i = d.length - 1; i > 0; i--) {\n            const j = Math.floor(Math.random() * (i + 1));\n            [d[i], d[j]] = [d[j], d[i]];\n        }\n        return d;\n    }\n    const n = Math.max(1, Math.min(4, humanCount || 1));\n    let deck = makeDeck();\n    const players = [];\n    for (let i = 0; i < 4; i++) {\n        const isHuman = i < n;\n        const hand = [];\n        for (let k = 0; k < 7; k++) hand.push(deck.pop());\n        players.push({\n            name: isHuman ? (nameList && nameList[i] ? nameList[i] : (i === 0 ? (currentProfile.displayName || \"Sen\") : \"Oyuncu \" + (i + 1))) : (\"Bot \" + (i + 1)),\n            bot: !isHuman,\n            hand\n        });\n        if (players.length >= n + (4 - n) && i >= n - 1 && n < 4) {\n            \/\/ fill remaining as bots up to at least n seats - actually always 4 seats with bots\n        }\n    }\n    \/\/ only keep n humans + bots to make total count between n and 4: use totalPlayers = max(n, ...) user asked 1-4\n    const total = Math.max(n, n); \/\/ play with `n` players where extras are bots if we set total fixed\n    \/\/ Better: totalPlayers = n (all human on same device for 2-4) OR 1 human + bots\n    \/\/ For same-device multi: all n are human alternating. For 1 player: 1 human + 3 bots.\n    \/\/ Re-init cleanly:\n    deck = makeDeck();\n    players.length = 0;\n    const totalPlayers = n === 1 ? 4 : n; \/\/ solo vs 3 bots; multi = that many humans on same device\n    for (let i = 0; i < totalPlayers; i++) {\n        const hand = [];\n        for (let k = 0; k < 7; k++) hand.push(deck.pop());\n        const isBot = n === 1 ? i > 0 : false;\n        players.push({\n            name: isBot ? (\"Bot \" + i) : (nameList && nameList[i] ? nameList[i] : (i === 0 ? (currentProfile.displayName || \"Sen\") : \"P\" + (i + 1))),\n            bot: isBot,\n            hand\n        });\n    }\n    let discard = [deck.pop()];\n    while (discard[0].c === \"wild\") {\n        deck.unshift(discard.pop());\n        discard.push(deck.pop());\n    }\n    let turn = 0, dir = 1, winner = null, wildPick = null;\n\n    function top() { return discard[discard.length - 1]; }\n    function canPlay(card) {\n        const t = top();\n        if (card.c === \"wild\") return true;\n        if (card.c === t.c || card.v === t.v) return true;\n        return false;\n    }\n    function drawOne(p) {\n        if (deck.length < 2) {\n            const keep = discard.pop();\n            deck = discard.splice(0).concat(deck);\n            for (let i = deck.length - 1; i > 0; i--) {\n                const j = Math.floor(Math.random() * (i + 1));\n                [deck[i], deck[j]] = [deck[j], deck[i]];\n            }\n            discard = [keep];\n        }\n        if (deck.length) p.hand.push(deck.pop());\n    }\n    function nextTurn(skip) {\n        turn = (turn + dir + players.length) % players.length;\n        if (skip) turn = (turn + dir + players.length) % players.length;\n    }\n    function applyCard(card, chooserColor) {\n        discard.push(card);\n        if (card.v === \"reverse\") {\n            dir *= -1;\n            if (players.length === 2) nextTurn(false);\n        } else if (card.v === \"skip\") {\n            nextTurn(true);\n            return;\n        } else if (card.v === \"+2\") {\n            nextTurn(false);\n            drawOne(players[turn]); drawOne(players[turn]);\n            nextTurn(false);\n            return;\n        } else if (card.v === \"+4\") {\n            card.c = chooserColor || COLORS[Math.floor(Math.random() * 4)];\n            nextTurn(false);\n            for (let i = 0; i < 4; i++) drawOne(players[turn]);\n            nextTurn(false);\n            return;\n        } else if (card.v === \"wild\") {\n            card.c = chooserColor || COLORS[Math.floor(Math.random() * 4)];\n        }\n        nextTurn(false);\n    }\n    function cardLabel(card) {\n        const v = card.v === \"skip\" ? \"\u2298\" : card.v === \"reverse\" ? \"\u21ba\" : card.v;\n        return (card.c === \"wild\" || card.v === \"wild\" || card.v === \"+4\" ? \"\u2605\" : \"\") + v;\n    }\n    function render() {\n        if (winner != null) {\n            area.innerHTML = `<button class=\"gameBackBtn\" id=\"gameBackBtn\">\u2190 Geri<\/button>\n                <div class=\"gameStatus\">\ud83c\udf89 ${escapeHtml(players[winner].name)} kazand\u0131!<\/div>\n                <button class=\"bigBtn\" id=\"unoAgain\">Tekrar<\/button>`;\n            gameBack(area);\n            document.getElementById(\"unoAgain\").onclick = () => startUnoLocal(n, nameList);\n            grantXp(currentUser.uid, 10, \"uno\").catch(() => {});\n            return;\n        }\n        const t = top();\n        let html = `<button class=\"gameBackBtn\" id=\"gameBackBtn\">\u2190 Geri<\/button>\n            <div class=\"gameStatus\">UNO \u00b7 S\u0131ra: <b>${escapeHtml(players[turn].name)}<\/b>${players[turn].bot ? \" (bot)\" : \"\"}<\/div>\n            <div style=\"display:flex;gap:8px;flex-wrap:wrap;justify-content:center;margin:8px 0;\">`;\n        players.forEach((p, i) => {\n            html += `<div style=\"padding:8px 12px;border-radius:8px;background:${i === turn ? \"#5865f2\" : \"#1e1f22\"};font-size:13px;\">${escapeHtml(p.name)}: ${p.hand.length} kart<\/div>`;\n        });\n        html += `<\/div>\n            <div style=\"text-align:center;margin:12px 0;\">\n                <div style=\"display:inline-block;width:72px;height:100px;border-radius:10px;background:${COLOR_HEX[t.c] || \"#333\"};color:#fff;font-weight:bold;font-size:22px;line-height:100px;box-shadow:0 4px 12px rgba(0,0,0,.4);\">${cardLabel(t)}<\/div>\n                <div style=\"font-size:12px;color:#949ba4;margin-top:6px;\">\u00dcst kart \u00b7 ${t.c} ${t.v}<\/div>\n            <\/div>`;\n        if (wildPick) {\n            html += `<div style=\"text-align:center;margin:8px;\">Renk se\u00e7:\n                ${COLORS.map(c => `<button class=\"unoColor\" data-c=\"${c}\" style=\"width:40px;height:40px;border:none;border-radius:50%;background:${COLOR_HEX[c]};margin:4px;\"><\/button>`).join(\"\")}\n            <\/div>`;\n        } else if (!players[turn].bot) {\n            html += `<div style=\"display:flex;flex-wrap:wrap;gap:6px;justify-content:center;max-width:480px;margin:0 auto;\">`;\n            players[turn].hand.forEach((card, idx) => {\n                const ok = canPlay(card);\n                html += `<button class=\"unoCard\" data-i=\"${idx}\" ${ok ? \"\" : \"disabled\"}\n                    style=\"width:52px;height:72px;border-radius:8px;border:2px solid ${ok ? \"#fff\" : \"#333\"};background:${COLOR_HEX[card.c] || \"#222\"};color:#fff;font-weight:bold;opacity:${ok ? 1 : 0.4};\">${cardLabel(card)}<\/button>`;\n            });\n            html += `<\/div>\n                <div style=\"text-align:center;margin-top:10px;\">\n                    <button class=\"liveBtn\" id=\"unoDraw\">Kart \u00e7ek<\/button>\n                <\/div>`;\n        } else {\n            html += `<div class=\"liveNote\">Bot d\u00fc\u015f\u00fcn\u00fcyor...<\/div>`;\n        }\n        area.innerHTML = html;\n        gameBack(area);\n        area.querySelectorAll(\".unoCard\").forEach(btn => {\n            btn.onclick = () => {\n                const i = +btn.dataset.i;\n                const card = players[turn].hand[i];\n                if (!canPlay(card)) return;\n                if (card.v === \"wild\" || card.v === \"+4\") {\n                    wildPick = { idx: i, card };\n                    render();\n                    return;\n                }\n                players[turn].hand.splice(i, 1);\n                if (players[turn].hand.length === 0) { winner = turn; render(); return; }\n                applyCard(card);\n                render();\n                if (!winner && players[turn].bot) setTimeout(botPlay, 500);\n            };\n        });\n        area.querySelectorAll(\".unoColor\").forEach(btn => {\n            btn.onclick = () => {\n                const card = wildPick.card;\n                players[turn].hand.splice(wildPick.idx, 1);\n                wildPick = null;\n                if (players[turn].hand.length === 0) { winner = turn; render(); return; }\n                applyCard(card, btn.dataset.c);\n                render();\n                if (!winner && players[turn].bot) setTimeout(botPlay, 500);\n            };\n        });\n        document.getElementById(\"unoDraw\")?.addEventListener(\"click\", () => {\n            drawOne(players[turn]);\n            nextTurn(false);\n            render();\n            if (!winner && players[turn].bot) setTimeout(botPlay, 500);\n        });\n        if (players[turn].bot && !winner) setTimeout(botPlay, 600);\n    }\n    function botPlay() {\n        if (winner != null || !players[turn].bot) return;\n        const hand = players[turn].hand;\n        let idx = hand.findIndex(c => canPlay(c) && c.c !== \"wild\");\n        if (idx < 0) idx = hand.findIndex(c => canPlay(c));\n        if (idx < 0) {\n            drawOne(players[turn]);\n            nextTurn(false);\n            render();\n            return;\n        }\n        const card = hand.splice(idx, 1)[0];\n        if (players[turn].hand.length === 0) { winner = turn; render(); return; }\n        applyCard(card, COLORS[Math.floor(Math.random() * 4)]);\n        render();\n    }\n    render();\n}\n\n\/* ---------- Ludo basit (2\u20134, ayn\u0131 cihaz) ---------- *\/\ndocument.getElementById(\"startLudoBtn\").onclick = () => {\n    const area = gameArea();\n    if (!area) return;\n    area.innerHTML = `\n        <button class=\"gameBackBtn\" id=\"gameBackBtn\">\u2190 Geri<\/button>\n        <div class=\"gameStatus\">\ud83c\udfb2 Ludo (basit)<\/div>\n        <div style=\"color:#b5bac1;font-size:13px;\">Oyuncu say\u0131s\u0131<\/div>\n        <div style=\"display:flex;gap:8px;margin:12px 0;\">\n            ${[2,3,4].map(n => `<button class=\"bigBtn ludoN\" data-n=\"${n}\" style=\"flex:1;\">${n}<\/button>`).join(\"\")}\n        <\/div>`;\n    gameBack(area);\n    area.querySelectorAll(\".ludoN\").forEach(b => {\n        b.onclick = () => startLudoSimple(+b.dataset.n);\n    });\n};\n\nfunction startLudoSimple(n) {\n    const area = gameArea();\n    if (!area) return;\n    const goal = 20;\n    const pos = Array(n).fill(0);\n    let turn = 0, last = 0, won = null;\n    function draw() {\n        if (won != null) {\n            area.innerHTML = `<button class=\"gameBackBtn\" id=\"gameBackBtn\">\u2190 Geri<\/button>\n                <div class=\"gameStatus\">\ud83c\udf89 Oyuncu ${won + 1} kazand\u0131!<\/div>\n                <button class=\"bigBtn\" id=\"ludoAgain\">Tekrar<\/button>`;\n            gameBack(area);\n            document.getElementById(\"ludoAgain\").onclick = () => startLudoSimple(n);\n            return;\n        }\n        area.innerHTML = `\n            <button class=\"gameBackBtn\" id=\"gameBackBtn\">\u2190 Geri<\/button>\n            <div class=\"gameStatus\">S\u0131ra: Oyuncu ${turn + 1} \u00b7 hedef ${goal}<\/div>\n            <div style=\"margin:12px 0;\">${pos.map((p, i) =>\n                `<div style=\"margin:6px 0;padding:10px;background:#1e1f22;border-radius:8px;\">\n                    P${i + 1}: ${\"\u25cf\".repeat(Math.min(p, goal))}${\"\u25cb\".repeat(Math.max(0, goal - p))} (${p})\n                <\/div>`).join(\"\")}<\/div>\n            <div class=\"gameStatus\" style=\"font-size:32px;\">${last ? \"\ud83c\udfb2 \" + last : \"Zar at\"}<\/div>\n            <button class=\"bigBtn\" id=\"ludoRoll\">Zar at<\/button>`;\n        gameBack(area);\n        document.getElementById(\"ludoRoll\").onclick = () => {\n            last = 1 + Math.floor(Math.random() * 6);\n            pos[turn] = Math.min(goal, pos[turn] + last);\n            if (pos[turn] >= goal) { won = turn; draw(); return; }\n            turn = (turn + 1) % n;\n            draw();\n        };\n    }\n    draw();\n}\n\n\/* ---------- Crew Panic (Among Us tarz\u0131) ---------- *\/\ndocument.getElementById(\"startAmongBtn\").onclick = () => openAmongLobby();\n\nconst AMONG_BOT_NAMES = [\"Bot Red\", \"Bot Blue\", \"Bot Green\", \"Bot Pink\", \"Bot Orange\", \"Bot Cyan\", \"Bot Lime\"];\n\nfunction openAmongLobby() {\n    const area = gameArea();\n    if (!area) return;\n    area.innerHTML = `\n        <button class=\"gameBackBtn\" id=\"gameBackBtn\">\u2190 Geri<\/button>\n        <div class=\"gameStatus\">\ud83d\ude80 Crew Panic<\/div>\n        <p style=\"color:#b5bac1;font-size:13px;\">G\u00f6rev \u00b7 oylama \u00b7 botlarla veya arkada\u015flarla. 4\u20138 koltuk.<\/p>\n        <div class=\"sectionTitle\">Botlarla oyna (an\u0131nda)<\/div>\n        <div style=\"display:flex;flex-wrap:wrap;gap:8px;margin:8px 0;\">\n            <button class=\"bigBtn amongBotN\" data-n=\"4\" style=\"flex:1;min-width:70px;\">4 ki\u015fi<\/button>\n            <button class=\"bigBtn amongBotN\" data-n=\"5\" style=\"flex:1;min-width:70px;\">5 ki\u015fi<\/button>\n            <button class=\"bigBtn amongBotN\" data-n=\"6\" style=\"flex:1;min-width:70px;\">6 ki\u015fi<\/button>\n            <button class=\"bigBtn amongBotN\" data-n=\"8\" style=\"flex:1;min-width:70px;\">8 ki\u015fi<\/button>\n        <\/div>\n        <div class=\"sectionTitle\">Online oda<\/div>\n        <button class=\"bigBtn\" id=\"amongCreate\" style=\"background:#5865f2;\">Oda olu\u015ftur (+ bot doldur)<\/button>\n        <div style=\"display:flex;gap:8px;margin-top:10px;\">\n            <input id=\"amongCode\" maxlength=\"8\" placeholder=\"Oda kodu\" style=\"flex:1;padding:12px;border:none;border-radius:8px;background:#1e1f22;color:#fff;\">\n            <button id=\"amongJoin\" style=\"padding:12px 16px;border:none;border-radius:8px;background:#23a559;color:#fff;font-weight:bold;\">Kat\u0131l<\/button>\n        <\/div>`;\n    gameBack(area);\n    area.querySelectorAll(\".amongBotN\").forEach(btn => {\n        btn.onclick = () => startAmongWithBots(+btn.dataset.n);\n    });\n    document.getElementById(\"amongCreate\").onclick = async () => {\n        const code = Math.random().toString(36).substring(2, 7).toUpperCase();\n        const players = {\n            [currentUser.uid]: { name: currentProfile.displayName, alive: true, tasks: 0, bot: false }\n        };\n        \/\/ 3 bot ekle (toplam 4)\n        for (let i = 0; i < 3; i++) {\n            const bid = \"bot_\" + i + \"_\" + Date.now().toString(36);\n            players[bid] = { name: AMONG_BOT_NAMES[i], alive: true, tasks: 0, bot: true };\n        }\n        await set(ref(database, \"amongRooms\/\" + code), {\n            host: currentUser.uid, status: \"lobby\", players, fillBots: true, createdAt: Date.now()\n        });\n        watchAmong(code, true);\n    };\n    document.getElementById(\"amongJoin\").onclick = async () => {\n        const code = (document.getElementById(\"amongCode\").value || \"\").trim().toUpperCase();\n        if (!code) return;\n        const s = await get(ref(database, \"amongRooms\/\" + code));\n        if (!s.exists()) return alert(\"Oda yok\");\n        const d = s.val();\n        if (d.status !== \"lobby\") return alert(\"Oyun ba\u015flam\u0131\u015f\");\n        if (Object.keys(d.players || {}).length >= 8) return alert(\"Dolu\");\n        await update(ref(database, \"amongRooms\/\" + code + \"\/players\/\" + currentUser.uid), {\n            name: currentProfile.displayName, alive: true, tasks: 0, bot: false\n        });\n        watchAmong(code, d.host === currentUser.uid);\n    };\n}\n\n\/** Yerel Crew Panic \u2014 sen + botlar (Firebase gerekmez) *\/\nfunction startAmongWithBots(total) {\n    total = Math.max(4, Math.min(8, total || 4));\n    const area = gameArea();\n    if (!area) return;\n    const players = {};\n    const roles = {};\n    const myId = \"me\";\n    players[myId] = { name: currentProfile.displayName || \"Sen\", alive: true, tasks: 0, bot: false };\n    for (let i = 1; i < total; i++) {\n        const id = \"bot_\" + i;\n        players[id] = { name: AMONG_BOT_NAMES[(i - 1) % AMONG_BOT_NAMES.length], alive: true, tasks: 0, bot: true };\n    }\n    const ids = Object.keys(players);\n    const imp = ids[Math.floor(Math.random() * ids.length)];\n    ids.forEach(id => { roles[id] = id === imp ? \"impostor\" : \"crew\"; });\n    const state = { players, roles, status: \"playing\", log: [] };\n    let botTimer = null;\n\n    function log(t) {\n        state.log.unshift(t);\n        if (state.log.length > 8) state.log.pop();\n    }\n    function aliveList() {\n        return Object.entries(state.players).filter(([, p]) => p.alive !== false);\n    }\n    function crewAlive() {\n        return aliveList().filter(([id]) => state.roles[id] === \"crew\");\n    }\n    function impAlive() {\n        return aliveList().filter(([id]) => state.roles[id] === \"impostor\");\n    }\n    function checkWin() {\n        if (impAlive().length === 0) {\n            state.status = \"ended\";\n            state.winnerText = \"M\u00fcrettebat kazand\u0131!\";\n            return true;\n        }\n        if (crewAlive().length <= impAlive().length) {\n            state.status = \"ended\";\n            state.winnerText = \"\u0130mpostor kazand\u0131!\";\n            return true;\n        }\n        const allTasks = crewAlive().every(([id]) => (state.players[id].tasks || 0) >= 3);\n        if (allTasks && crewAlive().length) {\n            state.status = \"ended\";\n            state.winnerText = \"M\u00fcrettebat g\u00f6revleri bitirdi!\";\n            return true;\n        }\n        return false;\n    }\n    function botTick() {\n        if (state.status !== \"playing\") return;\n        \/\/ bot crew g\u00f6rev\n        Object.entries(state.players).forEach(([id, p]) => {\n            if (!p.bot || p.alive === false) return;\n            if (state.roles[id] === \"crew\" && (p.tasks || 0) < 3 && Math.random() < 0.35) {\n                p.tasks = (p.tasks || 0) + 1;\n                log(p.name + \" g\u00f6rev yapt\u0131 (\" + p.tasks + \"\/3)\");\n            }\n        });\n        \/\/ impostor bot kill\n        const imps = impAlive().filter(([id, p]) => p.bot);\n        if (imps.length && Math.random() < 0.25) {\n            const victims = crewAlive();\n            if (victims.length) {\n                const [vid, vp] = victims[Math.floor(Math.random() * victims.length)];\n                state.players[vid].alive = false;\n                log(\"\ud83d\udc80 \" + vp.name + \" \u00f6ld\u00fcr\u00fcld\u00fc!\");\n            }\n        }\n        if (checkWin()) { render(); return; }\n        render();\n        botTimer = setTimeout(botTick, 2200);\n    }\n    function render() {\n        if (state.status === \"ended\") {\n            if (botTimer) clearTimeout(botTimer);\n            area.innerHTML = `<button class=\"gameBackBtn\" id=\"gameBackBtn\">\u2190 Geri<\/button>\n                <div class=\"gameStatus\">${escapeHtml(state.winnerText || \"Bitti\")}<\/div>\n                <button class=\"bigBtn\" id=\"amongAgain\">Tekrar (botlarla)<\/button>`;\n            gameBack(area);\n            document.getElementById(\"amongAgain\").onclick = () => startAmongWithBots(total);\n            grantXp(currentUser.uid, 8, \"among\").catch(() => {});\n            return;\n        }\n        if (state.status === \"meeting\") {\n            const alive = aliveList();\n            area.innerHTML = `\n                <button class=\"gameBackBtn\" id=\"gameBackBtn\">\u2190 Geri<\/button>\n                <div class=\"gameStatus\">\ud83d\udea8 Toplant\u0131 \u2014 kimi atal\u0131m?<\/div>\n                <div id=\"abVotes\" style=\"margin:10px 0;\"><\/div>\n                <button class=\"liveBtn gray\" id=\"abSkip\">Skip<\/button>\n                <div style=\"margin-top:10px;font-size:12px;color:#949ba4;\">${state.log.map(x => escapeHtml(x)).join(\"<br>\")}<\/div>`;\n            gameBack(area);\n            const box = document.getElementById(\"abVotes\");\n            alive.forEach(([id, p]) => {\n                const b = document.createElement(\"button\");\n                b.className = \"liveBtn\";\n                b.style.cssText = \"display:block;width:100%;margin:4px 0;\";\n                b.textContent = p.name + (p.bot ? \" (bot)\" : \"\");\n                b.onclick = () => resolveLocalVote(id);\n                box.appendChild(b);\n            });\n            document.getElementById(\"abSkip\").onclick = () => {\n                log(\"Oylama skip\");\n                state.status = \"playing\";\n                render();\n                botTimer = setTimeout(botTick, 1500);\n            };\n            return;\n        }\n        const me = state.players[myId];\n        const role = state.roles[myId];\n        const alive = aliveList();\n        area.innerHTML = `\n            <button class=\"gameBackBtn\" id=\"gameBackBtn\">\u2190 Geri<\/button>\n            <div class=\"gameStatus\">\ud83d\ude80 Crew Panic (bot) \u00b7 <b>${role === \"impostor\" ? \"\u0130MPOSTOR\" : \"M\u00fcrettebat\"}<\/b><\/div>\n            <div style=\"color:#b5bac1;font-size:13px;margin:8px 0;\">Canl\u0131: ${alive.map(([, p]) => escapeHtml(p.name) + (p.bot ? \"\ud83e\udd16\" : \"\")).join(\", \")}<\/div>\n            <div class=\"gameStatus\">G\u00f6revlerin: ${me.tasks || 0}\/3 \u00b7 ${me.alive === false ? \"\u00d6LD\u00dcN\" : \"Hayattas\u0131n\"}<\/div>\n            ${me.alive !== false ? `\n                <button class=\"bigBtn\" id=\"abTask\">G\u00f6rev yap (+1)<\/button>\n                <button class=\"liveBtn\" id=\"abMeet\" style=\"margin-top:8px;width:100%;\">\ud83d\udea8 Toplant\u0131<\/button>\n                ${role === \"impostor\" ? `<button class=\"liveBtn red\" id=\"abKill\" style=\"margin-top:8px;width:100%;\">Kill (crew)<\/button>` : \"\"}\n            ` : `<div class=\"liveNote\">\u00d6ld\u00fcn \u2014 botlar devam ediyor \/ toplant\u0131 bekle<\/div>\n                <button class=\"liveBtn\" id=\"abMeet\" style=\"margin-top:8px;width:100%;\">\ud83d\udea8 Toplant\u0131 izle<\/button>`}\n            <div style=\"margin-top:12px;font-size:12px;color:#949ba4;max-height:100px;overflow:auto;\">${state.log.map(x => escapeHtml(x)).join(\"<br>\")}<\/div>`;\n        gameBack(area);\n        document.getElementById(\"abTask\")?.addEventListener(\"click\", () => {\n            if ((me.tasks || 0) >= 3) return alert(\"G\u00f6revler bitti\");\n            me.tasks = (me.tasks || 0) + 1;\n            log(\"Sen g\u00f6rev yapt\u0131n (\" + me.tasks + \"\/3)\");\n            if (checkWin()) { render(); return; }\n            render();\n        });\n        document.getElementById(\"abMeet\")?.addEventListener(\"click\", () => {\n            state.status = \"meeting\";\n            if (botTimer) clearTimeout(botTimer);\n            log(\"Toplant\u0131 \u00e7a\u011fr\u0131ld\u0131\");\n            render();\n        });\n        document.getElementById(\"abKill\")?.addEventListener(\"click\", () => {\n            const victims = crewAlive().filter(([id]) => id !== myId);\n            if (!victims.length) return;\n            const [vid, vp] = victims[Math.floor(Math.random() * victims.length)];\n            state.players[vid].alive = false;\n            log(\"Sen \" + vp.name + \" \u00f6ld\u00fcrd\u00fcn\");\n            if (checkWin()) { render(); return; }\n            render();\n        });\n    }\n    function resolveLocalVote(targetId) {\n        \/\/ botlar rastgele oy (\u00e7o\u011fu impostora veya rastgele)\n        const alive = aliveList();\n        const counts = {};\n        counts[targetId] = 1;\n        alive.forEach(([id, p]) => {\n            if (!p.bot) return;\n            const pick = alive[Math.floor(Math.random() * alive.length)][0];\n            counts[pick] = (counts[pick] || 0) + 1;\n        });\n        let best = null, bestN = 0;\n        Object.entries(counts).forEach(([t, n]) => { if (n > bestN) { best = t; bestN = n; } });\n        if (best && state.players[best]) {\n            state.players[best].alive = false;\n            log(state.players[best].name + \" at\u0131ld\u0131 (\" + bestN + \" oy)\");\n        }\n        if (checkWin()) { render(); return; }\n        state.status = \"playing\";\n        render();\n        botTimer = setTimeout(botTick, 1500);\n    }\n    log(\"Oyun ba\u015flad\u0131 \u00b7 \" + total + \" oyuncu (bot dahil)\");\n    render();\n    botTimer = setTimeout(botTick, 2000);\n}\n\nfunction watchAmong(code, isHost) {\n    const area = document.getElementById(\"activeGameArea\");\n    if (currentGameUnsub) { currentGameUnsub(); currentGameUnsub = null; }\n    currentGameUnsub = onValue(ref(database, \"amongRooms\/\" + code), snap => {\n        if (!snap.exists() || !area) return;\n        const d = snap.val();\n        const players = d.players || {};\n        const list = Object.entries(players);\n        if (d.status === \"playing\") {\n            renderAmongPlay(code, d, isHost);\n            return;\n        }\n        if (d.status === \"meeting\") {\n            renderAmongMeeting(code, d);\n            return;\n        }\n        if (d.status === \"ended\") {\n            area.innerHTML = `<button class=\"gameBackBtn\" id=\"gameBackBtn\">\u2190 Geri<\/button>\n                <div class=\"gameStatus\">Bitti: ${escapeHtml(d.winnerText || \"?\")}<\/div>`;\n            gameBack(area);\n            return;\n        }\n        area.innerHTML = `\n            <button class=\"gameBackBtn\" id=\"gameBackBtn\">\u2190 Geri<\/button>\n            <div class=\"gameStatus\">Lobby <b>${code}<\/b> \u00b7 ${list.length}\/8<\/div>\n            <div style=\"margin:8px 0;\">${list.map(([, p]) => \"\u2022 \" + escapeHtml(p.name)).join(\"<br>\")}<\/div>\n            ${isHost ? `<button class=\"bigBtn\" id=\"amongFillBots\">Bot ekle (4'e tamamla)<\/button>\n            <button class=\"bigBtn\" id=\"amongStart\" style=\"margin-top:8px;\">Ba\u015flat<\/button>` : `<div class=\"liveNote\">Host bekleniyor...<\/div>`}`;\n        gameBack(area);\n        document.getElementById(\"amongFillBots\")?.addEventListener(\"click\", async () => {\n            const cur = { ...(d.players || {}) };\n            let i = 0;\n            while (Object.keys(cur).length < 4 && i < 8) {\n                const bid = \"bot_\" + Date.now() + \"_\" + i;\n                cur[bid] = { name: AMONG_BOT_NAMES[i % AMONG_BOT_NAMES.length], alive: true, tasks: 0, bot: true };\n                i++;\n            }\n            await update(ref(database, \"amongRooms\/\" + code), { players: cur });\n        });\n        document.getElementById(\"amongStart\")?.addEventListener(\"click\", async () => {\n            let cur = { ...(d.players || {}) };\n            \/\/ otomatik bot doldur en az 4\n            let i = 0;\n            while (Object.keys(cur).length < 4 && i < 8) {\n                const bid = \"bot_s_\" + i;\n                cur[bid] = { name: AMONG_BOT_NAMES[i % AMONG_BOT_NAMES.length], alive: true, tasks: 0, bot: true };\n                i++;\n            }\n            const ids = Object.keys(cur);\n            const imp = ids[Math.floor(Math.random() * ids.length)];\n            const roles = {};\n            ids.forEach(id => { roles[id] = id === imp ? \"impostor\" : \"crew\"; });\n            await update(ref(database, \"amongRooms\/\" + code), { status: \"playing\", players: cur, roles, meeting: null });\n            \/\/ host bot AI d\u00f6ng\u00fcs\u00fc\n            if (isHost) runOnlineAmongBots(code);\n        });\n    });\n}\n\nlet amongBotInterval = null;\nfunction runOnlineAmongBots(code) {\n    if (amongBotInterval) clearInterval(amongBotInterval);\n    amongBotInterval = setInterval(async () => {\n        try {\n            const s = await get(ref(database, \"amongRooms\/\" + code));\n            if (!s.exists()) { clearInterval(amongBotInterval); return; }\n            const d = s.val();\n            if (d.status !== \"playing\" || d.host !== currentUser.uid) return;\n            const updates = {};\n            Object.entries(d.players || {}).forEach(([id, p]) => {\n                if (!p.bot || p.alive === false) return;\n                if (d.roles[id] === \"crew\" && (p.tasks || 0) < 3 && Math.random() < 0.4) {\n                    updates[\"players\/\" + id + \"\/tasks\"] = (p.tasks || 0) + 1;\n                }\n            });\n            \/\/ impostor bot kill\n            const imps = Object.entries(d.roles || {}).filter(([id, r]) => r === \"impostor\" && d.players[id]?.bot && d.players[id]?.alive !== false);\n            if (imps.length && Math.random() < 0.2) {\n                const victims = Object.entries(d.players || {}).filter(([id, p]) => p.alive !== false && d.roles[id] === \"crew\");\n                if (victims.length) {\n                    const [vid] = victims[Math.floor(Math.random() * victims.length)];\n                    updates[\"players\/\" + vid + \"\/alive\"] = false;\n                }\n            }\n            if (Object.keys(updates).length) await update(ref(database, \"amongRooms\/\" + code), updates);\n            \/\/ win check\n            const s2 = await get(ref(database, \"amongRooms\/\" + code));\n            const dd = s2.val();\n            const alive = Object.entries(dd.players || {}).filter(([, p]) => p.alive !== false);\n            const crewA = alive.filter(([id]) => dd.roles[id] === \"crew\");\n            const impA = alive.filter(([id]) => dd.roles[id] === \"impostor\");\n            if (impA.length === 0) await update(ref(database, \"amongRooms\/\" + code), { status: \"ended\", winnerText: \"M\u00fcrettebat kazand\u0131\" });\n            else if (crewA.length <= impA.length) await update(ref(database, \"amongRooms\/\" + code), { status: \"ended\", winnerText: \"\u0130mpostor kazand\u0131\" });\n            else if (crewA.every(([id]) => (dd.players[id].tasks || 0) >= 3))\n                await update(ref(database, \"amongRooms\/\" + code), { status: \"ended\", winnerText: \"G\u00f6revler bitti \u2014 m\u00fcrettebat\" });\n        } catch (_) {}\n    }, 2500);\n}\n\nfunction renderAmongPlay(code, d, isHost) {\n    const area = document.getElementById(\"activeGameArea\");\n    if (!area) return;\n    const me = playersMe(d);\n    const role = (d.roles && d.roles[currentUser.uid]) || \"crew\";\n    const alive = Object.entries(d.players || {}).filter(([, p]) => p.alive !== false);\n    area.innerHTML = `\n        <button class=\"gameBackBtn\" id=\"gameBackBtn\">\u2190 Geri<\/button>\n        <div class=\"gameStatus\">\ud83d\ude80 Oyun \u00b7 Rol\u00fcn: <b>${role === \"impostor\" ? \"\u0130MPOSTOR\" : \"M\u00fcrettebat\"}<\/b><\/div>\n        <div style=\"color:#b5bac1;font-size:13px;margin:8px 0;\">Canl\u0131: ${alive.map(([, p]) => escapeHtml(p.name)).join(\", \")}<\/div>\n        <div class=\"gameStatus\">G\u00f6revlerin: ${me ? (me.tasks || 0) : 0}\/3<\/div>\n        <button class=\"bigBtn\" id=\"amongTask\">G\u00f6rev yap (+1)<\/button>\n        <button class=\"liveBtn\" id=\"amongMeet\" style=\"margin-top:8px;width:100%;\">\ud83d\udea8 Toplant\u0131<\/button>\n        ${role === \"impostor\" ? `<button class=\"liveBtn red\" id=\"amongKill\" style=\"margin-top:8px;width:100%;\">Kill (rastgele m\u00fcrettebat)<\/button>` : \"\"}\n        ${isHost ? `<button class=\"liveBtn gray\" id=\"amongEnd\" style=\"margin-top:8px;width:100%;\">Oyunu bitir<\/button>` : \"\"}`;\n    gameBack(area);\n    document.getElementById(\"amongTask\")?.addEventListener(\"click\", async () => {\n        const t = (me && me.tasks) || 0;\n        if (t >= 3) return alert(\"G\u00f6revler bitti\");\n        await update(ref(database, \"amongRooms\/\" + code + \"\/players\/\" + currentUser.uid), { tasks: t + 1 });\n        \/\/ t\u00fcm crew 3 g\u00f6rev yapt\u0131ysa crew kazan\u0131r\n        const snap = await get(ref(database, \"amongRooms\/\" + code));\n        const dd = snap.val();\n        const crewOk = Object.entries(dd.roles || {}).filter(([, r]) => r === \"crew\").every(([uid]) => (dd.players[uid]?.tasks || 0) >= 3);\n        if (crewOk) await update(ref(database, \"amongRooms\/\" + code), { status: \"ended\", winnerText: \"M\u00fcrettebat kazand\u0131 (g\u00f6revler)\" });\n    });\n    document.getElementById(\"amongMeet\")?.addEventListener(\"click\", async () => {\n        await update(ref(database, \"amongRooms\/\" + code), { status: \"meeting\", votes: {}, meetingBy: currentUser.uid });\n    });\n    document.getElementById(\"amongKill\")?.addEventListener(\"click\", async () => {\n        const victims = Object.entries(d.players || {}).filter(([uid, p]) => p.alive !== false && d.roles[uid] === \"crew\");\n        if (!victims.length) return;\n        const [vid] = victims[Math.floor(Math.random() * victims.length)];\n        await update(ref(database, \"amongRooms\/\" + code + \"\/players\/\" + vid), { alive: false });\n        const left = victims.length - 1;\n        if (left <= 0) await update(ref(database, \"amongRooms\/\" + code), { status: \"ended\", winnerText: \"\u0130mpostor kazand\u0131\" });\n    });\n    document.getElementById(\"amongEnd\")?.addEventListener(\"click\", async () => {\n        await update(ref(database, \"amongRooms\/\" + code), { status: \"ended\", winnerText: \"Host kapatt\u0131\" });\n    });\n}\nfunction playersMe(d) {\n    return d.players && d.players[currentUser.uid];\n}\nfunction renderAmongMeeting(code, d) {\n    const area = document.getElementById(\"activeGameArea\");\n    if (!area) return;\n    const alive = Object.entries(d.players || {}).filter(([, p]) => p.alive !== false);\n    const votes = d.votes || {};\n    area.innerHTML = `\n        <button class=\"gameBackBtn\" id=\"gameBackBtn\">\u2190 Geri<\/button>\n        <div class=\"gameStatus\">\ud83d\udea8 Toplant\u0131 \u2014 oy ver<\/div>\n        <div id=\"amongVoteList\" style=\"margin:12px 0;\"><\/div>\n        <button class=\"liveBtn gray\" id=\"amongSkip\">Skip<\/button>\n        <button class=\"bigBtn\" id=\"amongResolve\" style=\"margin-top:8px;\">Oylar\u0131 say (host)<\/button>`;\n    gameBack(area);\n    const box = document.getElementById(\"amongVoteList\");\n    alive.forEach(([uid, p]) => {\n        const b = document.createElement(\"button\");\n        b.className = \"liveBtn\";\n        b.style.cssText = \"display:block;width:100%;margin:4px 0;\";\n        b.textContent = p.name + (votes[uid] ? \" \u00b7 \" + Object.keys(votes[uid] || {}).length + \" oy\" : \"\");\n        b.onclick = async () => {\n            await set(ref(database, \"amongRooms\/\" + code + \"\/votes\/\" + uid + \"\/\" + currentUser.uid), true);\n        };\n        box.appendChild(b);\n    });\n    document.getElementById(\"amongSkip\").onclick = async () => {\n        await set(ref(database, \"amongRooms\/\" + code + \"\/votes\/skip\/\" + currentUser.uid), true);\n    };\n    document.getElementById(\"amongResolve\").onclick = async () => {\n        if (d.host !== currentUser.uid) return alert(\"Sadece host\");\n        const counts = {};\n        Object.entries(votes).forEach(([target, voters]) => {\n            counts[target] = Object.keys(voters || {}).length;\n        });\n        let best = null, bestN = 0;\n        Object.entries(counts).forEach(([t, n]) => { if (n > bestN) { best = t; bestN = n; } });\n        if (!best || best === \"skip\" || bestN < 1) {\n            await update(ref(database, \"amongRooms\/\" + code), { status: \"playing\", votes: null });\n            return;\n        }\n        await update(ref(database, \"amongRooms\/\" + code + \"\/players\/\" + best), { alive: false });\n        const role = d.roles[best];\n        if (role === \"impostor\") {\n            await update(ref(database, \"amongRooms\/\" + code), { status: \"ended\", winnerText: \"M\u00fcrettebat kazand\u0131 (impostor at\u0131ld\u0131)\" });\n        } else {\n            await update(ref(database, \"amongRooms\/\" + code), { status: \"playing\", votes: null });\n        }\n    };\n}\n\n\/* ---------- Turnuva ---------- *\/\ndocument.getElementById(\"startTournamentBtn\").onclick = () => openTournamentUI();\n\nfunction openTournamentUI() {\n    const area = gameArea();\n    if (!area) return;\n    const now = new Date();\n    const pad = n => String(n).padStart(2, \"0\");\n    const todayLocal = now.getFullYear() + \"-\" + pad(now.getMonth() + 1) + \"-\" + pad(now.getDate()) + \"T23:59\";\n    area.innerHTML = `\n        <button class=\"gameBackBtn\" id=\"gameBackBtn\">\u2190 Geri<\/button>\n        <div class=\"gameStatus\">\ud83c\udfc6 Turnuva \/ G\u00fcnl\u00fck yar\u0131\u015f<\/div>\n        <p style=\"color:#b5bac1;font-size:13px;\">Tarih bo\u015fsa <b>bug\u00fcn 23:59<\/b>. G\u00fcnl\u00fck skor yar\u0131\u015f\u0131nda g\u00fcn sonunda en y\u00fcksek skor \u00f6d\u00fcl\u00fc al\u0131r (\u00f6d\u00fcl kurandan).<\/p>\n        <input id=\"tName\" placeholder=\"Turnuva ad\u0131\" style=\"width:100%;padding:12px;border:none;border-radius:8px;background:#1e1f22;color:#fff;margin:6px 0;\">\n        <select id=\"tGame\" style=\"width:100%;padding:12px;border:none;border-radius:8px;background:#1e1f22;color:#fff;margin:6px 0;\">\n            <option value=\"xox\">XOX<\/option>\n            <option value=\"rps\">Ta\u015f-Ka\u011f\u0131t-Makas<\/option>\n            <option value=\"uno\">UNO<\/option>\n            <option value=\"among\">Crew Panic<\/option>\n            <option value=\"carrace\">Araba Yar\u0131\u015f\u0131 (skor)<\/option>\n            <option value=\"clicker\">10sn T\u0131klama (skor)<\/option>\n            <option value=\"reaction\">Reaksiyon (skor)<\/option>\n        <\/select>\n        <label style=\"font-size:12px;color:#949ba4;\">Biti\u015f (bo\u015f = bug\u00fcn)<\/label>\n        <input id=\"tDate\" type=\"datetime-local\" value=\"${todayLocal}\" style=\"width:100%;padding:12px;border:none;border-radius:8px;background:#1e1f22;color:#fff;margin:6px 0;\">\n        <label style=\"display:flex;align-items:center;gap:8px;font-size:13px;color:#dbdee1;margin:8px 0;\">\n            <input type=\"checkbox\" id=\"tDailyScore\"> G\u00fcnl\u00fck skor yar\u0131\u015f\u0131 (g\u00fcn sonunda en y\u00fcksek skor kazan\u0131r)\n        <\/label>\n        <input id=\"tPrize\" type=\"number\" min=\"10\" max=\"5000\" value=\"50\" placeholder=\"\u00d6d\u00fcl VC\" style=\"width:100%;padding:12px;border:none;border-radius:8px;background:#1e1f22;color:#fff;margin:6px 0;\">\n        <button class=\"bigBtn\" id=\"tCreate\">Turnuva olu\u015ftur (\u00f6d\u00fcl\u00fc kilitle)<\/button>\n        <div class=\"sectionTitle\" style=\"margin-top:16px;\">Aktif turnuvalar<\/div>\n        <div id=\"tList\"><div class=\"liveNote\">Y\u00fckleniyor...<\/div><\/div>`;\n    gameBack(area);\n    document.getElementById(\"tCreate\").onclick = async () => {\n        const name = (document.getElementById(\"tName\").value || \"\").trim() || \"Turnuva\";\n        const game = document.getElementById(\"tGame\").value;\n        let when = (document.getElementById(\"tDate\").value || \"\").trim();\n        if (!when) when = todayLocal;\n        const dailyScore = !!document.getElementById(\"tDailyScore\").checked;\n        const prizeN = Math.min(5000, Math.max(10, parseInt(document.getElementById(\"tPrize\").value, 10) || 50));\n        const coins = currentProfile.coins || 0;\n        if (coins < prizeN) return alert(\"Yetersiz VC (gerekli \" + prizeN + \")\");\n        try {\n            await addCoins(currentUser.uid, -prizeN);\n            currentProfile.coins = (currentProfile.coins || 0) - prizeN;\n            const id = push(ref(database, \"tournaments\")).key;\n            await set(ref(database, \"tournaments\/\" + id), {\n                name, game, when, prize: prizeN, dailyScore,\n                dayKey: (when || \"\").slice(0, 10),\n                host: currentUser.uid, hostName: currentProfile.displayName,\n                players: { [currentUser.uid]: { name: currentProfile.displayName, score: 0 } },\n                status: \"open\", createdAt: Date.now(), winner: null\n            });\n            alert(\"Turnuva a\u00e7\u0131ld\u0131. \u00d6d\u00fcl kilitlendi: \" + prizeN + \" VC\\nBiti\u015f: \" + when + (dailyScore ? \"\\n(G\u00fcnl\u00fck skor modu)\" : \"\"));\n            openTournamentUI();\n        } catch (e) { alert(e.message || e); }\n    };\n    loadTournaments();\n    tryResolveDailyTournaments();\n}\n\nasync function loadTournaments() {\n    const box = document.getElementById(\"tList\");\n    if (!box) return;\n    try {\n        const snap = await get(query(ref(database, \"tournaments\"), limitToLast(20)));\n        if (!snap.exists()) { box.innerHTML = `<div class=\"liveNote\">Turnuva yok<\/div>`; return; }\n        const items = Object.entries(snap.val()).sort((a, b) => (b[1].createdAt || 0) - (a[1].createdAt || 0));\n        box.innerHTML = \"\";\n        items.forEach(([id, t]) => {\n            const div = document.createElement(\"div\");\n            div.className = \"gameCard\";\n            div.style.cursor = \"default\";\n            const n = t.players ? Object.keys(t.players).length : 0;\n            div.innerHTML = `<div class=\"gameIcon\">\ud83c\udfc6<\/div><div class=\"gameInfo\">\n                <div class=\"gameName\">${escapeHtml(t.name || \"Turnuva\")}${t.dailyScore ? \" \u00b7 skor\" : \"\"}<\/div>\n                <div class=\"gameDesc\">${escapeHtml(t.game)} \u00b7 ${t.prize || 0} VC \u00b7 ${n} ki\u015fi \u00b7 ${t.status}\n                ${t.when ? \" \u00b7 biti\u015f \" + escapeHtml(String(t.when)) : \" \u00b7 bug\u00fcn\"}<\/div>\n                <div style=\"margin-top:8px;display:flex;gap:6px;flex-wrap:wrap;\">\n                    ${t.status === \"open\" ? `<button class=\"liveBtn green tJoin\" data-id=\"${id}\">Kat\u0131l<\/button>` : \"\"}\n                    ${t.host === currentUser.uid && t.status === \"open\" && !t.dailyScore ? `<button class=\"liveBtn tWin\" data-id=\"${id}\">Kazanan se\u00e7<\/button>` : \"\"}\n                    ${t.host === currentUser.uid && t.status === \"open\" && t.dailyScore ? `<button class=\"liveBtn tResolve\" data-id=\"${id}\">Skora g\u00f6re bitir<\/button>` : \"\"}\n                <\/div><\/div>`;\n            box.appendChild(div);\n        });\n        box.querySelectorAll(\".tJoin\").forEach(b => {\n            b.onclick = async () => {\n                await update(ref(database, \"tournaments\/\" + b.dataset.id + \"\/players\/\" + currentUser.uid), {\n                    name: currentProfile.displayName, score: 0\n                });\n                alert(\"Kat\u0131ld\u0131n\");\n                loadTournaments();\n            };\n        });\n        box.querySelectorAll(\".tWin\").forEach(b => {\n            b.onclick = async () => {\n                const id = b.dataset.id;\n                const s = await get(ref(database, \"tournaments\/\" + id));\n                if (!s.exists()) return;\n                const t = s.val();\n                const names = Object.entries(t.players || {});\n                if (!names.length) return alert(\"Oyuncu yok\");\n                const pick = prompt(\"Kazanan kullan\u0131c\u0131 ad\u0131 (@ olmadan):\\n\" + names.map(([, p]) => p.name).join(\", \"));\n                if (!pick) return;\n                const found = names.find(([, p]) => (p.name || \"\").toLowerCase() === pick.toLowerCase());\n                let winUid = found ? found[0] : await resolveUid(pick);\n                if (!winUid) return alert(\"Bulunamad\u0131\");\n                const prize = t.prize || 0;\n                await addCoins(winUid, prize);\n                await update(ref(database, \"tournaments\/\" + id), { status: \"done\", winner: winUid, winnerName: pick });\n                alert(\"\u00d6d\u00fcl verildi: \" + prize + \" VC \u2192 \" + pick);\n                loadTournaments();\n            };\n        });\n        box.querySelectorAll(\".tResolve\").forEach(b => {\n            b.onclick = () => resolveTournamentByScore(b.dataset.id).then(() => loadTournaments());\n        });\n    } catch (e) {\n        box.innerHTML = `<div class=\"liveNote\" style=\"color:#ed4245;\">${escapeHtml(e.message || String(e))}<\/div>`;\n    }\n}\n\nasync function resolveTournamentByScore(id) {\n    const s = await get(ref(database, \"tournaments\/\" + id));\n    if (!s.exists()) return;\n    const t = s.val();\n    if (t.status !== \"open\") return;\n    \/\/ scores path veya players.score\n    let bestUid = null, bestScore = -1, bestName = \"?\";\n    const scoreGame = t.game === \"carrace\" ? \"carrace\" : t.game === \"clicker\" ? \"clicker\" : t.game === \"reaction\" ? \"reaction\" : null;\n    if (scoreGame) {\n        try {\n            const sc = await get(ref(database, \"scores\/\" + scoreGame));\n            if (sc.exists()) {\n                Object.entries(sc.val()).forEach(([uid, row]) => {\n                    if (!(t.players && t.players[uid])) return;\n                    const v = Number(row.value) || 0;\n                    const better = scoreGame === \"reaction\" ? (bestScore < 0 || v < bestScore) : v > bestScore;\n                    \/\/ reaction: lower is better\n                    if (scoreGame === \"reaction\") {\n                        if (bestScore < 0 || v < bestScore) { bestScore = v; bestUid = uid; bestName = row.name || \"?\"; }\n                    } else if (v > bestScore) {\n                        bestScore = v; bestUid = uid; bestName = row.name || \"?\";\n                    }\n                });\n            }\n        } catch (_) {}\n    }\n    if (!bestUid) {\n        Object.entries(t.players || {}).forEach(([uid, p]) => {\n            const v = Number(p.score) || 0;\n            if (v > bestScore) { bestScore = v; bestUid = uid; bestName = p.name || \"?\"; }\n        });\n    }\n    if (!bestUid) { alert(\"Skor bulunamad\u0131\"); return; }\n    await addCoins(bestUid, t.prize || 0);\n    await update(ref(database, \"tournaments\/\" + id), {\n        status: \"done\", winner: bestUid, winnerName: bestName, winScore: bestScore\n    });\n    alert(\"G\u00fcn sonu: \" + bestName + \" kazand\u0131 \u00b7 skor \" + bestScore + \" \u00b7 +\" + (t.prize || 0) + \" VC\");\n}\n\nasync function tryResolveDailyTournaments() {\n    try {\n        const snap = await get(query(ref(database, \"tournaments\"), limitToLast(30)));\n        if (!snap.exists()) return;\n        const now = Date.now();\n        for (const [id, t] of Object.entries(snap.val())) {\n            if (t.status !== \"open\" || !t.dailyScore) continue;\n            if (t.host !== currentUser?.uid) continue;\n            let end = now;\n            if (t.when) {\n                const ts = Date.parse(t.when);\n                if (!isNaN(ts)) end = ts;\n            }\n            if (now >= end) await resolveTournamentByScore(id);\n        }\n    } catch (_) {}\n}\n\n\/* ---------- 2D Araba Yar\u0131\u015f\u0131 (d\u00fczeltildi: tek d\u00f6ng\u00fc) ---------- *\/\ndocument.getElementById(\"startCarRaceBtn\").onclick = () => {\n    try {\n        const area = gameArea();\n        area.scrollIntoView({ behavior: \"smooth\", block: \"start\" });\n        area.innerHTML = `<button class=\"gameBackBtn\" id=\"gameBackBtn\">\u2190 Geri<\/button>\n            <div class=\"gameStatus\">\ud83c\udfce\ufe0f 2D Araba Yar\u0131\u015f\u0131<\/div>\n            <div style=\"text-align:center;color:#949ba4;font-size:13px;margin-bottom:8px;\">\u25c0 \u25b6 \u00b7 A\/D \u00b7 buton \u00b7 dokun<\/div>\n            <div style=\"display:flex;justify-content:center;margin:8px 0;\">\n                <canvas id=\"carCanvas\" width=\"320\" height=\"480\" style=\"width:min(100%,320px);max-width:320px;background:#1a1a2e;border-radius:12px;touch-action:none;display:block;\"><\/canvas>\n            <\/div>\n            <div class=\"gameStatus\" id=\"carHud\">Y\u00fckleniyor...<\/div>\n            <div style=\"display:flex;gap:8px;justify-content:center;flex-wrap:wrap;margin-top:8px;\">\n                <button type=\"button\" id=\"carLeft\" style=\"padding:14px 20px;border:none;border-radius:8px;background:#404249;color:#fff;font-size:18px;\">\u25c0<\/button>\n                <button type=\"button\" id=\"carStartBtn\" style=\"padding:14px 24px;border:none;border-radius:8px;background:#23a559;color:#fff;font-weight:bold;font-size:16px;\">\u25b6 Ba\u015fla<\/button>\n                <button type=\"button\" id=\"carRight\" style=\"padding:14px 20px;border:none;border-radius:8px;background:#404249;color:#fff;font-size:18px;\">\u25b6<\/button>\n            <\/div>`;\n\n        const canvas = document.getElementById(\"carCanvas\");\n        if (!canvas) throw new Error(\"Canvas yok\");\n        const ctx = canvas.getContext(\"2d\");\n        const W = 320, H = 480;\n        canvas.width = W;\n        canvas.height = H;\n        const lanes = 3;\n        const laneW = W \/ lanes;\n        let carLane = 1, score = 0, speed = 3, running = false, anim = null;\n        let roadY = 0, obstacles = [], best = 0, ended = false, lastTs = 0;\n\n        function hud(t) {\n            const el = document.getElementById(\"carHud\");\n            if (el) el.textContent = t;\n        }\n\n        if (currentUser) {\n            get(ref(database, \"scores\/carrace\/\" + currentUser.uid)).then(s => {\n                if (s.exists()) best = Number(s.val().value) || 0;\n                if (!running) hud(\"Haz\u0131r \u00b7 En iyi: \" + best);\n            }).catch(() => { hud(\"Haz\u0131r \u2014 Ba\u015fla\"); });\n        } else hud(\"Haz\u0131r \u2014 Ba\u015fla\");\n\n        function spawn() {\n            let lane = Math.floor(Math.random() * lanes);\n            if (obstacles.length < 3 && lane === carLane) lane = (carLane + 1 + Math.floor(Math.random() * 2)) % lanes;\n            obstacles.push({ lane, y: -80, color: [\"#ed4245\", \"#faa61a\", \"#5865f2\", \"#e17055\"][Math.floor(Math.random() * 4)] });\n        }\n\n        function drawCar(lane, y, color) {\n            const x = lane * laneW + laneW \/ 2;\n            ctx.fillStyle = color;\n            ctx.fillRect(x - 18, y - 26, 36, 48);\n            ctx.fillStyle = \"#dfe6e9\";\n            ctx.fillRect(x - 10, y - 14, 20, 12);\n            ctx.fillStyle = \"#111\";\n            ctx.fillRect(x - 20, y - 16, 6, 10);\n            ctx.fillRect(x + 14, y - 16, 6, 10);\n            ctx.fillRect(x - 20, y + 8, 6, 10);\n            ctx.fillRect(x + 14, y + 8, 6, 10);\n        }\n\n        function drawScene() {\n            ctx.fillStyle = \"#2d3436\";\n            ctx.fillRect(0, 0, W, H);\n            ctx.strokeStyle = \"#ffeaa7\";\n            ctx.lineWidth = 3;\n            ctx.setLineDash([16, 16]);\n            for (let i = 1; i < lanes; i++) {\n                ctx.beginPath();\n                ctx.moveTo(i * laneW, (roadY % 32) - 32);\n                ctx.lineTo(i * laneW, H + 32);\n                ctx.stroke();\n            }\n            ctx.setLineDash([]);\n            ctx.fillStyle = \"#636e72\";\n            ctx.fillRect(0, 0, 8, H);\n            ctx.fillRect(W - 8, 0, 8, H);\n            obstacles.forEach(o => drawCar(o.lane, o.y, o.color));\n            drawCar(carLane, H - 70, \"#00cec9\");\n        }\n\n        function stopLoop() {\n            if (anim) { cancelAnimationFrame(anim); anim = null; }\n        }\n\n        function loop(ts) {\n            if (!running) return;\n            if (!lastTs) lastTs = ts;\n            const dt = Math.min(32, ts - lastTs) \/ 16.67;\n            lastTs = ts;\n\n            roadY += speed * dt;\n            for (let i = obstacles.length - 1; i >= 0; i--) {\n                const o = obstacles[i];\n                o.y += speed * dt;\n                if (o.lane === carLane && Math.abs(o.y - (H - 70)) < 44) {\n                    running = false;\n                    ended = true;\n                    stopLoop();\n                    endGame();\n                    return;\n                }\n                if (o.y > H + 90) obstacles.splice(i, 1);\n            }\n            score += dt;\n            if (Math.floor(score) % 55 === 0 && Math.floor(score - dt) % 55 !== 0) spawn();\n            if (Math.floor(score) % 200 === 0 && Math.floor(score - dt) % 200 !== 0) speed = Math.min(10, speed + 0.35);\n            hud(\"Skor: \" + Math.floor(score) + \" \u00b7 H\u0131z: \" + speed.toFixed(1) + \" \u00b7 En iyi: \" + best);\n            drawScene();\n            anim = requestAnimationFrame(loop);\n        }\n\n        async function endGame() {\n            drawScene();\n            ctx.fillStyle = \"rgba(0,0,0,0.65)\";\n            ctx.fillRect(0, 0, W, H);\n            ctx.fillStyle = \"#fff\";\n            ctx.font = \"bold 26px Arial\";\n            ctx.textAlign = \"center\";\n            ctx.fillText(\"\u00c7ARPI\u015eTIN!\", W \/ 2, H \/ 2 - 16);\n            ctx.font = \"16px Arial\";\n            ctx.fillText(\"Skor: \" + Math.floor(score), W \/ 2, H \/ 2 + 16);\n            const btn = document.getElementById(\"carStartBtn\");\n            if (btn) btn.textContent = \"\u25b6 Tekrar\";\n            try {\n                if (currentUser) {\n                    const sc = Math.floor(score);\n                    const better = await saveScore(\"carrace\", sc, \"desc\");\n                    if (sc > best) best = sc;\n                    hud(\"Skor: \" + sc + (better ? \" \u00b7 \ud83c\udfc6 Rekor!\" : \" \u00b7 En iyi: \" + best));\n                    if (sc >= 300) bumpStat(\"gamesWon\");\n                }\n            } catch (_) {}\n        }\n\n        function move(dir) {\n            if (!running) return;\n            carLane = Math.max(0, Math.min(lanes - 1, carLane + dir));\n            drawScene();\n        }\n\n        function startRace() {\n            stopLoop();\n            carLane = 1; score = 0; speed = 3; obstacles = []; roadY = 0;\n            running = true; ended = false; lastTs = 0;\n            const btn = document.getElementById(\"carStartBtn\");\n            if (btn) btn.textContent = \"Yeniden\";\n            hud(\"Skor: 0 \u00b7 En iyi: \" + best);\n            setTimeout(() => { if (running) spawn(); }, 900);\n            setTimeout(() => { if (running) spawn(); }, 1800);\n            anim = requestAnimationFrame(loop);\n        }\n\n        document.getElementById(\"carStartBtn\").onclick = (e) => { e.preventDefault(); e.stopPropagation(); startRace(); };\n        document.getElementById(\"carLeft\").onclick = (e) => { e.preventDefault(); move(-1); };\n        document.getElementById(\"carRight\").onclick = (e) => { e.preventDefault(); move(1); };\n\n        const onKey = (e) => {\n            const tag = (e.target && e.target.tagName) || \"\";\n            if (tag === \"INPUT\" || tag === \"TEXTAREA\" || e.target?.isContentEditable) return;\n            if (e.key === \"ArrowLeft\" || e.key === \"a\" || e.key === \"A\") { e.preventDefault(); move(-1); }\n            if (e.key === \"ArrowRight\" || e.key === \"d\" || e.key === \"D\") { e.preventDefault(); move(1); }\n            if ((e.key === \" \" || e.key === \"Enter\") && (!running || ended)) { e.preventDefault(); startRace(); }\n        };\n        window.addEventListener(\"keydown\", onKey);\n\n        canvas.addEventListener(\"pointerdown\", (e) => {\n            e.preventDefault();\n            const r = canvas.getBoundingClientRect();\n            const x = (e.clientX - r.left) \/ r.width * W;\n            if (!running) startRace();\n            else move(x < W \/ 2 ? -1 : 1);\n        });\n\n        drawScene();\n        ctx.fillStyle = \"rgba(0,0,0,0.5)\";\n        ctx.fillRect(0, 0, W, H);\n        ctx.fillStyle = \"#fff\";\n        ctx.font = \"bold 22px Arial\";\n        ctx.textAlign = \"center\";\n        ctx.fillText(\"BA\u015eLA'YA BAS\", W \/ 2, H \/ 2);\n\n        document.getElementById(\"gameBackBtn\").onclick = () => {\n            running = false;\n            stopLoop();\n            window.removeEventListener(\"keydown\", onKey);\n            area.classList.add(\"hidden\");\n            area.innerHTML = \"\";\n        };\n    } catch (err) {\n        console.error(err);\n        alert(\"Araba yar\u0131\u015f\u0131: \" + (err.message || err));\n    }\n};\n\n\/* =========================================================\n   PROF\u0130L SAYFASI\n========================================================= *\/\nconst STATUS_LABELS = { online: \"\ud83d\udfe2 \u00c7evrimi\u00e7i\", idle: \"\ud83c\udf19 Bo\u015fta\", dnd: \"\u26d4 Rahats\u0131z Etmeyin\", playing: \"\ud83c\udfae Oyun Oynuyor\", offline: \"\u26ab \u00c7evrimd\u0131\u015f\u0131\" };\n\nasync function viewProfile(uid) {\n    if (!uid || String(uid).startsWith(\"bot_\") || !currentUser) return;\n    hideExtraScreens(\"profile\");\n    hideMainAreas();\n    activeChatType = \"profile\";\n    showPageButton(uid === currentUser.uid ? \"myProfileButton\" : null);\n    profileScreen.classList.add(\"active\");\n    const body = document.getElementById(\"profilePageBody\");\n    body.innerHTML = `<div class=\"liveNote\">Y\u00fckleniyor...<\/div>`;\n    closeSidebar();\n\n    const isMe = uid === currentUser.uid;\n    const [uSnap, stSnap, adSnap, liveSnap, banSnap] = await Promise.all([\n        get(ref(database, \"users\/\" + uid)), get(ref(database, \"status\/\" + uid)),\n        get(ref(database, \"admins\/\" + uid)), get(ref(database, \"lives\/\" + uid)),\n        get(ref(database, \"banned\/\" + uid)).catch(() => null)\n    ]);\n    if (!uSnap.exists()) { body.innerHTML = `<div class=\"liveNote\">Kullan\u0131c\u0131 bulunamad\u0131.<\/div>`; return; }\n    const raw = uSnap.val();\n    \/\/ tema rengi\n    try {\n        const lvT = xpToLevel(raw.xp || 0);\n        body.style.background = raw.theme || levelThemeColor(lvT);\n    } catch (_) {}\n    const p = normalizeProfile(raw);\n    const stats = raw.stats || {};\n    const state = stSnap.val()?.state || \"offline\";\n    const level = xpToLevel(p.xp);\n    const into = p.xp % 50;\n    const iAmAdmin = await isCurrentUserAdmin();\n\n    body.innerHTML = `\n        <div class=\"profileHero\">\n            <div class=\"avatar large\" id=\"ppAvatar\"><\/div>\n            <div class=\"profileHeroText\">\n                <div class=\"profileHeroName\">${escapeHtml(p.displayName)} ${adSnap.exists() ? \"\ud83d\udc51\" : \"\"} ${p.xp >= 200 ? \"\u2b50\" : \"\"}<\/div>\n                <div class=\"profileHeroUser\">@${escapeHtml(p.username)} \u00b7 ${STATUS_LABELS[state] || STATUS_LABELS.offline}<\/div>\n                <div class=\"profileHeroAbout\">${escapeHtml(p.about)}<\/div>\n                <div style=\"margin-top:6px;font-size:13px;\">${computeBadges(p, adSnap.exists()).map(b => `<span title=\"${b.title}\">${b.icon}<\/span>`).join(\" \")} \u00b7 \ud83e\ude99 ${p.coins || 0}<\/div>\n            <\/div>\n        <\/div>\n        <div class=\"xpBarWrap\">\n            <div class=\"xpBarTop\"><span>Seviye ${level}<\/span><span>${p.xp} XP \u00b7 sonraki seviyeye ${50 - into} XP<\/span><\/div>\n            <div class=\"xpBar\"><div class=\"xpBarFill\" style=\"width:${(into \/ 50) * 100}%\"><\/div><\/div>\n        <\/div>\n        <div class=\"statGrid\">\n            <div class=\"statBox\"><div class=\"statNum\">${p.xp}<\/div><div class=\"statLabel\">Toplam XP<\/div><\/div>\n            <div class=\"statBox\"><div class=\"statNum\">${p.coins || 0}<\/div><div class=\"statLabel\">VegaCoin<\/div><\/div>\n            <div class=\"statBox\"><div class=\"statNum\">${stats.gamesWon || 0}<\/div><div class=\"statLabel\">Kazan\u0131lan oyun<\/div><\/div>\n            <div class=\"statBox\"><div class=\"statNum\">${new Date(p.createdAt).toLocaleDateString(\"tr-TR\")}<\/div><div class=\"statLabel\">Kat\u0131l\u0131m<\/div><\/div>\n        <\/div>\n        <div class=\"profileActions\" id=\"ppActions\"><\/div>\n        <div id=\"ppVideos\"><\/div>\n        <div id=\"ppGames\"><\/div>\n        <div id=\"ppFriends\"><\/div>`;\n    setAvatar(document.getElementById(\"ppAvatar\"), p);\n\n    const actions = document.getElementById(\"ppActions\");\n    function addBtn(label, cls, fn) {\n        const b = document.createElement(\"button\");\n        b.className = \"liveBtn \" + cls; b.textContent = label; b.onclick = fn;\n        actions.appendChild(b);\n    }\n    if (liveSnap.exists()) addBtn(\"\ud83d\udcfa Yay\u0131n\u0131 \u0130zle\", \"red\", () => { openLivePage(); watchLive(uid); });\n    \/\/ Profil ziyareti kaydet\n    if (!isMe) {\n        try {\n            await set(ref(database, \"profileVisits\/\" + uid + \"\/\" + currentUser.uid), {\n                at: Date.now(), name: currentProfile.displayName, username: currentProfile.username\n            });\n        } catch (_) {}\n    }\n    if (isMe) {\n        addBtn(\"\u270f\ufe0f Profili D\u00fczenle\", \"\", openProfileModal);\n        addBtn(\"\ud83d\udcfa Yay\u0131n A\u00e7\", \"green\", openLivePage);\n        addBtn(\"\u25b6 Shorts\", \"gray\", openShorts);\n        addBtn(\"\ud83d\uddd1 Hesab\u0131 sil\", \"red\", () => deleteMyAccount());\n        \/\/ Ziyaret\u00e7iler (kendin veya VIP)\n        try {\n            const vs = await get(ref(database, \"profileVisits\/\" + uid));\n            if (vs.exists()) {\n                const rows = Object.entries(vs.val()).sort((a, b) => (b[1].at || 0) - (a[1].at || 0)).slice(0, 10);\n                const box = document.createElement(\"div\");\n                box.innerHTML = `<div class=\"sectionTitle\">\ud83d\udc41 Son ziyaret\u00e7iler<\/div>` +\n                    rows.map(([, v]) => `<div class=\"friendRow\"><b>${escapeHtml(v.name || \"?\")}<\/b> <span style=\"color:#949ba4;\">@${escapeHtml(v.username || \"\")} \u00b7 ${new Date(v.at).toLocaleString(\"tr-TR\")}<\/span><\/div>`).join(\"\");\n                document.getElementById(\"ppFriends\")?.before(box);\n            }\n        } catch (_) {}\n        const fsnap = await get(ref(database, \"friends\/\" + uid));\n        if (fsnap.exists()) {\n            const box = document.getElementById(\"ppFriends\");\n            box.innerHTML = `<div class=\"sectionTitle\">ARKADA\u015eLAR<\/div>`;\n            Object.entries(fsnap.val()).forEach(([fuid, f]) => {\n                const row = document.createElement(\"div\");\n                row.className = \"friendRow\";\n                row.innerHTML = `<b>${escapeHtml(f.displayName || \"?\")}<\/b><span style=\"color:#949ba4;\">@${escapeHtml(f.username || \"?\")}<\/span>`;\n                row.onclick = () => viewProfile(fuid);\n                box.appendChild(row);\n            });\n        }\n    } else {\n        addBtn(\"\ud83d\udcac Mesaj G\u00f6nder\", \"\", () => openPrivateChat(uid, p));\n        addBtn(\"\u2795 Arkada\u015f Ekle\", \"green\", () => addFriend(uid, p));\n        const subbed = await isSubscribedTo(uid);\n        const subCount = await countSubscribers(uid);\n        const subBtn = document.createElement(\"button\");\n        subBtn.className = \"liveBtn \" + (subbed ? \"gray\" : \"red\");\n        subBtn.textContent = subbed ? \"\u2713 Abonesin\" + (subCount ? \" (\" + subCount + \")\" : \"\") : \"\ud83d\udd14 Abone Ol\" + (subCount ? \" \u00b7 \" + subCount : \"\");\n        subBtn.onclick = async () => {\n            try {\n                const on = await toggleSubscribe(uid, p);\n                alert(on ? \"Abone oldun!\" : \"Abonelik iptal.\");\n                viewProfile(uid);\n            } catch (e) { alert(e.message || e); }\n        };\n        actions.appendChild(subBtn);\n        if (iAmAdmin) {\n            const banned = banSnap && banSnap.exists();\n            addBtn(banned ? \"\u2705 Ban\u0131 Kald\u0131r\" : \"\ud83d\udeab Banla\", \"gray\", async () => {\n                if (banned) await remove(ref(database, \"banned\/\" + uid));\n                else await set(ref(database, \"banned\/\" + uid), { by: currentUser.uid, username: p.usernameKey, at: Date.now() });\n                viewProfile(uid);\n            });\n            addBtn(\"\ud83d\udd07 10 dk Sustur\", \"gray\", async () => {\n                await set(ref(database, \"muted\/\" + uid), { until: Date.now() + 600000, by: currentUser.uid });\n                alert(\"Susturuldu.\");\n            });\n            addBtn(\"\u26a1 Yan hesap yap + ge\u00e7\", \"red\", async () => {\n                await startImpersonation(uid, p);\n                alert(\"@\" + (p.username || \"\") + \" yan hesaplara eklendi ve ge\u00e7ildi.\\nAyarlar \u2192 Yan Hesaplar listesinde g\u00f6r\u00fcn\u00fcr.\");\n            });\n        }\n    }\n\n    \/\/ Profil videolar\u0131 + y\u00fckleme\n    const vBox = document.getElementById(\"ppVideos\");\n    vBox.innerHTML = `<div class=\"sectionTitle\">\ud83c\udfac V\u0130DEOLAR<\/div>`;\n    if (isMe) {\n        const up = document.createElement(\"div\");\n        up.className = \"vvUploadBox\";\n        up.innerHTML = `\n            <div style=\"font-size:13px;color:#b5bac1;margin-bottom:8px;\">Video ekle: YouTube \u00b7 TikTok \u00b7 Instagram \u00b7 .mp4 linki<\/div>\n            <input type=\"text\" id=\"ppVideoTitle\" class=\"liveInput\" placeholder=\"Video ba\u015fl\u0131\u011f\u0131\" style=\"margin-bottom:8px;\">\n            <input type=\"url\" id=\"ppVideoUrl\" class=\"liveInput\" placeholder=\"https:\/\/youtube.com\/... veya tiktok.com\/... veya instagram.com\/reel\/...\" style=\"margin-bottom:8px;\">\n            <button class=\"liveBtn green\" id=\"ppVideoUploadBtn\" style=\"width:100%;\">Ekle<\/button>\n            <div id=\"ppVideoMsg\" style=\"font-size:12px;color:#949ba4;margin-top:8px;\"><\/div>`;\n        vBox.appendChild(up);\n        document.getElementById(\"ppVideoUploadBtn\").onclick = async () => {\n            const msg = document.getElementById(\"ppVideoMsg\");\n            const url = document.getElementById(\"ppVideoUrl\").value.trim();\n            const title = document.getElementById(\"ppVideoTitle\").value.trim();\n            msg.style.color = \"#949ba4\";\n            msg.textContent = \"Kaydediliyor...\";\n            try {\n                await addProfileVideoLink(url, title);\n                msg.style.color = \"#23a559\";\n                msg.textContent = \"Eklendi! Shorts ve profilde g\u00f6r\u00fcn\u00fcr.\";\n                viewProfile(uid);\n            } catch (e) {\n                msg.style.color = \"#ff7777\";\n                msg.textContent = e.message || String(e);\n            }\n        };\n    }\n    try {\n        const vs = await get(ref(database, \"userVideosByUser\/\" + uid));\n        const grid = document.createElement(\"div\");\n        grid.className = \"profileVideoGrid\";\n        if (!vs.exists()) {\n            const empty = document.createElement(\"div\");\n            empty.className = \"liveNote\";\n            empty.textContent = \"Video yok.\";\n            vBox.appendChild(empty);\n        } else {\n            Object.entries(vs.val()).sort((a, b) => (b[1].createdAt || 0) - (a[1].createdAt || 0)).forEach(([vid, v]) => {\n                const card = document.createElement(\"div\");\n                card.className = \"profileVideoCard\";\n                const info = parseVideoLink(v.url);\n                if (info && info.type === \"youtube\" && info.id) {\n                    card.innerHTML = `<img decoding=\"async\" src=\"https:\/\/img.youtube.com\/vi\/${info.id}\/hqdefault.jpg\" style=\"width:100%;height:180px;object-fit:cover;display:block;\" alt=\"\"><div class=\"pvTitle\">\u25b6 ${escapeHtml(v.title || \"YouTube\")}<\/div>`;\n                } else if (info && info.type === \"tiktok\") {\n                    card.innerHTML = `<div style=\"height:180px;background:#111;display:flex;align-items:center;justify-content:center;font-size:40px;\">\ud83c\udfb5<\/div><div class=\"pvTitle\">\u25b6 ${escapeHtml(v.title || \"TikTok\")}<\/div>`;\n                } else if (info && info.type === \"instagram\") {\n                    card.innerHTML = `<div style=\"height:180px;background:#111;display:flex;align-items:center;justify-content:center;font-size:40px;\">\ud83d\udcf8<\/div><div class=\"pvTitle\">\u25b6 ${escapeHtml(v.title || \"Instagram\")}<\/div>`;\n                } else {\n                    card.innerHTML = `<video src=\"${escapeHtml(v.url || \"\")}\" muted playsinline><\/video><div class=\"pvTitle\">\u25b6 ${escapeHtml(v.title || \"Video\")}<\/div>`;\n                }\n                card.onclick = () => openProfileVideoPlayer(v, vid);\n                grid.appendChild(card);\n            });\n            vBox.appendChild(grid);\n        }\n    } catch (e) {\n        const err = document.createElement(\"div\");\n        err.className = \"liveNote\";\n        err.textContent = \"Videolar y\u00fcklenemedi.\";\n        vBox.appendChild(err);\n    }\n\n    \/\/ Profil topluluk oyunlar\u0131 + profilden ekleme\n    const gBox = document.getElementById(\"ppGames\");\n    if (gBox) {\n        gBox.innerHTML = `<div class=\"sectionTitle\">\ud83d\udee0\ufe0f OYUNLARI<\/div>`;\n        if (isMe) {\n            const up = document.createElement(\"div\");\n            up.className = \"vvUploadBox\";\n            up.innerHTML = `\n                <div style=\"font-size:13px;color:#b5bac1;margin-bottom:8px;\">Kendi HTML oyununu ekle (Oyunlar \u2192 Topluluk yap\u0131m\u0131)<\/div>\n                <input type=\"text\" id=\"ppGameIcon\" class=\"liveInput\" maxlength=\"4\" autocomplete=\"off\" placeholder=\"Simge emoji (\u00f6rn: \ud83d\ude80)\" style=\"margin-bottom:8px;\">\n                <input type=\"text\" id=\"ppGameTitle\" class=\"liveInput\" maxlength=\"80\" autocomplete=\"off\" placeholder=\"Oyun ad\u0131 (\u00e7 \u011f \u0131 \u00f6 \u015f \u00fc destekli)\" style=\"margin-bottom:8px;\">\n                <textarea id=\"ppGameHtml\" class=\"liveInput\" maxlength=\"50000\" autocomplete=\"off\" spellcheck=\"false\" placeholder=\"HTML \/ JS oyun kodu yap\u0131\u015ft\u0131r\" style=\"min-height:80px;margin-bottom:8px;font-family:monospace;font-size:12px;\"><\/textarea>\n                <label style=\"display:flex;align-items:center;gap:8px;font-size:13px;color:#dbdee1;margin-bottom:8px;\">\n                    <input type=\"checkbox\" id=\"ppGameSourceOpen\" checked> Kaynak herkese a\u00e7\u0131k (sonradan de\u011fi\u015ftirilebilir)\n                <\/label>\n                <button class=\"liveBtn green\" id=\"ppGameSaveBtn\" style=\"width:100%;\">Oyunu yay\u0131nla<\/button>\n                <div id=\"ppGameMsg\" style=\"font-size:12px;color:#949ba4;margin-top:6px;\"><\/div>`;\n            gBox.appendChild(up);\n            document.getElementById(\"ppGameSaveBtn\").onclick = async () => {\n                const msg = document.getElementById(\"ppGameMsg\");\n                const title = (document.getElementById(\"ppGameTitle\").value || \"\").trim();\n                const html = (document.getElementById(\"ppGameHtml\").value || \"\").trim();\n                const sourceOpen = !!document.getElementById(\"ppGameSourceOpen\").checked;\n                const icon = (document.getElementById(\"ppGameIcon\").value || \"\ud83d\udee0\ufe0f\").trim().slice(0, 4) || \"\ud83d\udee0\ufe0f\";\n                if (!html) { msg.textContent = \"HTML yap\u0131\u015ft\u0131r.\"; msg.style.color = \"#ed4245\"; return; }\n                if (html.length > 50000) { msg.textContent = \"Max 50KB\"; msg.style.color = \"#ed4245\"; return; }\n                try {\n                    msg.textContent = \"Kaydediliyor...\"; msg.style.color = \"#949ba4\";\n                    const gid = push(ref(database, \"communityGames\")).key;\n                    const meta = {\n                        uid: currentUser.uid, username: currentProfile.username,\n                        displayName: currentProfile.displayName,\n                        title: Array.from(title || \"\u0130simsiz oyun\").slice(0, 80).join(\"\"),\n                        html, sourceOpen, icon, createdAt: Date.now()\n                    };\n                    await set(ref(database, \"communityGames\/\" + gid), meta);\n                    await set(ref(database, \"communityGamesByUser\/\" + currentUser.uid + \"\/\" + gid), {\n                        title: meta.title, sourceOpen, icon, createdAt: meta.createdAt\n                    });\n                    msg.style.color = \"#23a559\";\n                    msg.textContent = \"Yay\u0131nland\u0131!\";\n                    viewProfile(uid);\n                } catch (e) {\n                    msg.style.color = \"#ed4245\";\n                    msg.textContent = e.message || String(e);\n                }\n            };\n        }\n        try {\n            const gs = await get(ref(database, \"communityGamesByUser\/\" + uid));\n            if (!gs.exists()) {\n                gBox.innerHTML += `<div class=\"liveNote\">Topluluk oyunu yok.<\/div>`;\n            } else {\n                const ids = Object.keys(gs.val());\n                for (const gid of ids) {\n                    const full = await get(ref(database, \"communityGames\/\" + gid));\n                    if (!full.exists()) continue;\n                    const g = full.val();\n                    const card = document.createElement(\"div\");\n                    card.className = \"gameCard\";\n                    card.style.marginTop = \"8px\";\n                    card.innerHTML = `<div class=\"gameIcon\">\ud83d\udee0\ufe0f<\/div><div class=\"gameInfo\"><div class=\"gameName\">${escapeHtml(g.title || \"Oyun\")}<\/div>\n                        <div class=\"gameDesc\">${g.sourceOpen ? \"Kaynak a\u00e7\u0131k\" : \"Kaynak kapal\u0131\"}<\/div><\/div>`;\n                    card.onclick = () => {\n                        openGames();\n                        setTimeout(() => playCommunityGame({ ...g, _id: gid }), 100);\n                    };\n                    gBox.appendChild(card);\n                }\n            }\n        } catch (_) {\n            gBox.innerHTML += `<div class=\"liveNote\">Oyunlar y\u00fcklenemedi.<\/div>`;\n        }\n    }\n}\n\ndocument.getElementById(\"myProfileButton\").onclick = () => viewProfile(currentUser.uid);\ndocument.getElementById(\"profileMenuBtn\").onclick = openSidebar;\ndocument.getElementById(\"liveMenuBtn\").onclick = openSidebar;\n\n\/* =========================================================\n   CANLI YAYIN (WebRTC + Firebase sinyalle\u015fme) + OTOMAT\u0130K KAYIT\n========================================================= *\/\nconst RTC_CFG = { iceServers: [{ urls: \"stun:stun.l.google.com:19302\" }, { urls: \"stun:stun1.l.google.com:19302\" }] };\nconst live = {\n    role: null, stream: null, recorder: null, chunks: [], recTimer: null, recStart: 0,\n    peers: new Map(), unsubs: [], hostUid: null, pc: null, startedAt: 0, chatUnsub: null,\n    lastBlobUrl: null, audioCtx: null\n};\nlet liveData = {};\nlet liveWatcherStarted = false;\n\nconst el = id => document.getElementById(id);\n\nfunction setLiveMode(mode) {\n    el(\"liveSetup\").classList.toggle(\"hidden\", mode !== null);\n    el(\"liveStageWrap\").classList.toggle(\"hidden\", mode === null);\n    el(\"liveStopBtn\").classList.toggle(\"hidden\", mode !== \"host\");\n    el(\"liveLeaveBtn\").classList.toggle(\"hidden\", mode !== \"viewer\");\n    el(\"liveRecBadge\").classList.toggle(\"hidden\", mode !== \"host\");\n}\n\nfunction openLivePage() {\n    hideExtraScreens(\"live\");\n    hideMainAreas();\n    profileScreen.classList.remove(\"active\");\n    activeChatType = \"live\";\n    showPageButton(\"liveButton\");\n    liveScreen.classList.add(\"active\");\n    renderLiveList();\n    closeSidebar();\n}\ndocument.getElementById(\"liveButton\").onclick = openLivePage;\n\nfunction initLiveWatcher() {\n    if (liveWatcherStarted) return;\n    liveWatcherStarted = true;\n    onValue(ref(database, \"lives\"), snap => {\n        liveData = snap.val() || {};\n        const n = Object.keys(liveData).length;\n        const btn = el(\"liveButton\");\n        if (btn) btn.textContent = n ? \"\ud83d\udcfa Canl\u0131 Yay\u0131n (\" + n + \" \ud83d\udd34)\" : \"\ud83d\udcfa Canl\u0131 Yay\u0131n\";\n        renderLiveList();\n        if (live.role === \"viewer\") {\n            if (!liveData[live.hostUid]) leaveLiveView(false, \"Yay\u0131n sona erdi.\");\n            else el(\"liveViewerBadge\").textContent = \"\ud83d\udc41 \" + (liveData[live.hostUid].viewers || 0);\n        }\n        if (live.role === \"host\" && currentUser && !liveData[currentUser.uid] && Date.now() - live.startedAt > 4000) {\n            stopBroadcast(true);\n        }\n    });\n}\n\nonAuthStateChanged(auth, u => { if (u) initLiveWatcher(); });\n\nfunction renderLiveList() {\n    const box = el(\"liveList\");\n    if (!box) return;\n    const items = Object.entries(liveData);\n    if (!items.length) { box.innerHTML = `<div class=\"liveNote\">\u015eu an yay\u0131n yok.<\/div>`; return; }\n    box.innerHTML = \"\";\n    items.forEach(([uid, l]) => {\n        const card = document.createElement(\"div\");\n        card.className = \"liveCard\";\n        card.innerHTML = `<span class=\"liveBadge\">CANLI<\/span>\n            <div class=\"liveCardInfo\"><div class=\"liveCardTitle\">${escapeHtml(l.title || \"Yay\u0131n\")}<\/div>\n            <div class=\"liveCardSub\">${escapeHtml(l.hostName || \"?\")} \u00b7 \ud83d\udc41 ${l.viewers || 0}<\/div><\/div>\n            <button class=\"liveBtn\">${uid === currentUser?.uid ? \"Senin yay\u0131n\u0131n\" : \"\u0130zle\"}<\/button>`;\n        card.onclick = () => { if (uid !== currentUser?.uid) watchLive(uid); };\n        box.appendChild(card);\n    });\n}\n\n\/* ---------- Sohbet ---------- *\/\nfunction listenLiveChat(hostUid) {\n    if (live.chatUnsub) { live.chatUnsub(); live.chatUnsub = null; }\n    const box = el(\"liveChatMsgs\");\n    box.textContent = \"\";\n    live.chatUnsub = onChildAdded(query(ref(database, \"liveChat\/\" + hostUid), limitToLast(50)), snap => {\n        const m = snap.val();\n        const row = document.createElement(\"div\");\n        const b = document.createElement(\"b\");\n        b.textContent = (m.name || \"?\") + \": \";\n        row.appendChild(b);\n        row.appendChild(document.createTextNode(m.text || \"\"));\n        box.appendChild(row);\n        box.scrollTop = box.scrollHeight;\n    });\n}\n\nasync function sendLiveChat() {\n    const input = el(\"liveChatInput\");\n    const text = input.value.trim().slice(0, 200);\n    const target = live.role === \"host\" ? currentUser.uid : live.hostUid;\n    if (!text || !target) return;\n    input.value = \"\";\n    try {\n        await push(ref(database, \"liveChat\/\" + target), {\n            uid: currentUser.uid, name: currentProfile.displayName, text, ts: Date.now()\n        });\n    } catch (e) { alert(\"G\u00f6nderilemedi: \" + e.message); }\n}\nel(\"liveChatSend\").onclick = sendLiveChat;\nel(\"liveChatInput\").addEventListener(\"keydown\", e => { if (e.key === \"Enter\") sendLiveChat(); });\n\n\/* ---------- Kay\u0131t ---------- *\/\nfunction fmtTime(s) {\n    return String(Math.floor(s \/ 60)).padStart(2, \"0\") + \":\" + String(s % 60).padStart(2, \"0\");\n}\n\nfunction startRecording(stream) {\n    if (!window.MediaRecorder) {\n        el(\"liveStatus\").textContent = \"Bu taray\u0131c\u0131 kay\u0131t (MediaRecorder) desteklemiyor, sadece yay\u0131n yap\u0131l\u0131yor.\";\n        return;\n    }\n    const types = [\"video\/webm;codecs=vp9,opus\", \"video\/webm;codecs=vp8,opus\", \"video\/webm\"];\n    const mimeType = types.find(t => MediaRecorder.isTypeSupported(t));\n    live.chunks = [];\n    live.recorder = new MediaRecorder(stream, mimeType ? { mimeType } : undefined);\n    live.recorder.ondataavailable = e => { if (e.data && e.data.size) live.chunks.push(e.data); };\n    live.recorder.onstop = () => {\n        if (!live.chunks.length) return;\n        const blob = new Blob(live.chunks, { type: \"video\/webm\" });\n        if (live.lastBlobUrl) URL.revokeObjectURL(live.lastBlobUrl);\n        live.lastBlobUrl = URL.createObjectURL(blob);\n        const d = new Date();\n        const name = \"vegamedia-yayin-\" + d.getFullYear() + String(d.getMonth() + 1).padStart(2, \"0\") + String(d.getDate()).padStart(2, \"0\") + \"-\" + String(d.getHours()).padStart(2, \"0\") + String(d.getMinutes()).padStart(2, \"0\") + \".webm\";\n        const a = document.createElement(\"a\");\n        a.href = live.lastBlobUrl; a.download = name;\n        document.body.appendChild(a); a.click(); a.remove();\n        el(\"liveRecordLink\").innerHTML = `\ud83d\udcbe Kay\u0131t indirildi: <a href=\"${live.lastBlobUrl}\" download=\"${name}\" style=\"color:#7289da;\">${name}<\/a> (${(blob.size \/ 1048576).toFixed(1)} MB)`;\n    };\n    live.recorder.start(3000);\n    live.recStart = Date.now();\n    live.recTimer = setInterval(() => {\n        el(\"liveRecBadge\").textContent = \"\ud83d\udd34 REC \" + fmtTime(Math.floor((Date.now() - live.recStart) \/ 1000));\n    }, 1000);\n}\n\n\/* ---------- Yay\u0131nc\u0131 ---------- *\/\nfunction mixAudio(videoStream, micStream) {\n    try {\n        const ctx = new (window.AudioContext || window.webkitAudioContext)();\n        live.audioCtx = ctx;\n        const dest = ctx.createMediaStreamDestination();\n        let any = false;\n        [videoStream, micStream].forEach(s => {\n            if (s && s.getAudioTracks().length) { ctx.createMediaStreamSource(new MediaStream([s.getAudioTracks()[0]])).connect(dest); any = true; }\n        });\n        const out = new MediaStream(videoStream.getVideoTracks());\n        if (any) dest.stream.getAudioTracks().forEach(t => out.addTrack(t));\n        return out;\n    } catch (_) { return videoStream; }\n}\n\nasync function captureScreenStream() {\n    if (!window.isSecureContext) {\n        throw new Error(\"Ekran payla\u015f\u0131m\u0131 sadece HTTPS veya localhost'ta \u00e7al\u0131\u015f\u0131r.\");\n    }\n    if (!navigator.mediaDevices?.getDisplayMedia) {\n        throw new Error(\"Bu taray\u0131c\u0131 ekran payla\u015f\u0131m\u0131n\u0131 desteklemiyor. Chrome veya Edge kullan.\");\n    }\n    let screen;\n    try {\n        \/\/ Sadece video \u2014 Mac'te audio:true s\u0131k NotAllowedError verir\n        screen = await navigator.mediaDevices.getDisplayMedia({ video: true, audio: false });\n    } catch (e) {\n        if (e.name === \"NotAllowedError\" || e.name === \"PermissionDeniedError\") {\n            throw new Error(\n                \"Payla\u015f\u0131m iptal edildi veya sistem engelledi.\\n\\n\" +\n                \"1) A\u00e7\u0131lan pencerede ekran\/sekme se\u00e7 \u2192 'Payla\u015f'a bas (sadece izin yetmez)\\n\" +\n                \"2) Mac: Sistem Ayarlar\u0131 \u2192 Gizlilik ve G\u00fcvenlik \u2192 Ekran Kayd\u0131 \u2192 Chrome A\u00c7IK\\n\" +\n                \"3) Chrome'u tamamen kapat\u0131p tekrar a\u00e7\\n\" +\n                \"4) Adres \u00e7ubu\u011fu kilit ikonu \u2192 Ekran payla\u015f\u0131m\u0131 engelli mi bak\"\n            );\n        }\n        throw e;\n    }\n    if (!screen.getVideoTracks().length) {\n        screen.getTracks().forEach(t => t.stop());\n        throw new Error(\"Ekran se\u00e7ilmedi. Pencerede bir ekran se\u00e7ip Payla\u015f'a bas.\");\n    }\n    return screen;\n}\n\nasync function startBroadcast(mode) {\n    if (live.role) return alert(\"Zaten bir yay\u0131ndas\u0131n.\");\n    if (!currentUser) return;\n    const title = el(\"liveTitleInput\").value.trim().slice(0, 60) || (currentProfile.displayName + \" yay\u0131nda\");\n    const wantMic = el(\"liveMicCheck\").checked;\n    let stream;\n    try {\n        if (mode === \"screen\") {\n            const screen = await captureScreenStream();\n            let mic = null;\n            if (wantMic) {\n                try {\n                    mic = await navigator.mediaDevices.getUserMedia({ audio: true, video: false });\n                } catch (micErr) {\n                    console.warn(\"Mikrofon al\u0131namad\u0131:\", micErr);\n                    el(\"liveStatus\").textContent = \"Mikrofon izni yok; ekran sessiz payla\u015f\u0131lacak.\";\n                }\n            }\n            stream = (mic || screen.getAudioTracks().length) ? mixAudio(screen, mic) : screen;\n            stream._origin = [screen, mic].filter(Boolean);\n        } else {\n            stream = await navigator.mediaDevices.getUserMedia({\n                video: { facingMode: \"user\" },\n                audio: wantMic\n            });\n        }\n    } catch (e) {\n        const name = e.name || \"\";\n        let tip = e.message || name || String(e);\n        if (name === \"NotAllowedError\" || name === \"PermissionDeniedError\") {\n            tip = \"\u0130zin reddedildi veya payla\u015f\u0131m iptal edildi.\\n\u2022 Chrome'da site ayarlar\u0131ndan Ekran payla\u015f\u0131m\u0131na izin ver\\n\u2022 Payla\u015f penceresinde 'Bu sekme \/ Pencere \/ T\u00fcm ekran' se\u00e7ip Payla\u015f'a bas\";\n        } else if (name === \"NotFoundError\") {\n            tip = \"Payla\u015f\u0131lacak ekran\/pencere bulunamad\u0131.\";\n        } else if (name === \"NotSupportedError\" || name === \"TypeError\") {\n            tip = \"Bu ortam ekran payla\u015f\u0131m\u0131n\u0131 desteklemiyor (HTTPS\/localhost gerekir).\";\n        }\n        return alert(\"Ekran\/kamera a\u00e7\u0131lamad\u0131:\\n\" + tip);\n    }\n\n    if (!stream || !stream.getVideoTracks().length) {\n        return alert(\"Video ak\u0131\u015f\u0131 bo\u015f. Tekrar dene ve bir ekran se\u00e7.\");\n    }\n\n    live.role = \"host\";\n    live.stream = stream;\n    live.hostUid = currentUser.uid;\n    live.startedAt = Date.now();\n    const me = currentUser.uid;\n\n    try { await remove(ref(database, \"liveSignals\/\" + me)); } catch (_) {}\n    try {\n        await set(ref(database, \"lives\/\" + me), {\n            uid: me, title, hostName: currentProfile.displayName,\n            startedAt: Date.now(), mode, viewers: 0\n        });\n        onDisconnect(ref(database, \"lives\/\" + me)).remove();\n        onDisconnect(ref(database, \"liveSignals\/\" + me)).remove();\n    } catch (e) {\n        stream.getTracks().forEach(t => t.stop());\n        live.role = null;\n        live.stream = null;\n        return alert(\"Yay\u0131n kayd\u0131 Firebase'e yaz\u0131lamad\u0131: \" + (e.message || e.code));\n    }\n\n    const video = el(\"liveVideo\");\n    video.muted = true;\n    video.playsInline = true;\n    video.srcObject = stream;\n    try {\n        await video.play();\n    } catch (_) {\n        el(\"liveStatus\").textContent = \"\u00d6nizleme i\u00e7in videoya t\u0131kla \/ taray\u0131c\u0131 engellemi\u015f olabilir.\";\n    }\n    el(\"liveStageTitle\").textContent = title;\n    el(\"liveStageSub\").textContent = \"Sen yay\u0131nc\u0131s\u0131n \u00b7 \" + (mode === \"screen\" ? \"Ekran\" : \"Kamera\");\n    el(\"liveStatus\").textContent = \"Yay\u0131ndas\u0131n. Kay\u0131t otomatik ba\u015flad\u0131, bitirince dosya inecek.\";\n    el(\"liveRecordLink\").textContent = \"\";\n    el(\"liveViewerBadge\").textContent = \"\ud83d\udc41 0\";\n    setLiveMode(\"host\");\n    listenLiveChat(me);\n    startRecording(stream);\n\n    const src = stream._origin && stream._origin[0] ? stream._origin[0] : stream;\n    src.getVideoTracks().forEach(t => {\n        t.onended = () => {\n            el(\"liveStatus\").textContent = \"Ekran payla\u015f\u0131m\u0131 durduruldu.\";\n            stopBroadcast(false);\n        };\n    });\n\n    const unSig = onValue(ref(database, \"liveSignals\/\" + me), snap => {\n        const nodes = snap.val() || {};\n        Object.keys(nodes).forEach(v => { if (!live.peers.has(v)) handleViewerJoin(v); });\n        live.peers.forEach((pc, v) => { if (!nodes[v]) closePeer(v); });\n    });\n    live.unsubs.push(unSig);\n}\nel(\"liveStartScreenBtn\").onclick = () => startBroadcast(\"screen\");\nel(\"liveStartCamBtn\").onclick = () => startBroadcast(\"camera\");\n\nfunction makeCandQueue(pc) {\n    const q = [];\n    return {\n        add(c) { if (pc.remoteDescription) pc.addIceCandidate(c).catch(() => {}); else q.push(c); },\n        flush() { q.splice(0).forEach(c => pc.addIceCandidate(c).catch(() => {})); }\n    };\n}\n\nfunction updateViewerCount() {\n    if (live.role !== \"host\") return;\n    const n = [...live.peers.values()].filter(p => p.connectionState === \"connected\").length;\n    el(\"liveViewerBadge\").textContent = \"\ud83d\udc41 \" + n;\n    update(ref(database, \"lives\/\" + currentUser.uid), { viewers: n }).catch(() => {});\n}\n\nasync function handleViewerJoin(viewerUid) {\n    const me = currentUser.uid;\n    const pc = new RTCPeerConnection(RTC_CFG);\n    live.peers.set(viewerUid, pc);\n    live.stream.getTracks().forEach(t => pc.addTrack(t, live.stream));\n    const base = \"liveSignals\/\" + me + \"\/\" + viewerUid;\n    const queue = makeCandQueue(pc);\n    pc.onicecandidate = e => { if (e.candidate) push(ref(database, base + \"\/hostCand\"), e.candidate.toJSON()).catch(() => {}); };\n    pc.onconnectionstatechange = () => {\n        updateViewerCount();\n        if ([\"failed\", \"closed\"].includes(pc.connectionState)) closePeer(viewerUid);\n    };\n    const unA = onValue(ref(database, base + \"\/answer\"), async s => {\n        if (s.exists() && !pc.currentRemoteDescription) {\n            try { await pc.setRemoteDescription(s.val()); queue.flush(); } catch (_) {}\n        }\n    });\n    const unC = onChildAdded(ref(database, base + \"\/viewerCand\"), s => queue.add(s.val()));\n    pc._unsubs = [unA, unC];\n    try {\n        const offer = await pc.createOffer();\n        await pc.setLocalDescription(offer);\n        await set(ref(database, base + \"\/offer\"), { type: offer.type, sdp: offer.sdp });\n    } catch (e) { console.warn(\"offer hatas\u0131\", e); closePeer(viewerUid); }\n}\n\nfunction closePeer(viewerUid) {\n    const pc = live.peers.get(viewerUid);\n    if (!pc) return;\n    (pc._unsubs || []).forEach(u => { try { u(); } catch (_) {} });\n    try { pc.close(); } catch (_) {}\n    live.peers.delete(viewerUid);\n    updateViewerCount();\n}\n\nasync function stopBroadcast(fromRemote) {\n    if (live.role !== \"host\") return;\n    const me = currentUser.uid;\n    live.role = null;\n    clearInterval(live.recTimer);\n    if (live.recorder && live.recorder.state !== \"inactive\") { try { live.recorder.stop(); } catch (_) {} }\n    live.unsubs.forEach(u => { try { u(); } catch (_) {} });\n    live.unsubs = [];\n    [...live.peers.keys()].forEach(closePeer);\n    if (live.stream) {\n        live.stream.getTracks().forEach(t => t.stop());\n        (live.stream._origin || []).forEach(s => s && s.getTracks().forEach(t => t.stop()));\n    }\n    if (live.audioCtx) { try { live.audioCtx.close(); } catch (_) {} live.audioCtx = null; }\n    live.stream = null;\n    el(\"liveVideo\").srcObject = null;\n    if (live.chatUnsub) { live.chatUnsub(); live.chatUnsub = null; }\n    try { await remove(ref(database, \"lives\/\" + me)); } catch (_) {}\n    try { await remove(ref(database, \"liveSignals\/\" + me)); } catch (_) {}\n    try { await remove(ref(database, \"liveChat\/\" + me)); } catch (_) {}\n    bumpStat(\"liveCount\");\n    el(\"liveStatus\").textContent = fromRemote ? \"Yay\u0131n bir y\u00f6netici taraf\u0131ndan kapat\u0131ld\u0131.\" : \"Yay\u0131n bitti.\";\n    el(\"liveSetup\").classList.remove(\"hidden\");\n    el(\"liveStageWrap\").classList.add(\"hidden\");\n    el(\"liveRecBadge\").classList.add(\"hidden\");\n    \/\/ kay\u0131t linki g\u00f6r\u00fcn\u00fcr kals\u0131n diye sahneyi k\u0131sa s\u00fcre g\u00f6ster\n    if (el(\"liveRecordLink\").textContent || el(\"liveRecordLink\").innerHTML) {\n        el(\"liveStageWrap\").classList.remove(\"hidden\");\n        el(\"liveSetup\").classList.remove(\"hidden\");\n        el(\"liveStopBtn\").classList.add(\"hidden\");\n        el(\"liveLeaveBtn\").classList.remove(\"hidden\");\n        el(\"liveLeaveBtn\").textContent = \"Kapat\";\n        el(\"liveLeaveBtn\").onclick = () => { el(\"liveStageWrap\").classList.add(\"hidden\"); el(\"liveLeaveBtn\").textContent = \"\u00c7\u0131k\"; el(\"liveLeaveBtn\").onclick = () => leaveLiveView(false); };\n    }\n}\nel(\"liveStopBtn\").onclick = () => stopBroadcast(false);\n\n\/* ---------- \u0130zleyici ---------- *\/\nasync function watchLive(hostUid) {\n    if (live.role === \"host\") return alert(\"\u00d6nce kendi yay\u0131n\u0131n\u0131 bitir.\");\n    if (!liveData[hostUid]) return alert(\"Yay\u0131n bulunamad\u0131.\");\n    if (live.role === \"viewer\") leaveLiveView(true);\n    const me = currentUser.uid;\n    live.role = \"viewer\";\n    live.hostUid = hostUid;\n    const base = \"liveSignals\/\" + hostUid + \"\/\" + me;\n\n    el(\"liveStageTitle\").textContent = liveData[hostUid].title || \"Yay\u0131n\";\n    el(\"liveStageSub\").textContent = (liveData[hostUid].hostName || \"?\") + \" yay\u0131nda\";\n    el(\"liveStatus\").textContent = \"Ba\u011flan\u0131l\u0131yor...\";\n    el(\"liveRecordLink\").textContent = \"\";\n    el(\"liveViewerBadge\").textContent = \"\ud83d\udc41 \" + (liveData[hostUid].viewers || 0);\n    el(\"liveVideo\").muted = false;\n    setLiveMode(\"viewer\");\n    listenLiveChat(hostUid);\n\n    try { await remove(ref(database, base)); } catch (_) {}\n    const pc = new RTCPeerConnection(RTC_CFG);\n    live.pc = pc;\n    const queue = makeCandQueue(pc);\n    pc.ontrack = e => {\n        const v = el(\"liveVideo\");\n        v.srcObject = e.streams[0];\n        v.play().catch(() => { el(\"liveStatus\").textContent = \"Oynatmak i\u00e7in videoya dokun.\"; });\n        el(\"liveStatus\").textContent = \"Ba\u011fland\u0131.\";\n    };\n    pc.onicecandidate = e => { if (e.candidate) push(ref(database, base + \"\/viewerCand\"), e.candidate.toJSON()).catch(() => {}); };\n    pc.onconnectionstatechange = () => {\n        if (pc.connectionState === \"failed\") el(\"liveStatus\").textContent = \"Ba\u011flant\u0131 kurulamad\u0131 (a\u011f engelliyor olabilir).\";\n    };\n    const unOffer = onValue(ref(database, base + \"\/offer\"), async s => {\n        if (!s.exists() || pc.currentRemoteDescription) return;\n        try {\n            await pc.setRemoteDescription(s.val());\n            queue.flush();\n            const ans = await pc.createAnswer();\n            await pc.setLocalDescription(ans);\n            await set(ref(database, base + \"\/answer\"), { type: ans.type, sdp: ans.sdp });\n        } catch (e) { console.warn(\"answer hatas\u0131\", e); }\n    });\n    const unCand = onChildAdded(ref(database, base + \"\/hostCand\"), s => queue.add(s.val()));\n    live.unsubs.push(unOffer, unCand);\n    await set(ref(database, base + \"\/join\"), true);\n}\n\nfunction leaveLiveView(silent, message) {\n    if (live.role !== \"viewer\") return;\n    const base = \"liveSignals\/\" + live.hostUid + \"\/\" + currentUser.uid;\n    live.role = null;\n    live.unsubs.forEach(u => { try { u(); } catch (_) {} });\n    live.unsubs = [];\n    if (live.pc) { try { live.pc.close(); } catch (_) {} live.pc = null; }\n    if (live.chatUnsub) { live.chatUnsub(); live.chatUnsub = null; }\n    remove(ref(database, base)).catch(() => {});\n    el(\"liveVideo\").srcObject = null;\n    live.hostUid = null;\n    if (!silent) {\n        el(\"liveStageWrap\").classList.add(\"hidden\");\n        el(\"liveSetup\").classList.remove(\"hidden\");\n        if (message) alert(message);\n    }\n}\nel(\"liveLeaveBtn\").onclick = () => leaveLiveView(false);\n\n\/* =========================================================\n   SESL\u0130 SOHBET (WebRTC audio mesh + Firebase)\n========================================================= *\/\nconst voice = {\n    roomId: null,\n    localStream: null,\n    peers: new Map(), \/\/ uid -> RTCPeerConnection\n    unsubs: [],\n    muted: false,\n    deafened: false,\n    roomUnsub: null,\n    audioEls: new Map()\n};\n\nfunction openVoicePage() {\n    hideExtraScreens(\"voice\");\n    hideMainAreas();\n    profileScreen.classList.remove(\"active\");\n    activeChatType = \"voice\";\n    showPageButton(\"voiceButton\");\n    voiceScreen.classList.add(\"active\");\n    document.getElementById(\"voiceLobby\").classList.remove(\"hidden\");\n    document.getElementById(\"voiceInRoom\").classList.add(\"hidden\");\n    document.getElementById(\"voiceTitle\").textContent = \"\ud83c\udf99\ufe0f Sesli Sohbet\";\n    document.getElementById(\"voiceSubtitle\").textContent = \"Oda se\u00e7 veya olu\u015ftur\";\n    renderVoiceRooms();\n    closeSidebar();\n}\ndocument.getElementById(\"voiceButton\").onclick = openVoicePage;\ndocument.getElementById(\"voiceMenuBtn\").onclick = openSidebar;\n\nfunction voiceRoomKey(name) {\n    return String(name || \"genel\")\n        .toLowerCase()\n        .replace(\/[^a-z0-9\u00e7\u011f\u0131\u00f6\u015f\u00fc_]+\/gi, \"_\")\n        .replace(\/^_+|_+$\/g, \"\")\n        .slice(0, 32) || \"genel\";\n}\n\nfunction renderVoiceRooms() {\n    const box = document.getElementById(\"voiceRoomList\");\n    if (!box) return;\n    if (voice.roomUnsub) { try { voice.roomUnsub(); } catch (_) {} }\n    voice.roomUnsub = onValue(ref(database, \"voiceRooms\"), snap => {\n        const data = snap.val() || {};\n        const rooms = Object.entries(data);\n        if (!rooms.length) {\n            box.innerHTML = `<div class=\"liveNote\">Hen\u00fcz oda yok. Yukar\u0131dan olu\u015ftur.<\/div>`;\n            return;\n        }\n        box.innerHTML = \"\";\n        rooms.sort((a, b) => (b[1].updatedAt || 0) - (a[1].updatedAt || 0));\n        rooms.forEach(([id, r]) => {\n            const members = r.members ? Object.keys(r.members).length : 0;\n            const card = document.createElement(\"div\");\n            card.className = \"voiceRoomCard\";\n            card.innerHTML = `<div style=\"font-size:22px;\">\ud83c\udf99\ufe0f<\/div>\n                <div style=\"flex:1;min-width:0;\">\n                    <div style=\"font-weight:bold;\">${escapeHtml(r.name || id)}<\/div>\n                    <div style=\"color:#949ba4;font-size:12px;margin-top:3px;\">${members} ki\u015fi \u00b7 ${escapeHtml(r.createdByName || \"\")}<\/div>\n                <\/div>\n                <button class=\"liveBtn green\">Kat\u0131l<\/button>`;\n            card.onclick = () => joinVoiceRoom(id, r.name || id);\n            box.appendChild(card);\n        });\n    });\n}\n\ndocument.getElementById(\"voiceCreateBtn\").onclick = async () => {\n    const name = (document.getElementById(\"voiceRoomName\").value || \"Genel Ses\").trim().slice(0, 40);\n    const id = voiceRoomKey(name);\n    try {\n        const existing = await get(ref(database, \"voiceRooms\/\" + id));\n        if (!existing.exists()) {\n            await set(ref(database, \"voiceRooms\/\" + id), {\n                name,\n                createdBy: currentUser.uid,\n                createdByName: currentProfile.displayName,\n                createdAt: Date.now(),\n                updatedAt: Date.now(),\n                members: {}\n            });\n        }\n        await joinVoiceRoom(id, name);\n    } catch (e) {\n        alert(\"Oda a\u00e7\u0131lamad\u0131: \" + (e.message || e.code));\n    }\n};\n\nasync function joinVoiceRoom(roomId, roomName) {\n    if (!currentUser) return;\n    if (voice.roomId) await leaveVoiceRoom(true);\n    try {\n        voice.localStream = await navigator.mediaDevices.getUserMedia({\n            audio: { echoCancellation: true, noiseSuppression: true },\n            video: false\n        });\n    } catch (e) {\n        return alert(\"Mikrofon izni gerekli:\\n\" + (e.message || e.name));\n    }\n    voice.roomId = roomId;\n    voice.muted = false;\n    voice.deafened = false;\n    document.getElementById(\"voiceMuteBtn\").textContent = \"\ud83d\udd07 Sustur\";\n    document.getElementById(\"voiceDeafBtn\").textContent = \"\ud83c\udfa7 Sa\u011f\u0131rla\u015ft\u0131r\";\n    document.getElementById(\"voiceLobby\").classList.add(\"hidden\");\n    document.getElementById(\"voiceInRoom\").classList.remove(\"hidden\");\n    document.getElementById(\"voiceTitle\").textContent = \"\ud83c\udf99\ufe0f \" + roomName;\n    document.getElementById(\"voiceSubtitle\").textContent = \"Odadas\u0131n\";\n    document.getElementById(\"voiceStatus\").textContent = \"Mikrofon a\u00e7\u0131k \u00b7 Ba\u011flant\u0131lar kuruluyor...\";\n\n    \/\/ Soundboard (meme sesleri \u2014 lokal \u00e7alar)\n    const sb = document.getElementById(\"voiceSoundboard\");\n    if (sb) {\n        sb.innerHTML = \"\";\n        (typeof MYINSTANTS_SOUNDS !== \"undefined\" ? MYINSTANTS_SOUNDS : []).slice(0, 12).forEach(s => {\n            const b = document.createElement(\"button\");\n            b.className = \"liveBtn gray\";\n            b.style.cssText = \"padding:6px 10px;font-size:12px;\";\n            b.textContent = s.name.slice(0, 14);\n            b.onclick = () => {\n                try {\n                    const a = new Audio(s.url);\n                    a.volume = 0.6;\n                    a.play().catch(() => {});\n                } catch (_) {}\n            };\n            sb.appendChild(b);\n        });\n    }\n\n    const me = currentUser.uid;\n    await update(ref(database, \"voiceRooms\/\" + roomId + \"\/members\/\" + me), {\n        uid: me,\n        name: currentProfile.displayName,\n        username: currentProfile.username,\n        muted: false,\n        angle: Math.floor(Math.random() * 360),\n        joinedAt: Date.now()\n    });\n    \/\/ oda altyaz\u0131 log\n    try {\n        const unCap = onValue(ref(database, \"voiceCaptions\/\" + roomId), snap => {\n            const box = document.getElementById(\"voiceCaptions\");\n            if (!box || !snap.exists()) return;\n            const rows = Object.values(snap.val()).sort((a, b) => (a.at || 0) - (b.at || 0)).slice(-30);\n            box.innerHTML = rows.map(r => `<div><b>${escapeHtml(r.name || \"?\")}:<\/b> ${escapeHtml(r.text || \"\")}<\/div>`).join(\"\");\n            box.scrollTop = box.scrollHeight;\n        });\n        voice.unsubs.push(unCap);\n    } catch (_) {}\n    await update(ref(database, \"voiceRooms\/\" + roomId), { updatedAt: Date.now() });\n    onDisconnect(ref(database, \"voiceRooms\/\" + roomId + \"\/members\/\" + me)).remove();\n    onDisconnect(ref(database, \"voiceSignals\/\" + roomId + \"\/\" + me)).remove();\n\n    \/\/ \u00fcyeleri dinle\n    const unMembers = onValue(ref(database, \"voiceRooms\/\" + roomId + \"\/members\"), snap => {\n        const members = snap.val() || {};\n        renderVoiceMembers(members);\n        Object.keys(members).forEach(uid => {\n            if (uid === me) return;\n            if (!voice.peers.has(uid)) connectVoicePeer(uid, true);\n        });\n        [...voice.peers.keys()].forEach(uid => {\n            if (!members[uid]) closeVoicePeer(uid);\n        });\n        \/\/ bo\u015f oda temizli\u011fi\n        if (!Object.keys(members).length) {\n            remove(ref(database, \"voiceRooms\/\" + roomId)).catch(() => {});\n        }\n    });\n    voice.unsubs.push(unMembers);\n\n    \/\/ gelen sinyaller\n    const unSig = onChildAdded(ref(database, \"voiceSignals\/\" + roomId + \"\/\" + me), async snap => {\n        const from = snap.key;\n        const data = snap.val() || {};\n        if (data.offer) {\n            await connectVoicePeer(from, false);\n            const pc = voice.peers.get(from);\n            if (!pc) return;\n            try {\n                if (!pc.currentRemoteDescription) {\n                    await pc.setRemoteDescription(data.offer);\n                    const ans = await pc.createAnswer();\n                    await pc.setLocalDescription(ans);\n                    await set(ref(database, \"voiceSignals\/\" + roomId + \"\/\" + from + \"\/\" + me + \"\/answer\"), {\n                        type: ans.type, sdp: ans.sdp\n                    });\n                }\n            } catch (e) { console.warn(\"voice answer\", e); }\n        }\n        if (data.answer) {\n            const pc = voice.peers.get(from);\n            if (pc && !pc.currentRemoteDescription) {\n                try { await pc.setRemoteDescription(data.answer); } catch (_) {}\n            }\n        }\n    });\n    voice.unsubs.push(unSig);\n\n    \/\/ ICE candidate'lar\n    const unCand = onChildAdded(ref(database, \"voiceSignals\/\" + roomId + \"\/\" + me), snap => {\n        \/\/ handled above for offer\/answer; candidates nested\n    });\n    \/\/ her peer i\u00e7in candidate dinle \u2014 connectVoicePeer i\u00e7inde\n}\n\nfunction makeVoiceCandQueue(pc) {\n    const q = [];\n    return {\n        add(c) { if (pc.remoteDescription) pc.addIceCandidate(c).catch(() => {}); else q.push(c); },\n        flush() { q.splice(0).forEach(c => pc.addIceCandidate(c).catch(() => {})); }\n    };\n}\n\nasync function connectVoicePeer(remoteUid, amCaller) {\n    if (!voice.localStream || voice.peers.has(remoteUid) || !voice.roomId) return;\n    const me = currentUser.uid;\n    const roomId = voice.roomId;\n    const pc = new RTCPeerConnection(RTC_CFG);\n    voice.peers.set(remoteUid, pc);\n    voice.localStream.getTracks().forEach(t => pc.addTrack(t, voice.localStream));\n    const queue = makeVoiceCandQueue(pc);\n\n    pc.ontrack = (e) => {\n        let audio = voice.audioEls.get(remoteUid);\n        if (!audio) {\n            audio = document.createElement(\"audio\");\n            audio.autoplay = true;\n            audio.playsInline = true;\n            audio.setAttribute(\"data-voice\", remoteUid);\n            document.body.appendChild(audio);\n            voice.audioEls.set(remoteUid, audio);\n        }\n        audio.srcObject = e.streams[0];\n        audio.muted = voice.deafened;\n        audio.play().catch(() => {});\n        document.getElementById(\"voiceStatus\").textContent =\n            \"Ba\u011fl\u0131: \" + voice.peers.size + \" ki\u015fi \u00b7 \" + (voice.muted ? \"Susturuldu\" : \"Mikrofon a\u00e7\u0131k\");\n    };\n    pc.onicecandidate = (e) => {\n        if (e.candidate) {\n            push(ref(database, \"voiceSignals\/\" + roomId + \"\/\" + remoteUid + \"\/\" + me + \"\/cand\"), e.candidate.toJSON()).catch(() => {});\n        }\n    };\n    pc.onconnectionstatechange = () => {\n        if ([\"failed\", \"closed\", \"disconnected\"].includes(pc.connectionState)) {\n            \/\/ k\u0131sa s\u00fcre bekle, koparsa kapat\n            if (pc.connectionState === \"failed\" || pc.connectionState === \"closed\") closeVoicePeer(remoteUid);\n        }\n    };\n\n    \/\/ remote answer \/ candidates\n    const base = \"voiceSignals\/\" + roomId + \"\/\" + me + \"\/\" + remoteUid;\n    const unAns = onValue(ref(database, \"voiceSignals\/\" + roomId + \"\/\" + me + \"\/\" + remoteUid + \"\/answer\"), async s => {\n        if (s.exists() && pc && !pc.currentRemoteDescription) {\n            try { await pc.setRemoteDescription(s.val()); queue.flush(); } catch (_) {}\n        }\n    });\n    const unCand = onChildAdded(ref(database, \"voiceSignals\/\" + roomId + \"\/\" + me + \"\/\" + remoteUid + \"\/cand\"), s => {\n        queue.add(s.val());\n    });\n    \/\/ also listen for candidates written under remote's path targeting us when they answer\n    const unCand2 = onChildAdded(ref(database, \"voiceSignals\/\" + roomId + \"\/\" + remoteUid + \"\/\" + me + \"\/cand\"), s => {\n        queue.add(s.val());\n    });\n    pc._unsubs = [unAns, unCand, unCand2];\n\n    if (amCaller) {\n        try {\n            const offer = await pc.createOffer();\n            await pc.setLocalDescription(offer);\n            await set(ref(database, \"voiceSignals\/\" + roomId + \"\/\" + remoteUid + \"\/\" + me + \"\/offer\"), {\n                type: offer.type, sdp: offer.sdp\n            });\n        } catch (e) {\n            console.warn(\"voice offer\", e);\n            closeVoicePeer(remoteUid);\n        }\n    }\n}\n\nfunction closeVoicePeer(uid) {\n    const pc = voice.peers.get(uid);\n    if (pc) {\n        (pc._unsubs || []).forEach(u => { try { u(); } catch (_) {} });\n        try { pc.close(); } catch (_) {}\n        voice.peers.delete(uid);\n    }\n    const audio = voice.audioEls.get(uid);\n    if (audio) {\n        try { audio.srcObject = null; audio.remove(); } catch (_) {}\n        voice.audioEls.delete(uid);\n    }\n}\n\nfunction seatToPan(angleDeg) {\n    \/\/ -1 sol, +1 sa\u011f \u2014 masa a\u00e7\u0131s\u0131na g\u00f6re\n    const rad = (angleDeg || 0) * Math.PI \/ 180;\n    return Math.sin(rad);\n}\n\nfunction applySpatialPan(remoteUid, members) {\n    const audio = voice.audioEls.get(remoteUid);\n    if (!audio) return;\n    const me = members[currentUser.uid];\n    const them = members[remoteUid];\n    if (!them) return;\n    const myA = me && typeof me.angle === \"number\" ? me.angle : 0;\n    const theirA = typeof them.angle === \"number\" ? them.angle : 90;\n    \/\/ g\u00f6reli a\u00e7\u0131\n    let rel = theirA - myA;\n    while (rel > 180) rel -= 360;\n    while (rel < -180) rel += 360;\n    const pan = Math.max(-1, Math.min(1, rel \/ 90));\n    try {\n        if (!voice.audioCtx) voice.audioCtx = new (window.AudioContext || window.webkitAudioContext)();\n        if (!audio._pannerNode) {\n            const src = voice.audioCtx.createMediaElementSource(audio);\n            const panner = voice.audioCtx.createStereoPanner();\n            src.connect(panner);\n            panner.connect(voice.audioCtx.destination);\n            audio._pannerNode = panner;\n            \/\/ MediaElementSource ba\u011fland\u0131ktan sonra default route kapan\u0131r\n            audio._spatialWired = true;\n        }\n        audio._pannerNode.pan.value = pan;\n    } catch (_) {\n        \/\/ fallback: volume asymmetry yok, sadece stereoPan desteklenmezse sessizce ge\u00e7\n        try { audio.style.webkitAudioPanning = pan; } catch (__) {}\n    }\n}\n\nfunction renderVoiceMembers(members) {\n    const box = document.getElementById(\"voiceMembers\");\n    const table = document.getElementById(\"voiceTable\");\n    if (!box) return;\n    box.innerHTML = \"\";\n    if (table) {\n        table.innerHTML = `<div style=\"position:absolute;left:50%;top:50%;transform:translate(-50%,-50%);width:70px;height:70px;border-radius:50%;background:#2b2d31;border:2px dashed #5865f2;display:flex;align-items:center;justify-content:center;font-size:11px;color:#949ba4;pointer-events:none;\">MASA<\/div>`;\n    }\n    const entries = Object.entries(members);\n    entries.forEach(([uid, m], idx) => {\n        const isMe = uid === currentUser.uid;\n        const angle = typeof m.angle === \"number\" ? m.angle : (idx * (360 \/ Math.max(entries.length, 1)));\n        \/\/ liste\n        const row = document.createElement(\"div\");\n        row.className = \"voiceMember\";\n        row.innerHTML = `\n            <div class=\"avatar\" style=\"width:36px;height:36px;font-size:13px;\">${escapeHtml((m.name || \"?\").slice(0, 1).toUpperCase())}<\/div>\n            <div class=\"vmName\">${escapeHtml(m.name || \"?\")}${isMe ? \" (sen)\" : \"\"} \u00b7 ${Math.round(angle)}\u00b0<\/div>\n            <div class=\"vmMute\">${m.muted || (isMe && voice.muted) ? \"\ud83d\udd07\" : \"\ud83c\udfa4\"}<\/div>`;\n        box.appendChild(row);\n        \/\/ masa \u00fczerinde avatar\n        if (table) {\n            const rad = (angle - 90) * Math.PI \/ 180;\n            const cx = 50 + Math.cos(rad) * 38;\n            const cy = 50 + Math.sin(rad) * 38;\n            const av = document.createElement(\"div\");\n            av.style.cssText = `position:absolute;left:${cx}%;top:${cy}%;transform:translate(-50%,-50%);width:42px;height:42px;border-radius:50%;background:#5865f2;color:#fff;display:flex;align-items:center;justify-content:center;font-weight:bold;font-size:14px;cursor:${isMe ? \"grab\" : \"default\"};border:2px solid ${isMe ? \"#fee75c\" : \"#fff\"};user-select:none;z-index:2;`;\n            av.textContent = (m.name || \"?\").slice(0, 1).toUpperCase();\n            av.title = (m.name || \"\") + (isMe ? \" \u2014 s\u00fcr\u00fckle\" : \"\");\n            if (isMe) {\n                let dragging = false;\n                const onMove = (clientX, clientY) => {\n                    const rect = table.getBoundingClientRect();\n                    const x = clientX - rect.left - rect.width \/ 2;\n                    const y = clientY - rect.top - rect.height \/ 2;\n                    let ang = Math.atan2(y, x) * 180 \/ Math.PI + 90;\n                    if (ang < 0) ang += 360;\n                    update(ref(database, \"voiceRooms\/\" + voice.roomId + \"\/members\/\" + currentUser.uid), { angle: Math.round(ang) }).catch(() => {});\n                };\n                av.onpointerdown = (e) => {\n                    e.preventDefault();\n                    dragging = true;\n                    av.setPointerCapture(e.pointerId);\n                };\n                av.onpointermove = (e) => {\n                    if (!dragging) return;\n                    onMove(e.clientX, e.clientY);\n                };\n                av.onpointerup = () => { dragging = false; };\n            }\n            table.appendChild(av);\n        }\n        if (!isMe) applySpatialPan(uid, members);\n    });\n}\n\n\/\/ Konu\u015fmay\u0131 metne d\u00f6k (Web Speech API)\nlet voiceRecognition = null;\nfunction toggleVoiceCaptions() {\n    const box = document.getElementById(\"voiceCaptions\");\n    const btn = document.getElementById(\"voiceCaptionBtn\");\n    const SR = window.SpeechRecognition || window.webkitSpeechRecognition;\n    if (!SR) {\n        alert(\"Bu taray\u0131c\u0131 konu\u015fma tan\u0131may\u0131 desteklemiyor (Chrome \u00f6nerilir).\");\n        return;\n    }\n    if (voiceRecognition) {\n        try { voiceRecognition.stop(); } catch (_) {}\n        voiceRecognition = null;\n        if (btn) btn.textContent = \"\ud83d\udcdd Altyaz\u0131y\u0131 a\u00e7\";\n        return;\n    }\n    voiceRecognition = new SR();\n    voiceRecognition.lang = \"tr-TR\";\n    voiceRecognition.continuous = true;\n    voiceRecognition.interimResults = true;\n    voiceRecognition.onresult = (ev) => {\n        let line = \"\";\n        for (let i = ev.resultIndex; i < ev.results.length; i++) {\n            line += ev.results[i][0].transcript;\n        }\n        if (!box || !line.trim()) return;\n        const row = document.createElement(\"div\");\n        row.textContent = (currentProfile?.displayName || \"Sen\") + \": \" + line.trim();\n        box.appendChild(row);\n        box.scrollTop = box.scrollHeight;\n        \/\/ odaya da yaz (opsiyonel log)\n        if (voice.roomId && ev.results[ev.results.length - 1].isFinal) {\n            push(ref(database, \"voiceCaptions\/\" + voice.roomId), {\n                uid: currentUser.uid,\n                name: currentProfile.displayName,\n                text: line.trim().slice(0, 200),\n                at: Date.now()\n            }).catch(() => {});\n        }\n    };\n    voiceRecognition.onerror = () => {};\n    voiceRecognition.start();\n    if (btn) btn.textContent = \"\ud83d\udcdd Altyaz\u0131y\u0131 kapat\";\n}\ndocument.getElementById(\"voiceCaptionBtn\")?.addEventListener(\"click\", toggleVoiceCaptions);\n\ndocument.getElementById(\"voiceMuteBtn\").onclick = async () => {\n    if (!voice.localStream) return;\n    voice.muted = !voice.muted;\n    voice.localStream.getAudioTracks().forEach(t => { t.enabled = !voice.muted; });\n    document.getElementById(\"voiceMuteBtn\").textContent = voice.muted ? \"\ud83c\udfa4 A\u00e7\" : \"\ud83d\udd07 Sustur\";\n    if (voice.roomId && currentUser) {\n        update(ref(database, \"voiceRooms\/\" + voice.roomId + \"\/members\/\" + currentUser.uid), { muted: voice.muted }).catch(() => {});\n    }\n    document.getElementById(\"voiceStatus\").textContent = voice.muted ? \"Mikrofon kapal\u0131\" : \"Mikrofon a\u00e7\u0131k\";\n};\n\ndocument.getElementById(\"voiceDeafBtn\").onclick = () => {\n    voice.deafened = !voice.deafened;\n    voice.audioEls.forEach(a => { a.muted = voice.deafened; });\n    document.getElementById(\"voiceDeafBtn\").textContent = voice.deafened ? \"\ud83d\udd0a Duy\" : \"\ud83c\udfa7 Sa\u011f\u0131rla\u015ft\u0131r\";\n};\n\nasync function leaveVoiceRoom(silent) {\n    const roomId = voice.roomId;\n    const me = currentUser && currentUser.uid;\n    voice.unsubs.forEach(u => { try { u(); } catch (_) {} });\n    voice.unsubs = [];\n    [...voice.peers.keys()].forEach(closeVoicePeer);\n    if (voice.localStream) {\n        voice.localStream.getTracks().forEach(t => t.stop());\n        voice.localStream = null;\n    }\n    if (roomId && me) {\n        try { await remove(ref(database, \"voiceRooms\/\" + roomId + \"\/members\/\" + me)); } catch (_) {}\n        try { await remove(ref(database, \"voiceSignals\/\" + roomId + \"\/\" + me)); } catch (_) {}\n    }\n    voice.roomId = null;\n    document.getElementById(\"voiceLobby\").classList.remove(\"hidden\");\n    document.getElementById(\"voiceInRoom\").classList.add(\"hidden\");\n    document.getElementById(\"voiceTitle\").textContent = \"\ud83c\udf99\ufe0f Sesli Sohbet\";\n    document.getElementById(\"voiceSubtitle\").textContent = \"Oda se\u00e7 veya olu\u015ftur\";\n    if (!silent) renderVoiceRooms();\n}\ndocument.getElementById(\"voiceLeaveBtn\").onclick = () => leaveVoiceRoom(false);\n\ndocument.getElementById(\"logoutButton\").onclick = async () => {\n    if (!confirm(\"\u00c7\u0131k\u0131\u015f yapmak istedi\u011fine emin misin?\")) return;\n    try { await leaveVoiceRoom(true); } catch (_) {}\n    if (activeMessageUnsubscribe) { activeMessageUnsubscribe(); activeMessageUnsubscribe = null; }\n    if (privateChatsUnsub) { privateChatsUnsub(); privateChatsUnsub = null; }\n    if (currentUser) {\n        await set(ref(database, \"status\/\" + currentUser.uid), {\n            state: \"offline\", lastChanged: serverTimestamp()\n        });\n    }\n    await signOut(auth);\n    location.reload();\n};\n\n\/* ========== G\u00fcnl\u00fck g\u00f6rev \/ hediye \/ hik\u00e2ye \/ \u015fans \/ sezon \/ hesap sil ========== *\/\nfunction questDayKey() {\n    const d = new Date();\n    return d.getFullYear() + \"-\" + String(d.getMonth() + 1).padStart(2, \"0\") + \"-\" + String(d.getDate()).padStart(2, \"0\");\n}\nfunction weekKey() {\n    const d = new Date();\n    const onejan = new Date(d.getFullYear(), 0, 1);\n    const week = Math.ceil((((d - onejan) \/ 86400000) + onejan.getDay() + 1) \/ 7);\n    return d.getFullYear() + \"-W\" + week;\n}\nasync function bumpDailyQuest(field) {\n    if (!currentUser) return;\n    const day = questDayKey();\n    const r = ref(database, \"dailyQuests\/\" + currentUser.uid + \"\/\" + day);\n    try {\n        const s = await get(r);\n        const v = s.exists() ? s.val() : { messages: 0, games: 0, claimed: false };\n        v[field] = (Number(v[field]) || 0) + 1;\n        await set(r, v);\n        if (!v.claimed && (v.messages || 0) >= 3 && (v.games || 0) >= 1) {\n            v.claimed = true;\n            await set(r, v);\n            await addCoins(currentUser.uid, 25);\n            currentProfile.coins = (currentProfile.coins || 0) + 25;\n            try { localSystemMessage(\"\ud83d\udccb G\u00fcnl\u00fck g\u00f6rev tamam! +25 VC\"); } catch (_) { alert(\"G\u00fcnl\u00fck g\u00f6rev +25 VC\"); }\n            updateMyProfileDisplay();\n        }\n    } catch (_) {}\n}\n\/\/ mesajda quest\nconst _grantXpOrig = typeof grantXp === \"function\" ? grantXp : null;\n\ndocument.getElementById(\"dailyQuestBtn\")?.addEventListener(\"click\", async () => {\n    if (!currentUser) return;\n    const day = questDayKey();\n    let v = { messages: 0, games: 0, claimed: false };\n    try {\n        const s = await get(ref(database, \"dailyQuests\/\" + currentUser.uid + \"\/\" + day));\n        if (s.exists()) v = s.val();\n    } catch (_) {}\n    alert(\"\ud83d\udccb G\u00fcnl\u00fck g\u00f6rev (\" + day + \")\\n\\nMesaj: \" + (v.messages || 0) + \"\/3\\nOyun: \" + (v.games || 0) + \"\/1\\n\u00d6d\u00fcl: 25 VC\\nDurum: \" + (v.claimed ? \"Al\u0131nd\u0131 \u2713\" : \"Devam ediyor\"));\n});\n\ndocument.getElementById(\"giftBtn\")?.addEventListener(\"click\", async () => {\n    if (!currentUser) return;\n    if ((currentProfile.coins || 0) < 5) return alert(\"En az 5 VC gerekli\");\n    const emojis = [\"\ud83c\udf81\", \"\ud83c\udf39\", \"\ud83d\udc8e\", \"\ud83e\udd84\", \"\ud83d\udd25\", \"\ud83d\udc51\"];\n    const g = emojis[Math.floor(Math.random() * emojis.length)];\n    try {\n        await addCoins(currentUser.uid, -5);\n        currentProfile.coins = (currentProfile.coins || 0) - 5;\n        let messagePath = \"messages\/general\";\n        if (activeChatType === \"private\" && activeChatId) messagePath = \"privateMessages\/\" + activeChatId;\n        else if (activeChatType === \"group\" && activeGroupId) messagePath = \"groupMessages\/\" + activeGroupId;\n        else if (activeChatType === \"club\" && activeChatId) messagePath = \"clubMessages\/\" + activeChatId;\n        else if (CHANNELS[activeChatType]) messagePath = CHANNELS[activeChatType].path;\n        await push(ref(database, messagePath), {\n            uid: currentUser.uid,\n            text: g + \" hediye g\u00f6nderdi!\",\n            gift: g,\n            timestamp: Date.now()\n        });\n        showGiftFly(g);\n        updateMyProfileDisplay();\n    } catch (e) { alert(e.message || e); }\n});\n\nfunction showGiftFly(emoji) {\n    const el = document.createElement(\"div\");\n    el.textContent = emoji;\n    el.style.cssText = \"position:fixed;left:50%;top:60%;font-size:64px;z-index:9999;pointer-events:none;transform:translate(-50%,0);transition:all 1.2s ease-out;opacity:1;\";\n    document.body.appendChild(el);\n    requestAnimationFrame(() => {\n        el.style.top = \"20%\";\n        el.style.opacity = \"0\";\n        el.style.transform = \"translate(-50%,-40px) scale(1.4)\";\n    });\n    setTimeout(() => el.remove(), 1300);\n}\n\ndocument.getElementById(\"storiesBtn\")?.addEventListener(\"click\", () => openStoriesUI());\nasync function openStoriesUI() {\n    if (!currentUser) return;\n    openGames();\n    const area = document.getElementById(\"activeGameArea\");\n    if (!area) return;\n    area.classList.remove(\"hidden\");\n    const list = document.getElementById(\"gamesListWrap\");\n    if (list) list.style.display = \"none\";\n    area.innerHTML = `<button class=\"gameBackBtn\" id=\"gameBackBtn\">\u2190 Geri<\/button>\n        <div class=\"gameStatus\">\ud83d\udcf8 Hik\u00e2yeler (24 saat)<\/div>\n        <textarea id=\"storyText\" maxlength=\"200\" placeholder=\"Metin...\" style=\"width:100%;min-height:60px;padding:10px;border:none;border-radius:8px;background:#1e1f22;color:#fff;\"><\/textarea>\n        <input id=\"storyUrl\" type=\"url\" placeholder=\"Opsiyonel g\u00f6rsel URL\" style=\"width:100%;padding:10px;border:none;border-radius:8px;background:#1e1f22;color:#fff;margin:8px 0;\">\n        <button class=\"bigBtn\" id=\"storyPost\">Payla\u015f<\/button>\n        <div id=\"storyFeed\" style=\"margin-top:12px;\"><\/div>`;\n    gameBack(area);\n    document.getElementById(\"storyPost\").onclick = async () => {\n        const text = (document.getElementById(\"storyText\").value || \"\").trim();\n        const url = (document.getElementById(\"storyUrl\").value || \"\").trim();\n        if (!text && !url) return alert(\"Bir \u015fey yaz\");\n        const id = push(ref(database, \"stories\")).key;\n        await set(ref(database, \"stories\/\" + id), {\n            uid: currentUser.uid, name: currentProfile.displayName, username: currentProfile.username,\n            text: text.slice(0, 200), image: url.slice(0, 500), at: Date.now(), expires: Date.now() + 86400000\n        });\n        alert(\"Hik\u00e2ye payla\u015f\u0131ld\u0131\");\n        openStoriesUI();\n    };\n    try {\n        const snap = await get(query(ref(database, \"stories\"), limitToLast(40)));\n        const box = document.getElementById(\"storyFeed\");\n        if (!snap.exists()) { box.innerHTML = `<div class=\"liveNote\">Hik\u00e2ye yok<\/div>`; return; }\n        const now = Date.now();\n        const items = Object.entries(snap.val()).filter(([, s]) => (s.expires || 0) > now).sort((a, b) => (b[1].at || 0) - (a[1].at || 0));\n        box.innerHTML = items.map(([, s]) =>\n            `<div style=\"background:#1e1f22;border-radius:10px;padding:12px;margin:8px 0;\">\n                <b>@${escapeHtml(s.username || s.name || \"?\")}<\/b>\n                <div style=\"margin-top:6px;\">${escapeHtml(s.text || \"\")}<\/div>\n                ${s.image ? `<img decoding=\"async\" src=\"${escapeHtml(s.image)}\" style=\"max-width:100%;border-radius:8px;margin-top:8px;\" onerror=\"this.remove()\">` : \"\"}\n                <div style=\"font-size:11px;color:#949ba4;margin-top:6px;\">${new Date(s.at).toLocaleString(\"tr-TR\")}<\/div>\n            <\/div>`\n        ).join(\"\") || `<div class=\"liveNote\">Aktif hik\u00e2ye yok<\/div>`;\n    } catch (e) {\n        document.getElementById(\"storyFeed\").innerHTML = `<div class=\"liveNote\">${escapeHtml(e.message || String(e))}<\/div>`;\n    }\n}\n\ndocument.getElementById(\"chanceGamesBtn\")?.addEventListener(\"click\", () => openChanceGames());\nfunction openChanceGames() {\n    openGames();\n    const area = document.getElementById(\"activeGameArea\");\n    if (!area) return;\n    area.classList.remove(\"hidden\");\n    const list = document.getElementById(\"gamesListWrap\");\n    if (list) list.style.display = \"none\";\n    area.innerHTML = `<button class=\"gameBackBtn\" id=\"gameBackBtn\">\u2190 Geri<\/button>\n        <div class=\"gameStatus\">\ud83c\udfb0 \u015eans oyunlar\u0131<\/div>\n        <p style=\"color:#b5bac1;font-size:13px;\">Bakiyen: ${(currentProfile.coins || 0)} VC<\/p>\n        <button class=\"bigBtn\" id=\"cgCoin\">Yaz\u0131-tura (10 VC)<\/button>\n        <button class=\"bigBtn\" id=\"cgDice\" style=\"margin-top:8px;\">Zar (5 VC) \u2014 6 gelirse x5<\/button>\n        <button class=\"bigBtn\" id=\"cgSlot\" style=\"margin-top:8px;\">Mini slot (15 VC)<\/button>\n        <div id=\"cgResult\" class=\"gameStatus\" style=\"margin-top:12px;\"><\/div>`;\n    gameBack(area);\n    const res = document.getElementById(\"cgResult\");\n    document.getElementById(\"cgCoin\").onclick = async () => {\n        if ((currentProfile.coins || 0) < 10) return alert(\"Yetersiz VC\");\n        await addCoins(currentUser.uid, -10);\n        currentProfile.coins -= 10;\n        const win = Math.random() < 0.48;\n        if (win) { await addCoins(currentUser.uid, 20); currentProfile.coins += 20; res.textContent = \"\ud83c\udf89 Yaz\u0131! +20 VC\"; }\n        else res.textContent = \"\ud83d\ude22 Tura \u2014 kaybettin\";\n        updateMyProfileDisplay();\n    };\n    document.getElementById(\"cgDice\").onclick = async () => {\n        if ((currentProfile.coins || 0) < 5) return alert(\"Yetersiz VC\");\n        await addCoins(currentUser.uid, -5);\n        currentProfile.coins -= 5;\n        const n = 1 + Math.floor(Math.random() * 6);\n        if (n === 6) { await addCoins(currentUser.uid, 25); currentProfile.coins += 25; res.textContent = \"\ud83c\udfb2 6! +25 VC\"; }\n        else res.textContent = \"\ud83c\udfb2 \" + n + \" \u2014 olmad\u0131\";\n        updateMyProfileDisplay();\n    };\n    document.getElementById(\"cgSlot\").onclick = async () => {\n        if ((currentProfile.coins || 0) < 15) return alert(\"Yetersiz VC\");\n        await addCoins(currentUser.uid, -15);\n        currentProfile.coins -= 15;\n        const sym = [\"\ud83c\udf52\", \"\ud83c\udf4b\", \"\u2b50\", \"\ud83d\udc8e\", \"7\ufe0f\u20e3\"];\n        const a = sym[Math.floor(Math.random() * sym.length)];\n        const b = sym[Math.floor(Math.random() * sym.length)];\n        const c = sym[Math.floor(Math.random() * sym.length)];\n        let gain = 0;\n        if (a === b && b === c) gain = a === \"\ud83d\udc8e\" ? 100 : 45;\n        else if (a === b || b === c) gain = 20;\n        if (gain) { await addCoins(currentUser.uid, gain); currentProfile.coins += gain; }\n        res.textContent = a + \" \" + b + \" \" + c + (gain ? \" \u2192 +\" + gain + \" VC\" : \" \u2192 bo\u015f\");\n        updateMyProfileDisplay();\n    };\n}\n\ndocument.getElementById(\"seasonBtn\")?.addEventListener(\"click\", async () => {\n    const wk = weekKey();\n    try {\n        const s = await get(ref(database, \"season\/\" + wk));\n        const rows = s.exists() ? Object.entries(s.val()).map(([uid, v]) => ({ uid, ...v })).sort((a, b) => (b.pts || 0) - (a.pts || 0)).slice(0, 15) : [];\n        const my = rows.find(r => r.uid === currentUser.uid);\n        alert(\"\ud83c\udfc5 Haftal\u0131k sezon \" + wk + \"\\n\\n\" +\n            (rows.length ? rows.map((r, i) => (i + 1) + \". \" + (r.name || \"?\") + \" \u2014 \" + (r.pts || 0) + \"p\").join(\"\\n\") : \"Hen\u00fcz puan yok\") +\n            (my ? \"\\n\\nSen: \" + (my.pts || 0) + \"p\" : \"\") +\n            \"\\n\\nMesaj\/oyun ile puan birikir. Hafta bitince reset + rozet.\");\n    } catch (e) { alert(e.message || e); }\n});\n\nasync function addSeasonPts(n) {\n    if (!currentUser || !n) return;\n    const wk = weekKey();\n    try {\n        const r = ref(database, \"season\/\" + wk + \"\/\" + currentUser.uid);\n        const s = await get(r);\n        const pts = (s.exists() ? Number(s.val().pts) || 0 : 0) + n;\n        await set(r, { pts, name: currentProfile.displayName, at: Date.now() });\n        if (pts >= 100) {\n            await update(ref(database, \"users\/\" + currentUser.uid + \"\/badges\"), { seasonChamp: true }).catch(() => {});\n        }\n    } catch (_) {}\n}\n\n\/\/ Hesap sil (ayarlar i\u00e7ine ba\u011fla)\nasync function deleteMyAccount() {\n    if (!currentUser) return;\n    if (!confirm(\"Hesab\u0131n silinecek. Emin misin?\")) return;\n    if (!confirm(\"Bu i\u015flem geri al\u0131namaz. Son kez onayla.\")) return;\n    const uid = currentUser.uid;\n    try {\n        const uname = currentProfile && currentProfile.usernameKey;\n        if (uname) await remove(ref(database, \"usernames\/\" + uname)).catch(() => {});\n        await remove(ref(database, \"users\/\" + uid)).catch(() => {});\n        await remove(ref(database, \"status\/\" + uid)).catch(() => {});\n        await signOut(auth);\n        alert(\"Hesap verileri silindi. Yeniden kay\u0131t olabilirsin.\");\n        location.reload();\n    } catch (e) {\n        alert(\"Silinemedi: \" + (e.message || e) + \"\\nFirebase Auth hesab\u0131 konsoldan da silinebilir.\");\n    }\n}\n\n\/* =========================================================\n   GEL\u0130\u015eM\u0130\u015e \u00d6ZELL\u0130KLER (ses filtre, matchmaking, secret, pet, combo...)\n========================================================= *\/\n(function initAdvancedFeatures() {\n    \/\/ --- Markdown ara\u00e7 \u00e7ubu\u011fu ---\n    document.querySelectorAll(\"#editorBar [data-md]\").forEach(btn => {\n        btn.onclick = () => {\n            const md = btn.dataset.md;\n            const el = messageInput;\n            const a = el.selectionStart, b = el.selectionEnd;\n            const sel = el.value.slice(a, b) || \"metin\";\n            el.value = el.value.slice(0, a) + md + sel + md + el.value.slice(b);\n            el.focus();\n            el.dispatchEvent(new Event(\"input\"));\n        };\n    });\n    document.getElementById(\"quoteBtn\")?.addEventListener(\"click\", () => {\n        const el = messageInput;\n        el.value = \"> \" + (el.value || \"al\u0131nt\u0131\");\n        el.dispatchEvent(new Event(\"input\"));\n    });\n    document.getElementById(\"secretBtn\")?.addEventListener(\"click\", () => {\n        const el = messageInput;\n        if (!el.value.startsWith(\"\/secret \")) el.value = \"\/secret \" + el.value;\n        el.focus();\n    });\n\n    \/\/ --- S\u00fcr\u00fckle-b\u0131rak resim ---\n    const dropZone = document.getElementById(\"mainChatArea\");\n    if (dropZone) {\n        [\"dragenter\", \"dragover\"].forEach(ev => dropZone.addEventListener(ev, e => {\n            e.preventDefault(); dropZone.classList.add(\"dragOverChat\");\n        }));\n        [\"dragleave\", \"drop\"].forEach(ev => dropZone.addEventListener(ev, e => {\n            e.preventDefault(); dropZone.classList.remove(\"dragOverChat\");\n        }));\n        dropZone.addEventListener(\"drop\", async e => {\n            const f = e.dataTransfer?.files?.[0];\n            if (!f || !f.type.startsWith(\"image\/\")) return;\n            try {\n                pendingImageData = await compressImage(f);\n                alert(\"Resim eklendi \u2014 G\u00f6nder'e bas.\");\n            } catch (err) { alert(err.message || err); }\n        });\n    }\n\n    \/\/ --- Yazma ritmi sesi ---\n    let typeAudioCtx = null;\n    messageInput?.addEventListener(\"keydown\", e => {\n        if (e.key.length !== 1 && e.key !== \"Backspace\") return;\n        try {\n            if (!typeAudioCtx) typeAudioCtx = new (window.AudioContext || window.webkitAudioContext)();\n            const o = typeAudioCtx.createOscillator();\n            const g = typeAudioCtx.createGain();\n            o.frequency.value = 400 + Math.random() * 200;\n            g.gain.value = 0.03;\n            o.connect(g); g.connect(typeAudioCtx.destination);\n            o.start();\n            g.gain.exponentialRampToValueAtTime(0.001, typeAudioCtx.currentTime + 0.05);\n            o.stop(typeAudioCtx.currentTime + 0.05);\n        } catch (_) {}\n    });\n\n    \/\/ --- Easter egg sand\u0131k ---\n    function spawnEgg() {\n        const old = document.getElementById(\"easterEgg\");\n        if (old) old.remove();\n        const egg = document.createElement(\"div\");\n        egg.id = \"easterEgg\";\n        egg.title = \"Hazine!\";\n        egg.style.left = (10 + Math.random() * 80) + \"vw\";\n        egg.style.top = (15 + Math.random() * 70) + \"vh\";\n        egg.onclick = async () => {\n            egg.remove();\n            try {\n                const xp = (currentProfile.xp || 0) + 25;\n                await update(ref(database, \"users\/\" + currentUser.uid), { xp });\n                currentProfile.xp = xp;\n                await addCoins(currentUser.uid, 5);\n                updateMyProfileDisplay();\n                alert(\"\ud83c\udf81 Hazine buldun! +25 XP \u00b7 +5 \ud83e\ude99\");\n            } catch (_) { alert(\"Hazine bulundu!\"); }\n        };\n        document.body.appendChild(egg);\n        setTimeout(() => egg.remove(), 45000);\n    }\n    setInterval(spawnEgg, 120000);\n    setTimeout(spawnEgg, 15000);\n\n    \/\/ --- Kombo takibi ---\n    window._lastComboWord = \"\";\n    window._comboCount = 0;\n    window._comboUsers = new Set();\n})();\n\nfunction checkMessageCombo(text, uid) {\n    const w = (text || \"\").trim().toLowerCase();\n    if (!w || w.length > 20) { window._comboCount = 0; return; }\n    if (w === window._lastComboWord) {\n        window._comboUsers.add(uid);\n        window._comboCount++;\n        if (window._comboCount >= 5 && window._comboUsers.size >= 3) {\n            const fx = document.createElement(\"div\");\n            fx.className = \"comboFx\";\n            document.body.appendChild(fx);\n            setTimeout(() => fx.remove(), 1200);\n            window._comboCount = 0;\n            window._comboUsers.clear();\n            if (currentUser) addCoins(currentUser.uid, 2).catch(() => {});\n        }\n    } else {\n        window._lastComboWord = w;\n        window._comboCount = 1;\n        window._comboUsers = new Set([uid]);\n    }\n}\n\n\/\/ Gizli mesaj komutu\nasync function handleSecretCommand(text) {\n    if (!text.toLowerCase().startsWith(\"\/secret \")) return false;\n    const secret = text.slice(8).trim();\n    if (!secret) return true;\n    let messagePath = \"messages\/general\";\n    if (activeChatType === \"private\" && activeChatId) messagePath = \"privateMessages\/\" + activeChatId;\n    else if (activeChatType === \"group\" && activeGroupId) messagePath = \"groupMessages\/\" + activeGroupId;\n    else if (CHANNELS[activeChatType]) messagePath = CHANNELS[activeChatType].path;\n    await push(ref(database, messagePath), {\n        uid: currentUser.uid,\n        text: secret,\n        secret: true,\n        timestamp: Date.now()\n    });\n    return true;\n}\n\n\/\/ Matchmaking kuyru\u011fu\nasync function joinMatchmaking(gameType) {\n    if (!currentUser) return;\n    const qRef = ref(database, \"matchQueue\/\" + gameType);\n    await set(ref(database, \"matchQueue\/\" + gameType + \"\/\" + currentUser.uid), {\n        uid: currentUser.uid,\n        name: currentProfile.displayName,\n        at: Date.now()\n    });\n    alert(\"E\u015fle\u015fme aran\u0131yor...\");\n    const unsub = onValue(qRef, async snap => {\n        if (!snap.exists()) return;\n        const players = Object.values(snap.val()).filter(p => p.uid !== currentUser.uid);\n        if (!players.length) return;\n        const other = players[0];\n        unsub();\n        await remove(ref(database, \"matchQueue\/\" + gameType + \"\/\" + currentUser.uid));\n        await remove(ref(database, \"matchQueue\/\" + gameType + \"\/\" + other.uid));\n        const code = Math.random().toString(36).substring(2, 8).toUpperCase();\n        if (gameType === \"rps\") {\n            await set(ref(database, \"minigames\/rps\/\" + code), {\n                host: currentUser.uid, hostName: currentProfile.displayName,\n                guest: other.uid, guestName: other.name, status: \"playing\", createdAt: Date.now()\n            });\n            alert(\"Rakip bulundu! Oda: \" + code + \"\\nOyunlar \u2192 Kat\u0131l ile kodu kullanabilirler.\");\n        } else if (gameType === \"xox\") {\n            await set(ref(database, \"minigames\/xox\/\" + code), {\n                host: currentUser.uid, hostName: currentProfile.displayName,\n                guest: other.uid, guestName: other.name, status: \"playing\",\n                board: Array(9).fill(\"\"), turn: \"X\", createdAt: Date.now()\n            });\n            alert(\"Rakip bulundu! XOX oda: \" + code);\n        } else {\n            alert(\"Rakip: \" + other.name + \" \u00b7 Oda kodu: \" + code);\n        }\n    });\n    setTimeout(() => { try { unsub(); remove(ref(database, \"matchQueue\/\" + gameType + \"\/\" + currentUser.uid)); } catch (_) {} }, 60000);\n}\n\n\/\/ Ses filtreleri (Web Audio)\nlet voiceAudioCtx = null, voicePitchNode = null, voiceFilterMode = 0;\nconst VOICE_FILTERS = [\"Kapal\u0131\", \"Helyum\", \"Robot\", \"Canavar\"];\nfunction applyVoiceFilter(stream) {\n    try {\n        if (!stream) return stream;\n        voiceAudioCtx = voiceAudioCtx || new (window.AudioContext || window.webkitAudioContext)();\n        const src = voiceAudioCtx.createMediaStreamSource(stream);\n        const dest = voiceAudioCtx.createMediaStreamDestination();\n        \/\/ basit pitch: playbackRate sim\u00fclasyonu i\u00e7in biquad + gain zinciri\n        const filter = voiceAudioCtx.createBiquadFilter();\n        const gain = voiceAudioCtx.createGain();\n        if (voiceFilterMode === 1) { \/\/ helyum\n            filter.type = \"highpass\"; filter.frequency.value = 800; gain.gain.value = 1.2;\n        } else if (voiceFilterMode === 2) { \/\/ robot\n            filter.type = \"bandpass\"; filter.frequency.value = 1000; filter.Q.value = 5; gain.gain.value = 1.4;\n        } else if (voiceFilterMode === 3) { \/\/ canavar\n            filter.type = \"lowpass\"; filter.frequency.value = 400; gain.gain.value = 1.5;\n        } else {\n            filter.type = \"allpass\"; filter.frequency.value = 1000; gain.gain.value = 1;\n        }\n        src.connect(filter); filter.connect(gain); gain.connect(dest);\n        \/\/ orijinal track'leri de koru - filtered stream d\u00f6nd\u00fcr\n        const mixed = new MediaStream();\n        dest.stream.getAudioTracks().forEach(t => mixed.addTrack(t));\n        return mixed;\n    } catch (_) { return stream; }\n}\n\nlet ambientAudio = null;\nfunction toggleAmbient() {\n    if (ambientAudio && !ambientAudio.paused) {\n        ambientAudio.pause();\n        ambientAudio = null;\n        return;\n    }\n    \/\/ lo-fi benzeri basit noise yerine online k\u0131sa loop (opsiyonel)\n    ambientAudio = new Audio(\"https:\/\/www.soundhelix.com\/examples\/mp3\/SoundHelix-Song-1.mp3\");\n    ambientAudio.loop = true;\n    ambientAudio.volume = 0.15;\n    ambientAudio.play().catch(() => alert(\"Ortam sesi \u00e7al\u0131namad\u0131\"));\n}\n\n\/\/ Sanal evcil hayvan\nfunction petStage(xp) {\n    if (xp < 50) return { emoji: \"\ud83e\udd5a\", name: \"Yumurta\", need: 50 };\n    if (xp < 150) return { emoji: \"\ud83d\udc23\", name: \"Yavru Vega\", need: 150 };\n    if (xp < 400) return { emoji: \"\ud83d\udc25\", name: \"Vega Bot\", need: 400 };\n    if (xp < 800) return { emoji: \"\ud83e\udd85\", name: \"Uzay Ku\u015fu\", need: 800 };\n    return { emoji: \"\ud83d\udc09\", name: \"Efsane Ejder\", need: null };\n}\n\nfunction renderPetHtml(xp) {\n    const p = petStage(xp || 0);\n    return `<div class=\"petBox\"><div style=\"font-size:48px\">${p.emoji}<\/div>\n        <div><b>${p.name}<\/b><\/div>\n        <div style=\"font-size:12px;color:#949ba4;margin-top:4px;\">Online ol, yaz, oyna \u2014 b\u00fcy\u00fcs\u00fcn${p.need ? \" \u00b7 sonraki: \" + p.need + \" XP\" : \"\"}<\/div><\/div>`;\n}\n\n\/\/ G\u00f6rsel anket\nasync function createVisualPoll(question, options) {\n    const id = push(ref(database, \"polls\")).key;\n    await set(ref(database, \"polls\/\" + id), {\n        q: question, options, votes: {}, by: currentUser.uid, at: Date.now()\n    });\n    let messagePath = CHANNELS[activeChatType] ? CHANNELS[activeChatType].path : \"messages\/general\";\n    await push(ref(database, messagePath), {\n        uid: currentUser.uid,\n        text: \"\ud83d\udcca ANKET: \" + question + \"\\n\" + options.map((o, i) => (i + 1) + \") \" + o).join(\"\\n\") + \"\\n(Oy: \/vote \" + id.slice(-6) + \" 1-4)\",\n        timestamp: Date.now(),\n        pollId: id\n    });\n    return id;\n}\n\n\/\/ Davet kodu\nasync function createInvite(groupId) {\n    const code = Math.random().toString(36).substring(2, 10).toUpperCase();\n    await set(ref(database, \"invites\/\" + code), {\n        groupId: groupId || null,\n        by: currentUser.uid,\n        expires: Date.now() + 24 * 3600 * 1000\n    });\n    return code;\n}\n\n\/\/ Hikaye zinciri\nasync function startStoryChain() {\n    const starters = [\n        \"Bir sabah uyand\u0131\u011f\u0131mda kendimi bir bilgisayar\u0131n i\u00e7inde buldum...\",\n        \"Uzay istasyonunun kap\u0131s\u0131 aniden a\u00e7\u0131ld\u0131 ve...\",\n        \"Sohbete yaz\u0131lan her mesaj asl\u0131nda bir b\u00fcy\u00fcyd\u00fc...\"\n    ];\n    const line = starters[Math.floor(Math.random() * starters.length)];\n    await set(ref(database, \"story\/current\"), {\n        lines: [{ text: line, by: \"sistem\", at: Date.now() }],\n        turn: null,\n        at: Date.now()\n    });\n    await push(ref(database, \"messages\/general\"), {\n        uid: currentUser.uid,\n        text: \"\ud83d\udcd6 H\u0130KAYE BA\u015eLADI:\\n_\" + line + \"_\\nDevam etmek i\u00e7in: \/story c\u00fcmlen\",\n        timestamp: Date.now()\n    });\n}\n\n\/\/ \/roll g\u00f6rsel\nfunction showDiceAnimation(n) {\n    const faces = [\"\u2680\", \"\u2681\", \"\u2682\", \"\u2683\", \"\u2684\", \"\u2685\"];\n    const el = document.createElement(\"div\");\n    el.className = \"diceAnim\";\n    el.textContent = faces[(n - 1) % 6] || \"\ud83c\udfb2\";\n    el.style.cssText = \"position:fixed;left:50%;top:40%;transform:translate(-50%,-50%);z-index:9999;font-size:64px;\";\n    document.body.appendChild(el);\n    setTimeout(() => el.remove(), 900);\n}\n\n\/* Mobil ekran y\u00fcksekli\u011fi + cihaz tipi (k\u00fc\u00e7\u00fck g\u00f6r\u00fcnme d\u00fczeltmesi) *\/\n(function setupResponsiveViewport() {\n    function apply() {\n        const h = window.visualViewport ? window.visualViewport.height : window.innerHeight;\n        document.documentElement.style.setProperty(\"--app-height\", h + \"px\");\n        document.documentElement.style.setProperty(\"--vh\", (h * 0.01) + \"px\");\n        const w = window.innerWidth;\n        const coarse = window.matchMedia(\"(pointer: coarse)\").matches;\n        const touch = navigator.maxTouchPoints > 0 || coarse;\n        document.body.classList.toggle(\"is-mobile\", w <= 760 || (touch && w <= 1024));\n        document.body.classList.toggle(\"is-tablet\", w > 760 && w <= 1024);\n        document.body.classList.toggle(\"is-desktop\", w > 1024);\n        document.body.classList.toggle(\"is-touch\", touch);\n        \/\/ Mobilde aray\u00fcz\u00fc b\u00fcy\u00fct (k\u00fc\u00e7\u00fck ekran hissini gider)\n        if (w <= 360) document.documentElement.style.setProperty(\"--ui-scale\", \"1.15\");\n        else if (w <= 760) document.documentElement.style.setProperty(\"--ui-scale\", \"1.22\");\n        else if (w <= 1024) document.documentElement.style.setProperty(\"--ui-scale\", \"1.1\");\n        else document.documentElement.style.setProperty(\"--ui-scale\", \"1\");\n    }\n    apply();\n    window.addEventListener(\"resize\", apply);\n    window.addEventListener(\"orientationchange\", () => setTimeout(apply, 150));\n    if (window.visualViewport) {\n        window.visualViewport.addEventListener(\"resize\", apply);\n        window.visualViewport.addEventListener(\"scroll\", apply);\n    }\n})();\n\n\/* Kul\u00fcp odalar\u0131 *\/\ndocument.getElementById(\"createClubBtn\")?.addEventListener(\"click\", async () => {\n    const name = prompt(\"Kul\u00fcp ad\u0131 (kal\u0131c\u0131 oda):\");\n    if (!name || !name.trim()) return;\n    try {\n        const id = push(ref(database, \"clubs\")).key;\n        const meta = {\n            name: name.trim().slice(0, 40),\n            createdBy: currentUser.uid,\n            members: { [currentUser.uid]: true },\n            createdAt: Date.now()\n        };\n        await set(ref(database, \"clubs\/\" + id), meta);\n        await set(ref(database, \"userClubs\/\" + currentUser.uid + \"\/\" + id), { name: meta.name, updatedAt: Date.now() });\n        alert(\"Kul\u00fcp olu\u015fturuldu: \" + meta.name);\n        loadClubs();\n        openClub(id, meta.name);\n    } catch (e) { alert(e.message || e); }\n});\n\nfunction loadClubs() {\n    const box = document.getElementById(\"clubsList\");\n    if (!box || !currentUser) return;\n    onValue(ref(database, \"userClubs\/\" + currentUser.uid), snap => {\n        box.innerHTML = \"\";\n        if (!snap.exists()) return;\n        Object.entries(snap.val()).forEach(([id, info]) => {\n            const btn = document.createElement(\"button\");\n            btn.className = \"channelButton\";\n            btn.textContent = \"\ud83c\udfe0 \" + (info.name || \"Kul\u00fcp\");\n            btn.onclick = () => openClub(id, info.name || \"Kul\u00fcp\");\n            box.appendChild(btn);\n        });\n    });\n}\n\nasync function openClub(clubId, name) {\n    activeChatType = \"club\";\n    activeChatId = clubId;\n    activePrivateUser = null;\n    activeGroupId = null;\n    document.querySelectorAll(\".channelButton\").forEach(b => b.classList.remove(\"active\"));\n    mainChatArea.style.display = \"flex\";\n    hideExtraScreens();\n    shortsScreen.classList.remove(\"active\");\n    document.getElementById(\"gamesScreen\")?.classList.remove(\"active\");\n    document.getElementById(\"chatTitle\").textContent = \"\ud83c\udfe0 \" + name;\n    document.getElementById(\"chatSubtitle\").textContent = \"Kul\u00fcp odas\u0131\";\n    messageInput.placeholder = name + \" kul\u00fcb\u00fcne yaz...\";\n    startMessageStream(\"clubMessages\/\" + clubId);\n    closeSidebar();\n}\n\n\/\/ club mesaj path i\u00e7in sendMessage'a ek\nconst _origSendClub = null;\n\ndocument.getElementById(\"wallpaperBtn\")?.addEventListener(\"click\", () => {\n    openSettings();\n    setTimeout(() => document.getElementById(\"chatBgSelect\")?.focus(), 200);\n});\n\ndocument.getElementById(\"duelLinkBtn\")?.addEventListener(\"click\", async () => {\n    const game = prompt(\"Oyun: xox \/ rps \/ uno\", \"xox\");\n    if (!game) return;\n    const code = Math.random().toString(36).substring(2, 8).toUpperCase();\n    try {\n        await set(ref(database, \"minigames\/\" + game + \"\/\" + code), {\n            host: currentUser.uid, hostName: currentProfile.displayName,\n            status: \"waiting\", createdAt: Date.now(), duel: true\n        });\n        const link = location.origin + location.pathname + \"?duel=\" + encodeURIComponent(game) + \"&code=\" + code;\n        try { await navigator.clipboard.writeText(link); } catch (_) {}\n        alert(\"1v1 d\u00fcello linki kopyaland\u0131:\\n\" + link + \"\\n\\nArkada\u015f\u0131na g\u00f6nder.\");\n    } catch (e) { alert(e.message || e); }\n});\n\n\/\/ ?duel= a\u00e7\u0131l\u0131\u015f\n(function checkDuelLink() {\n    try {\n        const u = new URL(location.href);\n        const g = u.searchParams.get(\"duel\");\n        const c = u.searchParams.get(\"code\");\n        if (g && c) {\n            window._pendingDuel = { game: g, code: c };\n        }\n    } catch (_) {}\n})();\n\n\/* PWA \u2014 Service Worker kayd\u0131 *\/\nif (\"serviceWorker\" in navigator) {\n    window.addEventListener(\"load\", () => {\n        navigator.serviceWorker.register(\"\/sw.js\").then((reg) => {\n            console.log(\"PWA SW kay\u0131tl\u0131\", reg.scope);\n        }).catch((e) => console.warn(\"SW kay\u0131t hatas\u0131:\", e));\n    });\n}\n\/\/ Android \"Uygulamay\u0131 y\u00fckle\" olay\u0131\nlet deferredPwaPrompt = null;\nwindow.addEventListener(\"beforeinstallprompt\", (e) => {\n    e.preventDefault();\n    deferredPwaPrompt = e;\n    const btn = document.getElementById(\"pwaInstallBtn\");\n    if (btn) btn.classList.remove(\"hidden\");\n});\nwindow.installVegaMediaPwa = async function () {\n    if (!deferredPwaPrompt) {\n        alert(\"Taray\u0131c\u0131 y\u00fckleme \u00f6nermiyor.\\nAndroid Chrome: Men\u00fc \u2192 Ana ekrana ekle \/ Uygulamay\u0131 y\u00fckle\\niPhone Safari: Payla\u015f \u2192 Ana Ekrana Ekle\");\n        return;\n    }\n    deferredPwaPrompt.prompt();\n    await deferredPwaPrompt.userChoice;\n    deferredPwaPrompt = null;\n};\n<\/script>\n<\/body>\n<\/html>\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t","protected":false},"excerpt":{"rendered":"<p>VegaMedia Chat VEGAMEDIA Giri\u015f Yap Kullan\u0131c\u0131 ad\u0131 \u015eifre Giri\u015f Yap Hesab\u0131n yok mu? Hesap olu\u015ftur Hesap Olu\u015ftur Kullan\u0131c\u0131 ad\u0131 0 \/ 20 \u015eifre \u015eifre tekrar Hesap Olu\u015ftur Zaten hesab\u0131n var m\u0131? Giri\u015f yap VEGAMEDIA \u2715 KANALLAR # genel # oyun # spor # m\u00fczik # teknoloji # giyotin \u2694\ufe0f # CAPS LOCK \u25b6 Shorts \ud83c\udfae [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"elementor_canvas","meta":{"footnotes":""},"class_list":["post-209","page","type-page","status-publish","hentry"],"_links":{"self":[{"href":"https:\/\/urasuzay.com\/index.php\/wp-json\/wp\/v2\/pages\/209","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/urasuzay.com\/index.php\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/urasuzay.com\/index.php\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/urasuzay.com\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/urasuzay.com\/index.php\/wp-json\/wp\/v2\/comments?post=209"}],"version-history":[{"count":142,"href":"https:\/\/urasuzay.com\/index.php\/wp-json\/wp\/v2\/pages\/209\/revisions"}],"predecessor-version":[{"id":374,"href":"https:\/\/urasuzay.com\/index.php\/wp-json\/wp\/v2\/pages\/209\/revisions\/374"}],"wp:attachment":[{"href":"https:\/\/urasuzay.com\/index.php\/wp-json\/wp\/v2\/media?parent=209"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}