Lompat ke isi

MediaWiki:Common.js: Perbedaan antara revisi

Dari Mippedia Data, basis data terbuka
Tidak ada ringkasan suntingan
Tanda: Suntingan perangkat seluler Suntingan peramban seluler
Tidak ada ringkasan suntingan
Tanda: Suntingan perangkat seluler Suntingan peramban seluler
Baris 1: Baris 1:
/**
/**
  * ====================================================================
  * ====================================================================
  * MIPPEDIA DATA - ADVANCED STRUCTURED DATA SYSTEM (V8.0 TITANIUM)
  * MIPPEDIA DATA - ADVANCED STRUCTURED DATA SYSTEM (V8.0 ULTIMATE PRO)
  * Fitur: 25+ Fitur Baru, Collapsible References, Direct Link Button,
  * Fitur Baru: Accordion References, Visit Site Button, Toast Notifs,
  * Dark Mode, Toast Notifications, Drag & Drop, Export CSV, Auto-Fill
  * Auto-Save Drafts, Reorder Data (Up/Down), File Export/Import,  
* 30+ Social Platforms, Glassmorphism UI, Mobile Perfect Animations.
  * ====================================================================
  * ====================================================================
  */
  */
Baris 19: Baris 20:
         var isLocked = false;
         var isLocked = false;
         var api = new mw.Api();
         var api = new mw.Api();
        var isDarkMode = localStorage.getItem('md-dark-mode') === 'true';


         // 1. DATA MASTER PLATFORM MEDIA SOSIAL & MUSIK (+5 Baru)
         // 1. DATA MASTER PLATFORM MEDIA SOSIAL & MUSIK (DITAMBAH BANYAK PLATFORM)
         var SOCIAL_PLATFORMS = {
         var SOCIAL_PLATFORMS = {
             applemusic: { name: 'Apple Music', base: 'https://music.apple.com/artist/', color: '#fc3c44', icon: '<svg width="13" height="13" viewBox="0 0 24 24" fill="currentColor"><path d="M12 2C6.477 2 2 6.477 2 12s4.477 10 10 10 10-4.477 10-10S17.523 2 12 2zm3.32 12.383c-.328.232-.82.418-1.32.418-1.238 0-1.922-.828-1.922-2.191v-4.14l4.312-.868v1.398l-2.91.586v2.805c0 .734.336 1.148.977 1.148.336 0 .617-.094.863-.258v1.102z"/></svg>' },
             applemusic: { name: 'Apple Music', base: 'https://music.apple.com/artist/', color: '#fc3c44', icon: '<svg width="13" height="13" viewBox="0 0 24 24" fill="currentColor"><path d="M12 2C6.477 2 2 6.477 2 12s4.477 10 10 10 10-4.477 10-10S17.523 2 12 2zm3.32 12.383c-.328.232-.82.418-1.32.418-1.238 0-1.922-.828-1.922-2.191v-4.14l4.312-.868v1.398l-2.91.586v2.805c0 .734.336 1.148.977 1.148.336 0 .617-.094.863-.258v1.102z"/></svg>' },
             spotify: { name: 'Spotify', base: 'https://open.spotify.com/artist/', color: '#1db954', icon: '<svg width="13" height="13" viewBox="0 0 24 24" fill="currentColor"><path d="M12 2C6.477 2 2 6.477 2 12s4.477 10 10 10 10-4.477 10-10S17.523 2 12 2zm4.586 14.424c-.18.295-.563.387-.857.207-2.35-1.434-5.308-1.758-8.793-.963-.335.077-.67-.133-.746-.468-.077-.334.132-.67.467-.745 3.816-.87 7.092-.493 9.72 1.112.294.18.386.563.209.857zm1.213-2.71c-.226.368-.703.483-1.07.258-2.688-1.652-6.785-2.13-9.965-1.164-.413.125-.85-.108-.975-.522-.125-.413.108-.85.522-.975 3.633-1.102 8.157-.568 11.23 1.332.368.226.483.703.258 1.071zm.14-2.827c-3.225-1.915-8.54-2.092-11.614-1.16-.503.153-1.037-.133-1.19-.636-.152-.503.133-1.037.636-1.19 3.532-1.072 9.404-.865 13.115 1.338.45.267.598.85.33 1.3-.267.45-.85.598-1.3.33z"/></svg>' },
             spotify: { name: 'Spotify', base: 'https://open.spotify.com/artist/', color: '#1db954', icon: '<svg width="13" height="13" viewBox="0 0 24 24" fill="currentColor"><path d="M12 2C6.477 2 2 6.477 2 12s4.477 10 10 10 10-4.477 10-10S17.523 2 12 2zm4.586 14.424c-.18.295-.563.387-.857.207-2.35-1.434-5.308-1.758-8.793-.963-.335.077-.67-.133-.746-.468-.077-.334.132-.67.467-.745 3.816-.87 7.092-.493 9.72 1.112.294.18.386.563.209.857zm1.213-2.71c-.226.368-.703.483-1.07.258-2.688-1.652-6.785-2.13-9.965-1.164-.413.125-.85-.108-.975-.522-.125-.413.108-.85.522-.975 3.633-1.102 8.157-.568 11.23 1.332.368.226.483.703.258 1.071zm.14-2.827c-3.225-1.915-8.54-2.092-11.614-1.16-.503.153-1.037-.133-1.19-.636-.152-.503.133-1.037.636-1.19 3.532-1.072 9.404-.865 13.115 1.338.45.267.598.85.33 1.3-.267.45-.85.598-1.3.33z"/></svg>' },
             soundcloud: { name: 'SoundCloud', base: 'https://soundcloud.com/', color: '#ff5500', icon: '<svg width="13" height="13" viewBox="0 0 24 24" fill="currentColor"><path d="M1.175 12.225c-.062 0-.115.053-.115.116v4.636c0 .062.053.115.115.115h.411c.063 0 .116-.053.116-.115v-4.636c0-.063-.053-.116-.116-.116h-.411zm1.312-1.28c-.062 0-.115.052-.115.115v6.52c0 .063.053.115.115.115h.43c.062 0 .115-.052.115-.115v-6.52c0-.063-.053-.115-.115-.115h-.43zm1.33-1.258c-.063 0-.115.052-.115.115v8.322c0 .063.052.115.115.115h.43c.063 0 .115-.052.115-.115V9.802c0-.063-.052-.115-.115-.115h-.43zm1.33-.86c-.063 0-.115.053-.115.116v9.542c0 .063.052.115.115.115h.43c.063 0 .115-.052.115-.115V8.942c0-.063-.052-.116-.115-.116h-.43zm21.43 3.652c-.413 0-.802.08-1.157.228-.312-2.73-2.613-4.858-5.422-4.858-1.08 0-2.083.315-2.928.858-.2-.702-.592-1.332-1.12-1.826-.78-.727-1.812-1.13-2.882-1.13-.815 0-1.6.236-2.272.684v10.822c0 .063.052.115.115.115h15.666c1.666 0 3.018-1.352 3.018-3.018 0-1.666-1.352-3.018-3.018-3.018z"/></svg>' },
             soundcloud: { name: 'SoundCloud', base: 'https://soundcloud.com/', color: '#ff5500', icon: '<svg width="13" height="13" viewBox="0 0 24 24" fill="currentColor"><path d="M1.175 12.225c-.062 0-.115.053-.115.116v4.636c0 .062.053.115.115.115h.411c.063 0 .116-.053.116-.115v-4.636c0-.063-.053-.116-.116-.116h-.411zm1.312-1.28c-.062 0-.115.052-.115.115v6.52c0 .063.053.115.115.115h.43c.062 0 .115-.052.115-.115v-6.52c0-.063-.053-.115-.115-.115h-.43zm1.33-1.258c-.063 0-.115.052-.115.115v8.322c0 .063.052.115.115.115h.43c.063 0 .115-.052.115-.115V9.802c0-.063-.052-.115-.115-.115h-.43zm1.33-.86c-.063 0-.115.053-.115.116v9.542c0 .063.052.115.115.115h.43c.063 0 .115-.052.115-.115V8.942c0-.063-.052-.116-.115-.116h-.43zm21.43 3.652c-.413 0-.802.08-1.157.228-.312-2.73-2.613-4.858-5.422-4.858-1.08 0-2.083.315-2.928.858-.2-.702-.592-1.332-1.12-1.826-.78-.727-1.812-1.13-2.882-1.13-.815 0-1.6.236-2.272.684v10.822c0 .063.052.115.115.115h15.666c1.666 0 3.018-1.352 3.018-3.018 0-1.666-1.352-3.018-3.018-3.018z"/></svg>' },
             bandcamp: { name: 'Bandcamp', base: 'https://bandcamp.com/', color: '#1da0c3', icon: '<svg width="13" height="13" viewBox="0 0 24 24" fill="currentColor"><path d="M0 18.75l7.437-13.5H24l-7.438 13.5H0z"/></svg>' },
             tidal: { name: 'Tidal', base: 'https://tidal.com/browse/artist/', color: '#000000', icon: '<svg width="13" height="13" viewBox="0 0 24 24" fill="currentColor"><path d="M12 4l4 4-4 4-4-4 4-4zm0 8l4 4-4 4-4-4 4-4zm8-8l4 4-4 4-4-4 4-4z"/></svg>' },
             instagram: { name: 'Instagram', base: 'https://instagram.com/', color: '#e1306c', icon: '<svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><rect x="2" y="2" width="20" height="20" rx="5" ry="5"></rect><path d="M16 11.37A4 4 0 1 1 12.63 8 4 4 0 0 1 16 11.37z"></path></svg>' },
            youtube: { name: 'YouTube', base: 'https://youtube.com/@', color: '#ff0000', icon: '<svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M22.54 6.42a2.78 2.78 0 0 0-1.94-2C18.88 4 12 4 12 4s-6.88 0-8.6.46a2.78 2.78 0 0 0-1.94 2A29 29 0 0 0 1 11.75a29 29 0 0 0 .46 5.33A2.78 2.78 0 0 0 3.4 19c1.72.46 8.6.46 8.6.46s6.88 0 8.6-.46a2.78 2.78 0 0 0 1.94-2 29 29 0 0 0 .46-5.25 29 29 0 0 0-.46-5.33z"></path><polygon points="9.75 15.02 15.5 11.75 9.75 8.48 9.75 15.02"></polygon></svg>' },
             instagram: { name: 'Instagram', base: 'https://instagram.com/', color: '#e1306c', icon: '<svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><rect x="2" y="2" width="20" height="20" rx="5" ry="5"></rect><path d="M16 11.37A4 4 0 1 1 12.63 8 4 4 0 0 1 16 11.37z"></path><line x1="17.5" y1="6.5" x2="17.51" y2="6.5"></line></svg>' },
             tiktok: { name: 'TikTok', base: 'https://www.tiktok.com/@', color: '#000000', icon: '<svg width="13" height="13" viewBox="0 0 24 24" fill="currentColor"><path d="M19.59 6.69a4.83 4.83 0 0 1-3.77-4.25V2h-3.45v13.67a2.89 2.89 0 1 1-5.2-1.74 2.89 2.89 0 0 1 2.31-2.22V8.2a6.34 6.34 0 0 0-5 6.13 6.34 6.34 0 1 0 10.7-4.52A8.25 8.25 0 0 0 20 10.56V6.69z"/></svg>' },
             tiktok: { name: 'TikTok', base: 'https://www.tiktok.com/@', color: '#000000', icon: '<svg width="13" height="13" viewBox="0 0 24 24" fill="currentColor"><path d="M19.59 6.69a4.83 4.83 0 0 1-3.77-4.25V2h-3.45v13.67a2.89 2.89 0 1 1-5.2-1.74 2.89 2.89 0 0 1 2.31-2.22V8.2a6.34 6.34 0 0 0-5 6.13 6.34 6.34 0 1 0 10.7-4.52A8.25 8.25 0 0 0 20 10.56V6.69z"/></svg>' },
            youtube: { name: 'YouTube', base: 'https://youtube.com/@', color: '#ff0000', icon: '<svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M22.54 6.42a2.78 2.78 0 0 0-1.94-2C18.88 4 12 4 12 4s-6.88 0-8.6.46a2.78 2.78 0 0 0-1.94 2A29 29 0 0 0 1 11.75a29 29 0 0 0 .46 5.33A2.78 2.78 0 0 0 3.4 19c1.72.46 8.6.46 8.6.46s6.88 0 8.6-.46a2.78 2.78 0 0 0 1.94-2 29 29 0 0 0 .46-5.25 29 29 0 0 0-.46-5.33z"></path><polygon points="9.75 15.02 15.5 11.75 9.75 8.48 9.75 15.02"></polygon></svg>' },
             twitter: { name: 'X / Twitter', base: 'https://x.com/', color: '#0f1419', icon: '<svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M23 3a10.9 10.9 0 0 1-3.14 1.53 4.48 4.48 0 0 0-7.86 3v1A10.66 10.66 0 0 1 3 4s-4 9 5 13a11.64 11.64 0 0 1-7 2c9 5 20 0 20-11.5a4.5 4.5 0 0 0-.08-.83A7.72 7.72 0 0 0 23 3z"></path></svg>' },
             twitter: { name: 'X / Twitter', base: 'https://x.com/', color: '#0f1419', icon: '<svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M23 3a10.9 10.9 0 0 1-3.14 1.53 4.48 4.48 0 0 0-7.86 3v1A10.66 10.66 0 0 1 3 4s-4 9 5 13a11.64 11.64 0 0 1-7 2c9 5 20 0 20-11.5a4.5 4.5 0 0 0-.08-.83A7.72 7.72 0 0 0 23 3z"></path></svg>' },
             threads: { name: 'Threads', base: 'https://www.threads.net/@', color: '#000000', icon: '<svg width="13" height="13" viewBox="0 0 24 24" fill="currentColor"><path d="M12 2C6.477 2 2 6.477 2 12s4.477 10 10 10 10-4.477 10-10S17.523 2 12 2zm3.842 12.338c-.288 1.83-1.85 3.09-3.842 3.09-2.298 0-4.043-1.68-4.043-4.135 0-2.454 1.745-4.134 4.043-4.134 1.583 0 2.875.836 3.447 2.083l-1.28.625c-.39-.817-1.182-1.328-2.167-1.328-1.55 0-2.613 1.15-2.613 2.754 0 1.603 1.063 2.753 2.613 2.753 1.258 0 2.19-.77 2.37-1.808h-2.37v-1.38h3.842v1.48z"/></svg>' },
             threads: { name: 'Threads', base: 'https://www.threads.net/@', color: '#000000', icon: '<svg width="13" height="13" viewBox="0 0 24 24" fill="currentColor"><path d="M12 2C6.477 2 2 6.477 2 12s4.477 10 10 10 10-4.477 10-10S17.523 2 12 2zm3.842 12.338c-.288 1.83-1.85 3.09-3.842 3.09-2.298 0-4.043-1.68-4.043-4.135 0-2.454 1.745-4.134 4.043-4.134 1.583 0 2.875.836 3.447 2.083l-1.28.625c-.39-.817-1.182-1.328-2.167-1.328-1.55 0-2.613 1.15-2.613 2.754 0 1.603 1.063 2.753 2.613 2.753 1.258 0 2.19-.77 2.37-1.808h-2.37v-1.38h3.842v1.48z"/></svg>' },
             facebook: { name: 'Facebook', base: 'https://facebook.com/', color: '#1877f2', icon: '<svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M18 2h-3a5 5 0 0 0-5 5v3H7v4h3v8h4v-8h3l1-4h-4V7a1 1 0 0 1 1-1h3z"></path></svg>' },
             facebook: { name: 'Facebook', base: 'https://facebook.com/', color: '#1877f2', icon: '<svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M18 2h-3a5 5 0 0 0-5 5v3H7v4h3v8h4v-8h3l1-4h-4V7a1 1 0 0 1 1-1h3z"></path></svg>' },
             linkedin: { name: 'LinkedIn', base: 'https://linkedin.com/in/', color: '#0a66c2', icon: '<svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M16 8a6 6 0 0 1 6 6v7h-4v-7a2 2 0 0 0-2-2 2 2 0 0 0-2 2v7h-4v-7a6 6 0 0 1 6-6z"></path><rect x="2" y="9" width="4" height="12"></rect><circle cx="4" cy="4" r="2"></circle></svg>' },
             linkedin: { name: 'LinkedIn', base: 'https://linkedin.com/in/', color: '#0a66c2', icon: '<svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M16 8a6 6 0 0 1 6 6v7h-4v-7a2 2 0 0 0-2-2 2 2 0 0 0-2 2v7h-4v-7a6 6 0 0 1 6-6z"></path><rect x="2" y="9" width="4" height="12"></rect><circle cx="4" cy="4" r="2"></circle></svg>' },
             github: { name: 'GitHub', base: 'https://github.com/', color: '#24292e', icon: '<svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M9 19c-5 1.5-5-2.5-7-3m14 6v-3.87a3.37 3.37 0 0 0-.94-2.61c3.14-.35 6.44-1.54 6.44-7A5.44 5.44 0 0 0 20 4.77 5.07 5.07 0 0 0 19.91 1S18.73.65 16 2.48a13.38 13.38 0 0 0-7 0C6.27.65 5.09 1 5.09 1A5.07 5.07 0 0 0 5 4.77a5.44 5.44 0 0 0-1.5 3.78c0 5.42 3.3 6.61 6.44 7A3.37 3.37 0 0 0 9 18.13V22"></path></svg>' },
             twitch: { name: 'Twitch', base: 'https://twitch.tv/', color: '#9146FF', icon: '<svg width="13" height="13" viewBox="0 0 24 24" fill="currentColor"><path d="M11.571 4.714h1.715v5.143H11.57zm4.715 0H18v5.143h-1.714zM6 0L1.714 4.286v15.428h5.143V24l4.286-4.286h3.428L22.286 12V0zm14.571 11.143l-3.428 3.428h-3.429l-3 3v-3H6.857V1.714h13.714Z"/></svg>' },
            pinterest: { name: 'Pinterest', base: 'https://pinterest.com/', color: '#e60023', icon: '<svg width="13" height="13" viewBox="0 0 24 24" fill="currentColor"><path d="M12 0C5.373 0 0 5.372 0 12c0 5.084 3.163 9.426 7.627 11.174-.105-.949-.2-2.405.042-3.441.218-.937 1.407-5.965 1.407-5.965s-.359-.719-.359-1.782c0-1.668.967-2.914 2.171-2.914 1.023 0 1.518.769 1.518 1.69 0 1.029-.655 2.568-.994 3.995-.283 1.194.599 2.169 1.777 2.169 2.133 0 3.772-2.249 3.772-5.495 0-2.873-2.064-4.882-5.012-4.882-3.414 0-5.418 2.561-5.418 5.207 0 1.031.397 2.138.893 2.738.098.119.112.224.083.345l-.333 1.36c-.053.22-.174.267-.402.161-1.499-.698-2.436-2.889-2.436-4.649 0-3.785 2.75-7.262 7.929-7.262 4.163 0 7.398 2.967 7.398 6.931 0 4.136-2.607 7.464-6.227 7.464-1.216 0-2.359-.631-2.75-1.378l-.748 2.853c-.271 1.043-1.002 2.35-1.492 3.146C9.57 23.812 10.763 24 12 24c6.627 0 12-5.373 12-12 0-6.628-5.373-12-12-12z"/></svg>' },
            discord: { name: 'Discord', base: 'https://discord.gg/', color: '#5865F2', icon: '<svg width="13" height="13" viewBox="0 0 24 24" fill="currentColor"><path d="M20.317 4.37a19.791 19.791 0 0 0-4.885-1.515.074.074 0 0 0-.079.037c-.21.375-.444.864-.608 1.25a18.27 18.27 0 0 0-5.487 0 12.64 12.64 0 0 0-.617-1.25.077.077 0 0 0-.079-.037A19.736 19.736 0 0 0 3.677 4.37a.07.07 0 0 0-.032.027C.533 9.046-.32 13.58.099 18.057a.082.082 0 0 0 .031.057 19.9 19.9 0 0 0 5.993 3.03.078.078 0 0 0 .084-.028 14.09 14.09 0 0 0 1.226-1.994.076.076 0 0 0-.041-.106 13.107 13.107 0 0 1-1.872-.892.077.077 0 0 1-.008-.128 10.2 10.2 0 0 0 .372-.292.074.074 0 0 1 .077-.01c3.928 1.793 8.18 1.793 12.062 0a.074.074 0 0 1 .078.01c.12.098.246.198.373.292a.077.077 0 0 1-.006.127 12.299 12.299 0 0 1-1.873.892.077.077 0 0 0-.041.107c.36.698.772 1.362 1.225 1.993a.076.076 0 0 0 .084.028 19.839 19.839 0 0 0 6.002-3.03.077.077 0 0 0 .032-.054c.5-5.177-.838-9.674-3.549-13.66a.061.061 0 0 0-.031-.028zM8.02 15.33c-1.183 0-2.157-1.085-2.157-2.419 0-1.333.956-2.419 2.157-2.419 1.21 0 2.176 1.096 2.157 2.42 0 1.333-.956 2.418-2.157 2.418zm7.975 0c-1.183 0-2.157-1.085-2.157-2.419 0-1.333.955-2.419 2.157-2.419 1.21 0 2.176 1.096 2.157 2.42 0 1.333-.946 2.418-2.157 2.418z"/></svg>' },
            twitch: { name: 'Twitch', base: 'https://twitch.tv/', color: '#9146ff', icon: '<svg width="13" height="13" viewBox="0 0 24 24" fill="currentColor"><path d="M11.571 4.714h1.715v5.143H11.57zm4.715 0H18v5.143h-1.714zM6 0L1.714 4.286v15.428h5.143V24l4.286-4.286h3.428L22.286 12V0zm14.571 11.143l-3.428 3.428h-3.429l-3 3v-3H6.857V1.714h13.714Z"/></svg>' },
            pinterest: { name: 'Pinterest', base: 'https://pinterest.com/', color: '#e60023', icon: '<svg width="13" height="13" viewBox="0 0 24 24" fill="currentColor"><path d="M12 0C5.373 0 0 5.372 0 12c0 5.084 3.163 9.426 7.627 11.174-.105-.949-.2-2.405.042-3.441.218-.937 1.407-5.965 1.407-5.965s-.359-.719-.359-1.782c0-1.668.967-2.914 2.171-2.914 1.023 0 1.518.769 1.518 1.69 0 1.029-.655 2.568-.994 3.995-.283 1.194.599 2.169 1.777 2.169 2.133 0 3.772-2.249 3.772-5.495 0-2.873-2.064-4.882-5.012-4.882-3.414 0-5.418 2.561-5.418 5.207 0 1.031.397 2.138.893 2.738.098.119.112.224.083.345l-.333 1.36c-.053.22-.174.267-.402.161-1.499-.698-2.436-2.889-2.436-4.649 0-3.785 2.75-7.262 7.929-7.262 4.163 0 7.398 2.967 7.398 6.931 0 4.136-2.607 7.464-6.227 7.464-1.216 0-2.359-.631-2.75-1.378l-.748 2.853c-.271 1.043-1.002 2.35-1.492 3.146C9.57 23.812 10.763 24 12 24c6.627 0 12-5.373 12-12 0-6.628-5.373-12-12-12z"/></svg>' }
            reddit: { name: 'Reddit', base: 'https://reddit.com/user/', color: '#ff4500', icon: '<svg width="13" height="13" viewBox="0 0 24 24" fill="currentColor"><path d="M24 11.779c0-1.459-1.192-2.645-2.657-2.645-.715 0-1.363.275-1.84.734-1.605-1.056-3.868-1.739-6.38-1.815l1.341-4.218 3.238.683c.038 1.168 1.002 2.1 2.189 2.1 1.212 0 2.193-.984 2.193-2.2s-.981-2.2-2.193-2.2c-1.01 0-1.868.682-2.131 1.606l-3.619-.763c-.156-.033-.311.042-.366.19l-1.547 4.86c-2.61.037-4.978.711-6.643 1.785-.477-.47-1.135-.754-1.861-.754-1.465 0-2.656 1.187-2.656 2.646 0 .97.533 1.811 1.317 2.271-.052.282-.086.567-.086.857 0 3.911 4.808 7.093 10.719 7.093s10.72-3.182 10.72-7.093c0-.274-.029-.544-.075-.81.832-.447 1.405-1.312 1.405-2.318zm-17.224 1.816c0-.868.71-1.575 1.582-1.575.872 0 1.581.707 1.581 1.575s-.709 1.574-1.581 1.574-1.582-.706-1.582-1.574zm9.014 4.597c-1.233 1.234-3.535 1.294-5.068 1.294-1.531 0-3.834-.06-5.068-1.294-.216-.216-.216-.566 0-.783.216-.217.567-.217.784 0 1.019 1.018 3.033 1.109 4.284 1.109 1.253 0 3.266-.09 4.284-1.109.217-.217.568-.217.784 0 .216.217.216.566 0 .783zm.18-2.923c-.872 0-1.582-.706-1.582-1.574 0-.868.71-1.575 1.582-1.575.871 0 1.581.707 1.581 1.575s-.71 1.574-1.581 1.574z"/></svg>' },
            discord: { name: 'Discord', base: 'https://discord.com/users/', color: '#5865f2', icon: '<svg width="13" height="13" viewBox="0 0 24 24" fill="currentColor"><path d="M20.317 4.3698a19.7913 19.7913 0 00-4.8851-1.5152.0741.0741 0 00-.0785.0371c-.211.3753-.4447.8648-.6083 1.2495-1.8447-.2762-3.68-.2762-5.4868 0-.1636-.3933-.4058-.8742-.6177-1.2495a.077.077 0 00-.0785-.037 19.7363 19.7363 0 00-4.8852 1.515.0699.0699 0 00-.0321.0277C.5334 9.0458-.319 13.5799.0992 18.0578a.0824.0824 0 00.0312.0561c2.0528 1.5076 4.0413 2.4228 5.9929 3.0294a.0777.0777 0 00.0842-.0276c.4616-.6304.8731-1.2952 1.226-1.9942a.076.076 0 00-.0416-.1057c-.6528-.2476-1.2743-.5495-1.8722-.8923a.077.077 0 01-.0076-.1277c.1258-.0943.2517-.1923.3718-.2914a.0743.0743 0 01.0776-.0105c3.9278 1.7933 8.18 1.7933 12.0614 0a.0739.0739 0 01.0785.0095c.1202.099.246.1981.3728.2924a.077.077 0 01-.0066.1276 12.2986 12.2986 0 01-1.873.8914.0766.0766 0 00-.0407.1067c.3604.698.7719 1.3628 1.225 1.9932a.076.076 0 00.0842.0286c1.961-.6067 3.9495-1.5219 6.0023-3.0294a.077.077 0 00.0313-.0552c.5004-5.177-.8382-9.6739-3.5485-13.6604a.061.061 0 00-.0312-.0286zM8.02 15.3312c-1.1825 0-2.1569-1.0857-2.1569-2.419 0-1.3332.9555-2.4189 2.157-2.4189 1.2108 0 2.1757 1.0952 2.1568 2.419 0 1.3332-.9555 2.4189-2.1569 2.4189zm7.9748 0c-1.1825 0-2.1569-1.0857-2.1569-2.419 0-1.3332.9554-2.4189 2.1569-2.4189 1.2108 0 2.1757 1.0952 2.1568 2.419 0 1.3332-.946 2.4189-2.1568 2.4189z"/></svg>' },
            wikipedia: { name: 'Wikipedia', base: 'https://id.wikipedia.org/wiki/', color: '#000000', icon: '<svg width="13" height="13" viewBox="0 0 24 24" fill="currentColor"><path d="M11.964 1.488C5.467 1.488.2 6.756.2 13.253s5.267 11.765 11.764 11.765 11.765-5.268 11.765-11.765S18.461 1.488 11.964 1.488zm-2.003 18.06l-4.706-9.412h1.412l2.353 5.378 1.954-5.378h1.41l2.42 5.513 2.164-5.513h1.365l-4.47 9.412h-1.554l-1.954-5.464-2.046 5.464h-1.348z"/></svg>' }
         };
         };


         // 2. PRESET TEMPLATES LABEL LENGKAP
         // 2. PRESET TEMPLATES
         var PRESET_LABELS = [
         var PRESET_LABELS = [
             "Nama Lahir", "Tanggal Lahir", "Tempat Lahir", "Pekerjaan",  
             "Nama Lahir", "Tanggal Lahir", "Tempat Lahir", "Pekerjaan", "Gelar",
             "Kebangsaan", "Genre", "Instrumen", "Label Rekaman",  
             "Kebangsaan", "Genre", "Instrumen", "Label Rekaman", "Zodiak",
             "Tahun Aktif", "Situs Web Resmi", "Pasangan", "Orang Tua", "Agama", "Pendidikan"
             "Tahun Aktif", "Situs Web Resmi", "Pasangan", "Orang Tua", "Pendidikan"
         ];
         ];


         // 3. MASTER TIPE RUJUKAN
         // 3. MASTER TIPE RUJUKAN
         var REF_TYPES = {
         var REF_TYPES = {
             "Berita": ["Berita Online", "Berita Cetak / Koran", "Wawancara Eksklusif", "Liputan Khusus"],
             "Berita": ["Berita Online", "Berita Cetak / Koran", "Wawancara Eksklusif", "Siaran Radio / TV"],
             "Website": ["Situs Resmi", "Portal Informasi", "Database Web", "Forum Diskusi"],
             "Website": ["Situs Resmi", "Portal Informasi", "Database Web", "Forum Diskusi"],
             "Buku": ["Buku Cetak", "E-Book", "Bab / Bagian Buku", "Monograf"],
             "Buku": ["Buku Cetak", "E-Book", "Bab / Bagian Buku", "Biografi Cetak"],
             "Jurnal": ["Jurnal Ilmiah Peer-Reviewed", "Paper Konferensi", "Tesis / Disertasi"],
             "Jurnal": ["Jurnal Ilmiah", "Paper Konferensi", "Artikel Review", "Tesis / Disertasi"],
            "Siaran Pers": ["Siaran Pers Resmi", "Pengumuman Instansi / BUMN"],
             "Musik & Video": ["MusicBrainz", "Discogs", "Spotify", "YouTube", "Film Dokumenter"],
             "Dokumen PDF": ["Laporan Tahunan / Annual Report", "Dokumen Kebijakan"],
             "Lainnya": ["Siaran Pers", "Dokumen PDF", "Postingan Medsos", "Arsip Web"]
            "Studio / Database Musik": ["MusicBrainz", "Discogs", "Genius", "AllMusic", "Spotify For Artists"],
            "Video": ["YouTube Video", "Film Dokumenter", "Wawancara Video"],
             "Podcast": ["Episode Podcast", "Siniar Audio Resmi"],
            "Media Sosial": ["Postingan / Tweet", "Video Singkat", "Live Stream"],
            "Ensiklopedia": ["Ensiklopedia Cetak", "Ensiklopedia Online"],
            "Arsip": ["Arsip Nasional", "Web Archive (Wayback Machine)"]
         };
         };


         // 4. IKON SISTEM (SVG)
         // 4. IKON SISTEM (SVG Ditingkatkan)
         var svgEdit = '<svg class="md-icon" width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M11 4H4a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-7"></path><path d="M18.5 2.5a2.121 2.121 0 0 1 3 3L12 15l-4 1 1-4 9.5-9.5z"></path></svg>';
         var svgEdit = '<svg class="md-icon" width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M11 4H4a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-7"></path><path d="M18.5 2.5a2.121 2.121 0 0 1 3 3L12 15l-4 1 1-4 9.5-9.5z"></path></svg>';
         var svgLock = '<svg class="md-icon" width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><rect x="3" y="11" width="18" height="11" rx="2" ry="2"></rect><path d="M7 11V7a5 5 0 0 1 10 0v4"></path></svg>';
         var svgLock = '<svg class="md-icon" width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><rect x="3" y="11" width="18" height="11" rx="2" ry="2"></rect><path d="M7 11V7a5 5 0 0 1 10 0v4"></path></svg>';
Baris 73: Baris 64:
         var svgSearch = '<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="11" cy="11" r="8"></circle><line x1="21" y1="21" x2="16.65" y2="16.65"></line></svg>';
         var svgSearch = '<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="11" cy="11" r="8"></circle><line x1="21" y1="21" x2="16.65" y2="16.65"></line></svg>';
         var svgCode = '<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><polyline points="16 18 22 12 16 6"></polyline><polyline points="8 6 2 12 8 18"></polyline></svg>';
         var svgCode = '<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><polyline points="16 18 22 12 16 6"></polyline><polyline points="8 6 2 12 8 18"></polyline></svg>';
        var svgChevronDown = '<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><polyline points="6 9 12 15 18 9"></polyline></svg>';
         var svgExternal = '<svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6"></path><polyline points="15 3 21 3 21 9"></polyline><line x1="10" y1="14" x2="21" y2="3"></line></svg>';
         var svgExternal = '<svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6"></path><polyline points="15 3 21 3 21 9"></polyline><line x1="10" y1="14" x2="21" y2="3"></line></svg>';
         var svgMoon = '<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z"></path></svg>';
         var svgArrowUp = '<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><line x1="12" y1="19" x2="12" y2="5"></line><polyline points="5 12 12 5 19 12"></polyline></svg>';
         var svgSun = '<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="12" cy="12" r="5"></circle><line x1="12" y1="1" x2="12" y2="3"></line><line x1="12" y1="21" x2="12" y2="23"></line><line x1="4.22" y1="4.22" x2="5.64" y2="5.64"></line><line x1="18.36" y1="18.36" x2="19.78" y2="19.78"></line><line x1="1" y1="12" x2="3" y2="12"></line><line x1="21" y1="12" x2="23" y2="12"></line><line x1="4.22" y1="19.78" x2="5.64" y2="18.36"></line><line x1="18.36" y1="5.64" x2="19.78" y2="4.22"></line></svg>';
         var svgArrowDown = '<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><line x1="12" y1="5" x2="12" y2="19"></line><polyline points="19 12 12 19 5 12"></polyline></svg>';
         var svgDownload = '<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"></path><polyline points="7 10 12 15 17 10"></polyline><line x1="12" y1="15" x2="12" y2="3"></line></svg>';
         var svgDownload = '<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"></path><polyline points="7 10 12 15 17 10"></polyline><line x1="12" y1="15" x2="12" y2="3"></line></svg>';
        var svgClone = '<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><rect x="9" y="9" width="13" height="13" rx="2" ry="2"></rect><path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"></path></svg>';
        var svgDrag = '<svg width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" style="cursor:grab; color:#94a3b8;"><line x1="8" y1="6" x2="21" y2="6"></line><line x1="8" y1="12" x2="21" y2="12"></line><line x1="8" y1="18" x2="21" y2="18"></line><line x1="3" y1="6" x2="3.01" y2="6"></line><line x1="3" y1="12" x2="3.01" y2="12"></line><line x1="3" y1="18" x2="3.01" y2="18"></line></svg>';


         // 5. HELPER UTILITY
         // 5. HELPER UTILITY (Notifikasi Toast, Extract Domain, dll)
         function showToast(msg, type) {
         function showToast(message, type) {
             var bg = type === 'error' ? '#ef4444' : '#10b981';
             var bg = type === 'error' ? '#dc2626' : (type === 'warning' ? '#d97706' : '#16a34a');
             var $toast = $('<div style="position:fixed; bottom:20px; right:20px; background:'+bg+'; color:white; padding:12px 20px; border-radius:8px; box-shadow:0 10px 25px rgba(0,0,0,0.2); z-index:9999; font-weight:600; font-size:0.9rem; transform:translateY(100px); opacity:0; transition:all 0.3s ease;">' + msg + '</div>');
             var $toast = $('<div style="position:fixed; bottom:20px; right:20px; background:'+bg+'; color:#fff; padding:12px 20px; border-radius:8px; box-shadow:0 4px 12px rgba(0,0,0,0.15); z-index:9999; font-weight:600; font-size:0.9rem; opacity:0; transform:translateY(20px); transition:all 0.3s ease;">'+message+'</div>');
             $('body').append($toast);
             $('body').append($toast);
             setTimeout(function() { $toast.css({transform: 'translateY(0)', opacity: 1}); }, 50);
             setTimeout(function() { $toast.css({opacity: 1, transform: 'translateY(0)'}); }, 10);
             setTimeout(function() { $toast.css({transform: 'translateY(100px)', opacity: 0}); setTimeout(function(){ $toast.remove(); }, 300); }, 3000);
             setTimeout(function() {
                $toast.css({opacity: 0, transform: 'translateY(20px)'});
                setTimeout(function() { $toast.remove(); }, 300);
            }, 3000);
         }
         }


Baris 93: Baris 86:
             var parts = dateStr.split('-');
             var parts = dateStr.split('-');
             if (parts.length !== 3) return dateStr;
             if (parts.length !== 3) return dateStr;
             var months = ['Jan', 'Feb', 'Mar', 'Apr', 'Mei', 'Jun', 'Jul', 'Agu', 'Sep', 'Okt', 'Nov', 'Des'];
             var months = ['Januari', 'Februari', 'Maret', 'April', 'Mei', 'Juni', 'Juli', 'Agustus', 'September', 'Oktober', 'November', 'Desember'];
             var day = parseInt(parts[2], 10);
             var day = parseInt(parts[2], 10);
             var monthIdx = parseInt(parts[1], 10) - 1;
             var monthIdx = parseInt(parts[1], 10) - 1;
Baris 104: Baris 97:
             try {
             try {
                 if (!urlStr.match(/^https?:\/\//i)) urlStr = 'https://' + urlStr;
                 if (!urlStr.match(/^https?:\/\//i)) urlStr = 'https://' + urlStr;
                 return new URL(urlStr).hostname.replace(/^www\./, '');
                 var parsed = new URL(urlStr);
             } catch(e) { return urlStr.replace(/^https?:\/\/(www\.)?/, '').split('/')[0]; }
                return parsed.hostname.replace(/^www\./, '');
             } catch(e) {
                return urlStr.replace(/^https?:\/\/(www\.)?/, '').split('/')[0];
            }
         }
         }


Baris 111: Baris 107:
             if (!urlStr) return '';
             if (!urlStr) return '';
             urlStr = urlStr.trim();
             urlStr = urlStr.trim();
             if (urlStr && !urlStr.match(/^https?:\/\//i)) return 'https://' + urlStr;
             if (urlStr && !urlStr.match(/^https?:\/\//i)) {
                return 'https://' + urlStr;
            }
             return urlStr;
             return urlStr;
         }
         }
Baris 121: Baris 119:
             var d = String(now.getDate()).padStart(2, '0');
             var d = String(now.getDate()).padStart(2, '0');
             return y + '-' + m + '-' + d;
             return y + '-' + m + '-' + d;
        }
       
        function toTitleCase(str) {
            return str.replace(/\w\S*/g, function(txt){ return txt.charAt(0).toUpperCase() + txt.substr(1).toLowerCase(); });
         }
         }


        function getRefQuality(ref) {
         // 6. STYLESHEET MODERN V8.0 PRO
            if (!ref || (!ref.url && !ref.title)) return 0;
            var score = 0;
            if(ref.url) score++; if(ref.title) score++; if(ref.publisher || ref.site) score++;
            if(ref.date) score++; if(ref.author) score++;
            return score;
        }
 
         // 6. STYLESHEET MODERN V8.0 TITANIUM (Dark Mode Ready & Animations)
         var css = `
         var css = `
            :root {
                --md-bg: #ffffff; --md-surface: #f8fafc; --md-border: #e2e8f0;
                --md-text-main: #0f172a; --md-text-sub: #64748b; --md-primary: #4f46e5;
                --md-primary-hover: #4338ca; --md-shadow: rgba(0,0,0,0.06);
                --md-glass: rgba(255, 255, 255, 0.8);
            }
            .md-dark {
                --md-bg: #1e1e2f; --md-surface: #2a2a40; --md-border: #3b3b5c;
                --md-text-main: #f1f5f9; --md-text-sub: #94a3b8; --md-primary: #6366f1;
                --md-primary-hover: #818cf8; --md-shadow: rgba(0,0,0,0.3);
                --md-glass: rgba(30, 30, 47, 0.8);
            }
             #mippedia-data-app {
             #mippedia-data-app {
                 background: var(--md-bg); border-radius: 16px; box-shadow: 0 4px 24px var(--md-shadow);
                 background: #ffffff; border-radius: 16px; box-shadow: 0 8px 30px rgba(0,0,0,0.04);
                 padding: 20px; margin: 20px 0; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
                 padding: 24px; margin: 24px 0; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
                 border: 1px solid var(--md-border); max-width: 100%; box-sizing: border-box; overflow: hidden;
                 border: 1px solid #f1f5f9; max-width: 100%; box-sizing: border-box; overflow: hidden;
                color: var(--md-text-main); transition: background 0.3s, color 0.3s;
             }
             }
              
              
            /* Sticky Header */
             .md-header {
             .md-header {
                 display: flex; flex-wrap: wrap; justify-content: space-between; align-items: center;
                 display: flex; flex-wrap: wrap; justify-content: space-between; align-items: center;
                 gap: 12px; margin-bottom: 16px; padding-bottom: 14px; border-bottom: 1px solid var(--md-border);
                 gap: 12px; margin-bottom: 20px; padding-bottom: 16px; border-bottom: 2px solid #f8fafc;
                position: sticky; top: 0; background: var(--md-glass); backdrop-filter: blur(10px); z-index: 10;
             }
             }
             .md-title-container { display: flex; align-items: center; gap: 8px; flex: 1 1 auto; min-width: 180px; }
             .md-title-container { display: flex; align-items: center; gap: 10px; flex: 1 1 auto; min-width: 180px; }
             .md-title { font-size: 1.25rem; font-weight: 800; margin: 0; white-space: nowrap; letter-spacing: -0.3px; }
             .md-title { font-size: 1.35rem; font-weight: 800; color: #0f172a; margin: 0; white-space: nowrap; letter-spacing: -0.5px; }
             .md-actions { display: flex; gap: 6px; align-items: center; flex-wrap: wrap; }
             .md-actions { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; }
              
              
             .md-btn-icon {
             .md-btn-icon {
                 background: var(--md-surface); border: 1px solid var(--md-border); cursor: pointer; color: var(--md-primary);
                 background: #f8fafc; border: 1px solid #e2e8f0; cursor: pointer; color: #4f46e5;
                 padding: 8px 12px; border-radius: 8px; transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);
                 padding: 8px 14px; border-radius: 10px; transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);
                 display: inline-flex; align-items: center; gap: 6px; font-size: 0.8rem; font-weight: 600; white-space: nowrap;
                 display: inline-flex; align-items: center; gap: 6px; font-size: 0.85rem; font-weight: 700; white-space: nowrap;
             }
             }
             .md-btn-icon:hover:not(:disabled) { background: var(--md-border); transform: translateY(-2px); box-shadow: 0 4px 10px var(--md-shadow); }
             .md-btn-icon:hover:not(:disabled) { background: #e0e7ff; border-color: #c7d2fe; transform: translateY(-2px); box-shadow: 0 4px 12px rgba(79, 70, 229, 0.1); }
            .md-btn-icon:active:not(:disabled) { transform: translateY(0); }
            .md-btn-lock { color: #e11d48; background: #fff1f2; border-color: #fecdd3; }
            .md-btn-lock:hover:not(:disabled) { background: #ffe4e6; border-color: #fda4af; box-shadow: 0 4px 12px rgba(225, 29, 72, 0.1); }


            /* Tab Filters */
             .md-search-box { position: relative; margin-bottom: 20px; width: 100%; box-sizing: border-box; }
            .md-tabs { display: flex; gap: 10px; margin-bottom: 15px; border-bottom: 2px solid var(--md-surface); padding-bottom: 5px; }
            .md-tab { background: none; border: none; font-weight: 700; color: var(--md-text-sub); cursor: pointer; padding: 5px 10px; border-bottom: 2px solid transparent; transition: 0.2s; font-size: 0.85rem;}
            .md-tab.active { color: var(--md-primary); border-bottom-color: var(--md-primary); }
            .md-tab:hover { color: var(--md-primary); }
 
             .md-search-box { position: relative; margin-bottom: 16px; width: 100%; box-sizing: border-box; }
             .md-search-input {
             .md-search-input {
                 width: 100%; padding: 10px 12px 10px 34px; border: 1px solid var(--md-border); border-radius: 8px;
                 width: 100%; padding: 12px 16px 12px 40px; border: 2px solid #f1f5f9; border-radius: 12px;
                 font-size: 0.9rem; box-sizing: border-box; background: var(--md-surface); color: var(--md-text-main); transition: 0.2s;
                 font-size: 0.9rem; font-weight: 500; box-sizing: border-box; background: #f8fafc; transition: 0.3s;
             }
             }
             .md-search-input:focus { background: var(--md-bg); border-color: var(--md-primary); outline: none; box-shadow: 0 0 0 3px rgba(99, 102, 241, 0.2); }
             .md-search-input:focus { background: #fff; border-color: #6366f1; outline: none; box-shadow: 0 0 0 4px rgba(99, 102, 241, 0.1); }
             .md-search-icon { position: absolute; left: 10px; top: 50%; transform: translateY(-50%); color: var(--md-text-sub); }
             .md-search-icon { position: absolute; left: 14px; top: 50%; transform: translateY(-50%); color: #94a3b8; }


             /* Row Display & Drag */
             /* Row Display Fix */
             .md-row-display {
             .md-row-display {
                 display: flex; justify-content: space-between; align-items: flex-start;
                 display: flex; justify-content: space-between; align-items: flex-start;
                 padding: 14px 12px; border-bottom: 1px solid var(--md-border); transition: all 0.3s;
                 padding: 16px; border: 1px solid transparent; border-bottom: 1px solid #f1f5f9; transition: all 0.2s;
                 border-radius: 12px; gap: 12px; margin-bottom: 8px; background: var(--md-bg);
                 border-radius: 12px; gap: 12px; margin-bottom: 8px; background: #fff; position: relative;
             }
             }
             .md-row-display.dragging { opacity: 0.5; background: var(--md-surface); }
             .md-row-display:hover { background: #fafafa; border-color: #f1f5f9; box-shadow: 0 4px 12px rgba(0,0,0,0.02); }
            .md-row-display:hover { background: var(--md-surface); box-shadow: inset 4px 0 0 var(--md-primary); }
              
              
            .md-drag-handle { cursor: grab; padding-top: 5px; color: var(--md-text-sub); display:flex; align-items:center;}
             .md-data-group { display: flex; flex-direction: column; gap: 8px; flex: 1; min-width: 0; }
             .md-data-group { display: flex; flex-direction: column; gap: 6px; flex: 1; min-width: 0; }
             .md-data-label { font-size: 0.72rem; color: #64748b; font-weight: 800; text-transform: uppercase; letter-spacing: 0.8px; }
             .md-data-label { font-size: 0.72rem; color: var(--md-text-sub); font-weight: 800; text-transform: uppercase; letter-spacing: 0.6px; }
             .md-data-value-wrap { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
             .md-data-value-wrap { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
             .md-data-value { font-size: 1.1rem; color: #0f172a; line-height: 1.4; font-weight: 700; word-break: break-word; }
             .md-data-value { font-size: 1.05rem; font-weight: 600; word-break: break-word; color: var(--md-text-main); }
           
             .md-data-value a { color: var(--md-primary); text-decoration: none; }
             .md-btn-copy {
             .md-data-value a:hover { text-decoration: underline; }
                background: #f1f5f9; border: none; color: #64748b; cursor: pointer; padding: 4px 6px;
                border-radius: 6px; transition: 0.2s; display: inline-flex; align-items: center;
            }
             .md-btn-copy:hover { color: #4f46e5; background: #e0e7ff; transform: scale(1.05); }


             /* AKORDEON REFERENSI V8.0 */
            .md-row-actions { display: flex; flex-direction: column; gap: 6px; }
             .md-ref-container { margin-top: 6px; width: 100%; box-sizing: border-box; }
 
             .md-ref-toggle {
             /* Tampilan Referensi V8.0 (ACCORDION COLLAPSIBLE) */
                 background: var(--md-surface); border: 1px solid var(--md-border); padding: 6px 12px; border-radius: 20px;
             .md-ref-container { margin-top: 12px; width: 100%; max-width: 450px; box-sizing: border-box; }
                 font-size: 0.78rem; font-weight: 700; color: var(--md-text-sub); cursor: pointer; display: inline-flex; align-items: center; gap: 6px;
             .md-ref-summary {
                 transition: 0.2s; user-select: none;
                 background: #f8fafc; padding: 8px 12px; border-radius: 8px; border: 1px solid #e2e8f0;
                 display: flex; justify-content: space-between; align-items: center; cursor: pointer;
                 transition: all 0.2s; user-select: none;
             }
             }
             .md-ref-toggle:hover { background: var(--md-border); color: var(--md-primary); }
             .md-ref-summary:hover { background: #f1f5f9; border-color: #cbd5e1; }
             .md-ref-toggle.open { background: var(--md-primary); color: white; border-color: var(--md-primary); }
            .md-ref-summary.open { border-bottom-left-radius: 0; border-bottom-right-radius: 0; border-bottom-color: transparent; background: #f1f5f9; }
             .md-ref-tag { font-size: 0.8rem; font-weight: 700; color: #4f46e5; display: flex; align-items: center; gap: 6px; }
            .md-ref-toggle { color: #94a3b8; transition: transform 0.3s; display: flex; align-items: center; }
            .md-ref-summary.open .md-ref-toggle { transform: rotate(180deg); color: #4f46e5; }
              
              
             .md-ref-panel {
             .md-ref-body {
                display: none; /* Disembunyikan by default */
                 background: #fff; padding: 12px; border: 1px solid #e2e8f0; border-top: none;
                 background: var(--md-surface); padding: 12px 14px; border-radius: 10px; margin-top: 8px;
                 border-bottom-left-radius: 8px; border-bottom-right-radius: 8px; font-size: 0.85rem;
                 border-left: 4px solid var(--md-primary); font-size: 0.85rem; flex-direction: column; gap: 8px;
                 display: none; box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.05);
                 border-top: 1px solid var(--md-border); border-right: 1px solid var(--md-border); border-bottom: 1px solid var(--md-border);
                animation: mdFadeIn 0.3s ease-out;
             }
             }
            @keyframes mdFadeIn { from { opacity: 0; transform: translateY(-5px); } to { opacity: 1; transform: translateY(0); } }
             .md-ref-header { font-weight: 800; color: #0f172a; margin-bottom: 8px; display: block; word-break: break-word; line-height: 1.3; }
           
             .md-ref-details-grid { display: flex; flex-direction: column; gap: 4px; margin-bottom: 12px; }
             .md-ref-header { font-weight: 800; font-size: 0.9rem; color: var(--md-text-main); word-break: break-word; }
             .md-ref-detail-row { display: flex; flex-wrap: wrap; gap: 4px; font-size: 0.82rem; }
             .md-ref-details-grid { display: flex; flex-direction: column; gap: 4px; }
             .md-ref-lbl { font-weight: 700; color: #64748b; }
             .md-ref-detail-row { display: flex; flex-wrap: wrap; align-items: baseline; gap: 4px 6px; font-size: 0.82rem; }
             .md-ref-val { color: #334155; font-weight: 500; }
             .md-ref-lbl { font-weight: 700; color: var(--md-text-sub); white-space: nowrap; flex-shrink: 0; }
             .md-ref-val { color: var(--md-text-main); font-weight: 500; }
              
              
             .md-ref-bottom { display: flex; justify-content: space-between; align-items: center; margin-top: 8px; border-top: 1px dashed var(--md-border); padding-top: 8px; }
             .md-btn-visit {
            .md-ref-badge { display: inline-block; background: var(--md-border); color: var(--md-text-main); padding: 3px 8px; border-radius: 6px; font-weight: 700; font-size: 0.72rem; }
                display: inline-flex; align-items: center; gap: 6px; background: #eff6ff; color: #2563eb;
            .md-btn-direct {
                padding: 6px 12px; border-radius: 6px; font-weight: 700; font-size: 0.8rem; text-decoration: none;
                background: var(--md-primary); color: white !important; text-decoration: none; padding: 5px 12px; border-radius: 6px;
                 transition: 0.2s; border: 1px solid #bfdbfe; width: max-content;
                 font-weight: 700; font-size: 0.78rem; display: inline-flex; align-items: center; gap: 5px; transition: 0.2s;
             }
             }
             .md-btn-direct:hover { background: var(--md-primary-hover); transform: scale(1.05); text-decoration: none; }
             .md-btn-visit:hover { background: #dbeafe; text-decoration: none; transform: translateY(-1px); }
            .md-q-indicator { display:inline-block; width:8px; height:8px; border-radius:50%; margin-left:5px; }


             /* Media Sosial Badges */
             /* Media Sosial Badges V8 */
             .md-social-group { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 8px; }
             .md-social-group { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 10px; }
             .md-social-badge {
             .md-social-badge {
                 display: inline-flex; align-items: center; gap: 6px; padding: 5px 11px; border-radius: 18px;
                 display: inline-flex; align-items: center; gap: 6px; padding: 6px 12px; border-radius: 20px;
                 font-size: 0.78rem; font-weight: 600; color: white !important; text-decoration: none; transition: transform 0.2s, opacity 0.2s;
                 font-size: 0.8rem; font-weight: 700; color: white; text-decoration: none; transition: all 0.2s;
                 box-shadow: 0 2px 4px rgba(0,0,0,0.1);
                 box-shadow: 0 2px 4px rgba(0,0,0,0.1);
             }
             }
             .md-social-badge:hover { transform: translateY(-2px); opacity: 0.9; text-decoration: none; }
             .md-social-badge:hover { transform: translateY(-2px) scale(1.02); opacity: 0.95; box-shadow: 0 4px 8px rgba(0,0,0,0.15); color: white; text-decoration: none; }
 
            /* Preset Pill Badges */
            .md-preset-wrapper { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 8px; }
            .md-preset-pill {
                background: #f8fafc; border: 1px solid #e2e8f0; padding: 4px 10px; border-radius: 12px;
                font-size: 0.75rem; font-weight: 700; color: #64748b; cursor: pointer; transition: 0.2s;
            }
            .md-preset-pill:hover { background: #4f46e5; color: #fff; border-color: #4f46e5; }


             /* Form Elements */
             /* Form Elements */
             .md-form-box { background: var(--md-bg); border-radius: 12px; padding: 18px; margin-top: 16px; border: 1px solid var(--md-border); box-shadow: 0 8px 30px var(--md-shadow); animation: mdFadeIn 0.3s; }
             .md-form-box { background: #ffffff; border-radius: 16px; padding: 24px; margin-top: 24px; border: 1px solid #e2e8f0; box-shadow: 0 10px 40px rgba(0,0,0,0.06); animation: slideDown 0.3s ease; }
             .md-form-title { font-size: 1.1rem; font-weight: 800; margin: 0 0 16px 0; border-bottom: 2px solid var(--md-border); padding-bottom: 8px; display:flex; justify-content:space-between;}
            @keyframes slideDown { from { opacity: 0; transform: translateY(-10px); } to { opacity: 1; transform: translateY(0); } }
             .md-form-group { margin-bottom: 14px; position:relative;}
           
             .md-form-group label { display: block; font-size: 0.82rem; font-weight: 700; margin-bottom: 6px; color: var(--md-text-sub); }
             .md-form-title { font-size: 1.15rem; font-weight: 800; color: #0f172a; margin: 0 0 20px 0; border-bottom: 2px solid #f1f5f9; padding-bottom: 12px; }
             .md-form-group { margin-bottom: 18px; }
             .md-form-group label { display: block; font-size: 0.85rem; font-weight: 700; margin-bottom: 8px; color: #334155; }
             .md-input, .md-select, .md-textarea {
             .md-input, .md-select, .md-textarea {
                 width: 100%; padding: 9px 12px; border: 1px solid var(--md-border); border-radius: 8px;
                 width: 100%; padding: 10px 14px; border: 2px solid #e2e8f0; border-radius: 10px;
                 box-sizing: border-box; font-family: inherit; font-size: 0.9rem; transition: 0.2s; background: var(--md-surface); color: var(--md-text-main);
                 box-sizing: border-box; font-family: inherit; font-size: 0.95rem; transition: 0.2s; background: #fafafa;
             }
             }
             .md-input:focus, .md-select:focus, .md-textarea:focus { border-color: var(--md-primary); outline: none; box-shadow: 0 0 0 3px rgba(79, 70, 229, 0.15); }
             .md-input:focus, .md-select:focus, .md-textarea:focus { border-color: #6366f1; background: #fff; outline: none; box-shadow: 0 0 0 4px rgba(99, 102, 241, 0.1); }
            .md-input.error { border-color: #ef4444; background: #fef2f2; }
            .md-dark .md-input.error { background: #3f1a1a; }
           
            .md-preset-pill { background: var(--md-surface); border: 1px solid var(--md-border); padding: 4px 10px; border-radius: 12px; font-size: 0.75rem; font-weight: 600; cursor: pointer; transition: 0.2s; display:inline-block; margin:2px;}
            .md-preset-pill:hover { background: var(--md-primary); color:white; border-color:var(--md-primary);}
              
              
             .md-ref-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; background: var(--md-surface); padding: 12px; border-radius: 8px; border: 1px dashed var(--md-border); }
             .md-ref-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; background: #f8fafc; padding: 16px; border-radius: 12px; border: 1px dashed #cbd5e1; }
             .md-social-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; background: var(--md-surface); padding: 12px; border-radius: 8px; border: 1px solid var(--md-border); max-height: 280px; overflow-y: auto; }
             .md-social-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; background: #f1f5f9; padding: 16px; border-radius: 12px; border: 1px solid #e2e8f0; max-height: 320px; overflow-y: auto; }
             .md-grid-full { grid-column: span 2; }
             .md-grid-full { grid-column: span 2; }
              
              
             .md-form-actions { display: flex; gap: 10px; align-items: center; margin-top: 20px; padding-top: 14px; border-top: 1px solid var(--md-border); flex-wrap: wrap; }
             .md-form-actions { display: flex; gap: 12px; align-items: center; margin-top: 24px; padding-top: 16px; border-top: 1px solid #e2e8f0; flex-wrap: wrap; }
             .md-btn { padding: 10px 18px; border: none; border-radius: 8px; font-weight: 700; cursor: pointer; color: white; font-size: 0.85rem; transition: 0.2s; display: inline-flex; align-items: center; gap: 6px; justify-content: center; }
             .md-btn {
             .md-btn:hover:not(:disabled) { transform: translateY(-2px); box-shadow: 0 4px 10px rgba(0,0,0,0.15); }
                padding: 12px 20px; border: none; border-radius: 10px; font-weight: 800; cursor: pointer;
             .md-btn-save { background: linear-gradient(135deg, #4f46e5, #4338ca); flex: 1; min-width: 140px; }
                color: white; font-size: 0.9rem; transition: 0.2s; display: inline-flex; align-items: center; gap: 8px; justify-content: center;
            }
             .md-btn:hover:not(:disabled) { transform: translateY(-2px); box-shadow: 0 4px 12px rgba(0,0,0,0.15); }
            .md-btn:active:not(:disabled) { transform: translateY(0); }
             .md-btn-save { background: linear-gradient(135deg, #4f46e5, #4338ca); flex: 1; min-width: 150px; }
             .md-btn-cancel { background: #64748b; }
             .md-btn-cancel { background: #64748b; }
             .md-btn-delete { background: #dc2626; margin-left: auto; }
             .md-btn-delete { background: #ef4444; margin-left: auto; }
              
              
             .md-char-count { position:absolute; right:10px; top:35px; font-size:0.7rem; color:var(--md-text-sub); }
             .md-spinner { display: none; width: 14px; height: 14px; border: 2px solid rgba(255,255,255,0.3); border-radius: 50%; border-top-color: #fff; animation: md-spin 0.8s linear infinite; }
            .is-loading .md-spinner { display: inline-block; }
            @keyframes md-spin { to { transform: rotate(360deg); } }


             @media (max-width: 600px) {
             @media (max-width: 600px) {
                 #mippedia-data-app { padding: 14px; margin: 10px 0; border-radius: 12px; }
                 #mippedia-data-app { padding: 16px; margin: 16px 0; border-radius: 14px; }
                 .md-header { position: relative; backdrop-filter: none; }
                 .md-header { flex-direction: column; align-items: flex-start; gap: 12px; }
                 .md-actions { width: 100%; justify-content: flex-start; overflow-x: auto; padding-bottom: 5px;}
                 .md-actions { width: 100%; justify-content: flex-start; overflow-x: auto; padding-bottom: 4px; }
                 .md-btn-icon { padding: 7px 10px; font-size: 0.75rem; }
                 .md-btn-icon { padding: 8px 12px; font-size: 0.8rem; flex-shrink: 0; }
                 .md-ref-grid, .md-social-grid { grid-template-columns: 1fr; }
                 .md-ref-grid, .md-social-grid { grid-template-columns: 1fr; }
                 .md-grid-full { grid-column: span 1; }
                 .md-grid-full { grid-column: span 1; }
                 .md-form-actions { flex-direction: column; width: 100%; }
                 .md-form-actions { flex-direction: column; width: 100%; }
                 .md-btn { width: 100%; margin: 0 !important; }
                 .md-btn { width: 100%; margin: 0 !important; }
                 .md-row-display { padding: 12px 8px; gap: 8px; }
                 .md-row-display { padding: 14px 10px; flex-direction: column; }
                 .md-data-value { font-size: 0.95rem; }
                 .md-row-actions { flex-direction: row; width: 100%; justify-content: flex-end; margin-top: 10px; border-top: 1px dashed #e2e8f0; padding-top: 10px; }
                .md-drag-handle { display:none; } /* Hide drag on mobile to prevent scrolling issues */
             }
             }
             .md-native-render { display: none; }
             .md-native-render { display: none; }
         `;
         `;
         $('<style id="md-styles">').text(css).appendTo('head');
         $('<style>').text(css).appendTo('head');
        if(isDarkMode) $('body').addClass('md-dark');


         // 7. PARSER & PENYIMPANAN DATA
         // 7. PARSER & PENYIMPANAN DATA
Baris 307: Baris 284:
                         dataItems = parsed.items || [];
                         dataItems = parsed.items || [];
                         isLocked = parsed.locked || false;
                         isLocked = parsed.locked || false;
                     } catch(e) { console.error("JSON Error", e); }
                     } catch(e) { console.error("JSON Error", e); showToast('Gagal memuat struktur JSON!', 'error'); }
                 }
                 }
                 return content;  
                 return content;  
Baris 315: Baris 292:
         function buildWikitextVal(item) {
         function buildWikitextVal(item) {
             var val = item.val;
             var val = item.val;
             if (item.linkTarget && item.linkTarget.trim() !== '') return "[[" + item.linkTarget.trim() + "|" + val + "]]";
             if (item.linkTarget && item.linkTarget.trim() !== '') {
                return "[[" + item.linkTarget.trim() + "|" + val + "]]";
            }
             if (item.linkSplit) {
             if (item.linkSplit) {
                 return val.replace(/([a-zA-Z0-9_À-ÿ\- ]+)/g, function(match) {
                 return val.replace(/([a-zA-Z0-9_À-ÿ\- ]+)/g, function(match) {
                     var trimmed = match.trim();
                     var trimmed = match.trim();
                     if (trimmed.length > 2 && trimmed.toLowerCase() !== 'dan' && trimmed.toLowerCase() !== 'atau') return "[[" + trimmed + "]]";
                     if (trimmed.length > 2 && trimmed.toLowerCase() !== 'dan' && trimmed.toLowerCase() !== 'atau') {
                        return "[[" + trimmed + "]]";
                    }
                     return match;
                     return match;
                 });
                 });
             }
             }
             if (item.link) return "[[" + val + "]]";
             if (item.link) {
                return "[[" + val + "]]";
            }
             return val;
             return val;
         }
         }
Baris 329: Baris 312:
         function buildWikitextRef(refObj) {
         function buildWikitextRef(refObj) {
             if (!refObj) return "";
             if (!refObj) return "";
             var title = refObj.title || extractDomain(refObj.url) || "Rujukan";
             var title = refObj.title || "Rujukan";
             var text = refObj.url ? "[" + ensureHttps(refObj.url) + " " + title + "]" : "'''" + title + "'''";
             var text = refObj.url ? "[" + ensureHttps(refObj.url) + " " + title + "]" : "'''" + title + "'''";
             var details = [];
             var details = [];
Baris 335: Baris 318:
             if (refObj.site) details.push("Situs: " + refObj.site);
             if (refObj.site) details.push("Situs: " + refObj.site);
             if (refObj.publisher) details.push("Penerbit: " + refObj.publisher);
             if (refObj.publisher) details.push("Penerbit: " + refObj.publisher);
             if (refObj.date) details.push("Tanggal Akses: " + formatIndonesianDate(refObj.date));
             if (refObj.date) details.push("Diakses: " + formatIndonesianDate(refObj.date));
            if (refObj.type) details.push("Jenis: " + refObj.type + (refObj.subType ? " (" + refObj.subType + ")" : ""));
              
              
             if (details.length > 0) text += " &mdash; <small>" + details.join(" &bull; ") + "</small>";
             if (details.length > 0) text += " &mdash; <small>" + details.join(" &bull; ") + "</small>";
Baris 342: Baris 324:
         }
         }


         function saveData(actionMsg, $btnEl, originalContent, isMinor) {
         function saveData(actionType, $btnEl, originalContent, callback) {
             if ($btnEl) { $btnEl.prop('disabled', true).html('Menyimpan...⏳'); }
             if ($btnEl) $btnEl.addClass('is-loading').prop('disabled', true);
              
              
             var jsonStr = JSON.stringify({ locked: isLocked, items: dataItems });
             var jsonStr = JSON.stringify({ locked: isLocked, items: dataItems });
             var wt = "<!-- MIPPEDIA_DATA_START | " + jsonStr + " -->\n<div class=\"md-native-render\">\n{| class=\"wikitable\"\n! Data !! Nilai !! Referensi\n";
             var wt = "<!-- MIPPEDIA_DATA_START | " + jsonStr + " -->\n";
            wt += "<div class=\"md-native-render\">\n{| class=\"wikitable\"\n! Data !! Nilai !! Referensi\n";
              
              
             dataItems.forEach(function(item) {
             dataItems.forEach(function(item) {
                 wt += "|-\n| " + item.prop + " || " + buildWikitextVal(item) + " || " + buildWikitextRef(item.ref) + "\n";
                var valTxt = buildWikitextVal(item);
                var refTxt = buildWikitextRef(item.ref);
                 wt += "|-\n| " + item.prop + " || " + valTxt + " || " + refTxt + "\n";
             });
             });
             wt += "|}\n</div>\n<!-- MIPPEDIA_DATA_END -->";
             wt += "|}\n</div>\n<!-- MIPPEDIA_DATA_END -->";
Baris 355: Baris 340:
             var newContent;
             var newContent;
             var regex = /<!-- MIPPEDIA_DATA_START \| .*? -->[\s\S]*?<!-- MIPPEDIA_DATA_END -->/;
             var regex = /<!-- MIPPEDIA_DATA_START \| .*? -->[\s\S]*?<!-- MIPPEDIA_DATA_END -->/;
             if (regex.test(originalContent)) newContent = originalContent.replace(regex, wt);
             if (regex.test(originalContent)) {
             else newContent = originalContent.trim() + "\n\n" + wt;
                newContent = originalContent.replace(regex, wt);
             } else {
                newContent = originalContent.trim() + "\n\n" + wt;
            }


             api.postWithToken('csrf', {
             api.postWithToken('csrf', {
                 action: 'edit', title: pageName, text: newContent,  
                 action: 'edit', title: pageName, text: newContent, summary: 'Mippedia Data V8: ' + actionType, minor: false
                summary: 'Mippedia V8: ' + actionMsg, minor: isMinor || false
             }).done(function() {
             }).done(function() {
                 showToast('Berhasil disimpan! Memuat ulang...', 'success');
                 localStorage.removeItem('md_draft_' + pageName); // Hapus draft jika sukses
                setTimeout(function(){ window.location.reload(true); }, 1000);
                if(callback) callback();
                else {
                    showToast('Berhasil disimpan! Memuat ulang...', 'success');
                    setTimeout(function() { window.location.href = location.pathname + "?refresh=" + new Date().getTime(); }, 1000);
                }
             }).fail(function(err) {
             }).fail(function(err) {
                 if ($btnEl) $btnEl.prop('disabled', false).html('Coba Lagi');
                 if ($btnEl) $btnEl.removeClass('is-loading').prop('disabled', false);
                 showToast("Gagal menyimpan: " + err, 'error');
                 showToast("Gagal menyimpan: " + err, 'error');
             });
             });
Baris 374: Baris 365:
             var $app = $('<div id="mippedia-data-app"></div>');
             var $app = $('<div id="mippedia-data-app"></div>');
              
              
             // HEADER & ACTION BAR
             // HEADER
             var $header = $('<div class="md-header"></div>');
             var $header = $('<div class="md-header"></div>');
             var $titleContainer = $('<div class="md-title-container"><h3 class="md-title">' + svgEdit + ' Data Terstruktur V8</h3></div>');
             var $titleContainer = $('<div class="md-title-container"><h3 class="md-title">' + svgEdit + ' Data Terstruktur</h3></div>');
             var $actions = $('<div class="md-actions"></div>');
             var $actions = $('<div class="md-actions"></div>');
              
              
             // Toggle Dark Mode
             // Tombol Ekspor/Impor JSON Baru
            var $darkBtn = $('<button class="md-btn-icon" title="Mode Gelap">' + (isDarkMode ? svgSun : svgMoon) + '</button>');
             var $jsonBtn = $('<button class="md-btn-icon" title="Ekspor/Impor File JSON">' + svgDownload + ' Data JSON</button>');
            $darkBtn.on('click', function() {
                isDarkMode = !isDarkMode;
                localStorage.setItem('md-dark-mode', isDarkMode);
                $('body').toggleClass('md-dark', isDarkMode);
                $(this).html(isDarkMode ? svgSun : svgMoon);
            });
            $actions.append($darkBtn);
 
            // Export CSV
             var $csvBtn = $('<button class="md-btn-icon" title="Ekspor CSV">' + svgDownload + ' CSV</button>');
            $csvBtn.on('click', function() { exportCSV(); });
            $actions.append($csvBtn);
 
            var $jsonBtn = $('<button class="md-btn-icon" title="JSON Tool">' + svgCode + ' JSON</button>');
             $jsonBtn.on('click', function() { showJsonModal(rawContent); });
             $jsonBtn.on('click', function() { showJsonModal(rawContent); });
             $actions.append($jsonBtn);
             $actions.append($jsonBtn);


             if (isSysop) {
             if (isSysop) {
                 var $lockBtn = $('<button class="md-btn-icon">' + (isLocked ? svgUnlock + ' Buka Kunci' : svgLock + ' Kunci') + '</button>');
                 var $lockBtn = $('<button class="md-btn-icon ' + (isLocked ? 'md-btn-unlock' : 'md-btn-lock') + '">' + (isLocked ? svgUnlock + ' Buka Kunci' : svgLock + ' Kunci') + ' <span class="md-spinner"></span></button>');
                 $lockBtn.on('click', function() {
                 $lockBtn.on('click', function() {
                     isLocked = !isLocked;
                     isLocked = !isLocked;
                     saveData(isLocked ? 'Mengunci data' : 'Membuka kunci data', $(this), rawContent, true);
                     saveData(isLocked ? 'Mengunci data' : 'Membuka kunci data', $(this), rawContent);
                 });
                 });
                 $actions.append($lockBtn);
                 $actions.append($lockBtn);
Baris 408: Baris 385:


             if (!isLocked || isSysop) {
             if (!isLocked || isSysop) {
                 var $addBtn = $('<button class="md-btn-icon" style="background:var(--md-primary); color:white; border-color:var(--md-primary);">' + svgEdit + ' Tambah</button>');
                 var $addBtn = $('<button class="md-btn-icon" style="background:#4f46e5; color:white; border-color:#4338ca;">' + svgEdit + ' Tambah Baru</button>');
                 $addBtn.on('click', function() { showForm(-1, rawContent); });
                 $addBtn.on('click', function() { showForm(-1, rawContent); });
                 $actions.append($addBtn);
                 $actions.append($addBtn);
Baris 416: Baris 393:
             $app.append($header);
             $app.append($header);


             // FILTER TABS & SEARCH
             // SEARCH BAR
             if (dataItems.length > 1) {
             if (dataItems.length > 2) {
                var $tabArea = $('<div class="md-tabs"><button class="md-tab active" data-filter="all">Semua Data</button><button class="md-tab" data-filter="social">Punya Sosmed</button><button class="md-tab" data-filter="ref">Ada Referensi</button></div>');
                 var $searchBox = $('<div class="md-search-box"><span class="md-search-icon">' + svgSearch + '</span><input type="text" class="md-search-input" placeholder="Cari data terstruktur (misal: Tanggal Lahir)..."></div>');
                 var $searchBox = $('<div class="md-search-box"><span class="md-search-icon">' + svgSearch + '</span><input type="text" class="md-search-input" placeholder="Cari data (label/nilai)..."></div>');
                 $searchBox.find('input').on('keyup input', function() {
               
                     var q = $(this).val().toLowerCase();
                $tabArea.find('.md-tab').on('click', function() {
                    $tabArea.find('.md-tab').removeClass('active'); $(this).addClass('active');
                    filterList();
                });
                 $searchBox.find('input').on('keyup input', filterList);
               
                $app.append($tabArea).append($searchBox);
 
                function filterList() {
                     var q = $searchBox.find('input').val().toLowerCase();
                    var filter = $tabArea.find('.active').data('filter');
                   
                     $app.find('.md-row-display').each(function() {
                     $app.find('.md-row-display').each(function() {
                         var $r = $(this);
                         var text = $(this).text().toLowerCase();
                        var text = $r.text().toLowerCase();
                         $(this).toggle(text.indexOf(q) !== -1);
                         var hasSocial = $r.find('.md-social-group').length > 0;
                        var hasRef = $r.find('.md-ref-container').length > 0;
                       
                        var matchSearch = text.indexOf(q) !== -1;
                        var matchTab = filter === 'all' ? true : (filter === 'social' ? hasSocial : hasRef);
                       
                        $r.toggle(matchSearch && matchTab);
                     });
                     });
                 }
                 });
                $app.append($searchBox);
             }
             }


             // DAFTAR BARIS DATA (List)
             // DAFTAR BARIS DATA
             var $list = $('<div class="md-list"></div>');
             var $list = $('<div class="md-list"></div>');
             if (dataItems.length === 0) {
             if (dataItems.length === 0) {
                 $list.append('<div style="text-align:center; padding: 30px 10px; color:var(--md-text-sub); border:2px dashed var(--md-border); border-radius:12px; margin-top:10px;">Belum ada data. Klik <b>Tambah</b> untuk mulai menyusun mahakarya.</div>');
                 $list.append('<div style="text-align:center; padding: 40px 20px; background:#f8fafc; border-radius:12px; border:2px dashed #cbd5e1; color:#64748b;"><h4>Belum ada data!</h4><p style="font-size:0.9rem; margin-top:8px;">Klik tombol <b>Tambah Baru</b> di atas untuk mulai membuat struktur.</p></div>');
             } else {
             } else {
                 dataItems.forEach(function(item, index) {
                 dataItems.forEach(function(item, index) {
                     var $row = $('<div class="md-row-display" draggable="true" data-index="'+index+'"></div>');
                     var $row = $('<div class="md-row-display"></div>');
                    var $dragHandle = $('<div class="md-drag-handle" title="Tahan & Geser">' + svgDrag + '</div>');
                   
                     var $info = $('<div class="md-data-group"></div>');
                     var $info = $('<div class="md-data-group"></div>');
                     $info.append('<span class="md-data-label">' + item.prop + '</span>');
                     $info.append('<span class="md-data-label">' + item.prop + '</span>');
                      
                      
                     // Render Nilai Data
                     // RENDER NILAI DATA
                    var displayValHtml = '';
                     var rawVal = item.val || '';
                     var rawVal = item.val || '';
                    var displayValHtml = rawVal;
 
                     if (rawVal.match(/^https?:\/\//i)) {
                     if (rawVal.match(/^https?:\/\//i)) {
                         displayValHtml = '<a href="' + rawVal + '" target="_blank">' + extractDomain(rawVal) + ' ' + svgExternal + '</a>';
                        var domain = extractDomain(rawVal);
                         displayValHtml = '<a href="' + rawVal + '" target="_blank" style="color:#2563eb; text-decoration:none;">' + domain + '</a>';
                     } else if (item.linkTarget && item.linkTarget.trim() !== '') {
                     } else if (item.linkTarget && item.linkTarget.trim() !== '') {
                         displayValHtml = '<a href="' + mw.util.getUrl(item.linkTarget.trim()) + '">' + rawVal + '</a>';
                         displayValHtml = '<a href="' + mw.util.getUrl(item.linkTarget.trim()) + '" style="color:#2563eb; text-decoration:none;">' + rawVal + '</a>';
                     } else if (item.linkSplit) {
                     } else if (item.linkSplit) {
                         var parts = rawVal.split(/([,/\s]+dan\s+|[,/\s]+atau\s+|[,/]+)/gi);
                         var parts = rawVal.split(/([,/\s]+dan\s+|[,/\s]+atau\s+|[,/]+)/gi);
                         displayValHtml = parts.map(function(p) {
                         displayValHtml = parts.map(function(p) {
                             var trimmed = p.trim();
                             var trimmed = p.trim();
                             if (trimmed && !p.match(/^[,/\s]+$/) && !/^(dan|atau)$/i.test(trimmed)) {
                             if (trimmed && !p.match(/^[,/\s]+$/) && trimmed.toLowerCase() !== 'dan' && trimmed.toLowerCase() !== 'atau') {
                                 return '<a href="' + mw.util.getUrl(trimmed) + '">' + trimmed + '</a>';
                                 return '<a href="' + mw.util.getUrl(trimmed) + '" style="color:#2563eb; text-decoration:none;">' + trimmed + '</a>';
                             }
                             }
                             return p;
                             return p;
                         }).join('');
                         }).join('');
                     } else if (item.link) {
                     } else if (item.link) {
                         displayValHtml = '<a href="' + mw.util.getUrl(rawVal) + '">' + rawVal + '</a>';
                         displayValHtml = '<a href="' + mw.util.getUrl(rawVal) + '" style="color:#2563eb; text-decoration:none;">' + rawVal + '</a>';
                    } else {
                        displayValHtml = rawVal;
                     }
                     }


Baris 482: Baris 443:
                     $valWrap.append('<span class="md-data-value">' + displayValHtml + '</span>');
                     $valWrap.append('<span class="md-data-value">' + displayValHtml + '</span>');
                      
                      
                     var $copyBtn = $('<button class="md-btn-icon" style="padding:4px; border:none; background:transparent;" title="Salin teks">' + svgCopy + '</button>');
                     var $copyBtn = $('<button class="md-btn-copy" title="Salin nilai teks">' + svgCopy + '</button>');
                     $copyBtn.on('click', function() { navigator.clipboard.writeText(rawVal); showToast('Teks disalin: ' + rawVal, 'success'); });
                     $copyBtn.on('click', function() {
                        navigator.clipboard.writeText(rawVal);
                        showToast('Teks disalin!', 'success');
                    });
                     $valWrap.append($copyBtn);
                     $valWrap.append($copyBtn);
                     $info.append($valWrap);
                     $info.append($valWrap);


                     // Render Media Sosial (+ Twitch dll)
                     // RENDER MEDIA SOSIAL & MUSIK
                     if (item.isPersonOrg && item.socials) {
                     if (item.isPersonOrg && item.socials) {
                         var $socialGroup = $('<div class="md-social-group"></div>');
                         var $socialGroup = $('<div class="md-social-group"></div>');
Baris 494: Baris 458:
                             var uname = item.socials[key];
                             var uname = item.socials[key];
                             if (uname) {
                             if (uname) {
                                 hasSocial = true; var platform = SOCIAL_PLATFORMS[key];
                                 hasSocial = true;
                                var platform = SOCIAL_PLATFORMS[key];
                                 var fullUrl = platform.base + uname.replace(/^@/, '');
                                 var fullUrl = platform.base + uname.replace(/^@/, '');
                                 $socialGroup.append('<a class="md-social-badge" href="'+fullUrl+'" target="_blank" style="background:'+platform.color+';">'+platform.icon+' '+platform.name+'</a>');
                                 var $badge = $('<a class="md-social-badge" href="' + fullUrl + '" target="_blank" style="background:' + platform.color + ';">' + platform.icon + ' ' + platform.name + '</a>');
                                $socialGroup.append($badge);
                             }
                             }
                         });
                         });
Baris 502: Baris 468:
                     }
                     }
                      
                      
                     // Render FITUR AKORDEON REFERENSI
                     // RENDER REFERENSI EKSPLISIT (V8 ACCORDION)
                     if (item.ref && (item.ref.url || item.ref.title)) {
                     if (item.ref && (item.ref.url || item.ref.title)) {
                         var ref = item.ref;
                         var ref = item.ref;
                         var $refContainer = $('<div class="md-ref-container"></div>');
                         var $refContainer = $('<div class="md-ref-container"></div>');
                        var refTitle = ref.title || extractDomain(ref.url) || "Rujukan Eksternal";
                          
                          
                        // Toggle Button
                         var siteNameLabel = ref.site || extractDomain(ref.url) || "Referensi";
                         var qScore = getRefQuality(ref);
                         var $refSummary = $('<div class="md-ref-summary" title="Klik untuk lihat detail referensi"><span class="md-ref-tag">' + svgRef + ' 1 Referensi (' + siteNameLabel + ')</span><span class="md-ref-toggle">' + svgChevronDown + '</span></div>');
                        var qColor = qScore >= 4 ? '#10b981' : (qScore >= 2 ? '#f59e0b' : '#ef4444');
                        var $refBody = $('<div class="md-ref-body"></div>');
                         var $toggleBtn = $('<button class="md-ref-toggle">' + svgRef + ' Lihat Referensi <span class="md-q-indicator" style="background:'+qColor+';" title="Kualitas Ref: '+qScore+'/5"></span></button>');
                          
                          
                         // Panel Detail
                         var refTitle = ref.title || "Sumber Rujukan";
                         var $refPanel = $('<div class="md-ref-panel"></div>');
                        $refBody.append('<span class="md-ref-header">' + refTitle + '</span>');
                         $refPanel.append('<div class="md-ref-header">' + refTitle + '</div>');
 
                         var $detailsGrid = $('<div class="md-ref-details-grid"></div>');
                         if (ref.author) $detailsGrid.append('<div class="md-ref-detail-row"><span class="md-ref-lbl">Penulis:</span><span class="md-ref-val">' + ref.author + '</span></div>');
                        if (ref.site) $detailsGrid.append('<div class="md-ref-detail-row"><span class="md-ref-lbl">Situs/Penerbit:</span><span class="md-ref-val">' + ref.site + (ref.publisher ? ' / ' + ref.publisher : '') + '</span></div>');
                        if (ref.date) $detailsGrid.append('<div class="md-ref-detail-row"><span class="md-ref-lbl">Diakses:</span><span class="md-ref-val">' + formatIndonesianDate(ref.date) + '</span></div>');
                        if (ref.type) $detailsGrid.append('<div class="md-ref-detail-row"><span class="md-ref-lbl">Tipe:</span><span class="md-ref-val">' + ref.type + (ref.subType ? ' - ' + ref.subType : '') + '</span></div>');
                          
                          
                         var $detailsGrid = $('<div class="md-ref-details-grid"></div>');
                         $refBody.append($detailsGrid);
                        if(ref.author) $detailsGrid.append('<div class="md-ref-detail-row"><span class="md-ref-lbl">Penulis:</span><span class="md-ref-val">'+ref.author+'</span></div>');
                        if(ref.site) $detailsGrid.append('<div class="md-ref-detail-row"><span class="md-ref-lbl">Situs:</span><span class="md-ref-val">'+ref.site+'</span></div>');
                        if(ref.publisher) $detailsGrid.append('<div class="md-ref-detail-row"><span class="md-ref-lbl">Penerbit:</span><span class="md-ref-val">'+ref.publisher+'</span></div>');
                        if(ref.date) $detailsGrid.append('<div class="md-ref-detail-row"><span class="md-ref-lbl">Akses:</span><span class="md-ref-val">'+formatIndonesianDate(ref.date)+'</span></div>');
                        $refPanel.append($detailsGrid);
 
                        var $refBottom = $('<div class="md-ref-bottom"></div>');
                        if (ref.type) {
                            var tLbl = ref.type + (ref.subType ? ' • ' + ref.subType : '');
                            $refBottom.append('<span class="md-ref-badge">' + tLbl + '</span>');
                        } else {
                            $refBottom.append('<span></span>'); // spacer
                        }


                        // Tombol Kunjungi Tautan Langsung
                         if (ref.url) {
                         if (ref.url) {
                             var safeUrl = ensureHttps(ref.url);
                             var safeUrl = ensureHttps(ref.url);
                             $refBottom.append('<a href="' + safeUrl + '" target="_blank" class="md-btn-direct">' + svgExternal + ' Kunjungi</a>');
                             $refBody.append('<a href="' + safeUrl + '" target="_blank" class="md-btn-visit">' + svgExternal + ' Kunjungi Situs</a>');
                         }
                         }
                        $refPanel.append($refBottom);


                        // Logic Buka-Tutup (Akordeon)
                         $refSummary.on('click', function() {
                         $toggleBtn.on('click', function() {
                             $refBody.slideToggle(200);
                             var isOpen = $(this).hasClass('open');
                             $(this).toggleClass('open');
                             $(this).toggleClass('open');
                            if(isOpen) {
                                $refPanel.slideUp(200);
                                $(this).html(svgRef + ' Lihat Referensi <span class="md-q-indicator" style="background:'+qColor+';"></span>');
                            } else {
                                $refPanel.slideDown(200).css('display', 'flex');
                                $(this).html(svgRef + ' Tutup Detail');
                            }
                         });
                         });


                         $refContainer.append($toggleBtn).append($refPanel);
                         $refContainer.append($refSummary).append($refBody);
                         $info.append($refContainer);
                         $info.append($refContainer);
                     }
                     }
                      
                      
                     $row.append($dragHandle).append($info);
                     $row.append($info);


                     if (!isLocked || isSysop) {
                     if (!isLocked || isSysop) {
                         var $actionGroup = $('<div style="display:flex; flex-direction:column; gap:4px; align-items:flex-end;"></div>');
                         var $actionsGroup = $('<div class="md-row-actions"></div>');
                         var $editIcon = $('<button class="md-btn-icon" style="padding:6px;">' + svgEdit + ' Edit</button>');
                       
                         $editIcon.on('click', function() { showForm(index, rawContent); });
                        // Urutkan Atas/Bawah (Fitur Baru)
                         var $btnUp = $('<button class="md-btn-icon" style="padding:4px 6px;" title="Pindah ke Atas" ' + (index === 0 ? 'disabled style="opacity:0.3; cursor:not-allowed;"' : '') + '>' + svgArrowUp + '</button>');
                         var $btnDown = $('<button class="md-btn-icon" style="padding:4px 6px;" title="Pindah ke Bawah" ' + (index === dataItems.length-1 ? 'disabled style="opacity:0.3; cursor:not-allowed;"' : '') + '>' + svgArrowDown + '</button>');
                          
                          
                         var $cloneIcon = $('<button class="md-btn-icon" style="padding:6px; background:transparent; border:none; color:var(--md-text-sub);" title="Duplikasi Data">' + svgClone + '</button>');
                         $btnUp.on('click', function() {
                         $cloneIcon.on('click', function() {  
                            if(index > 0) {
                             var cloned = JSON.parse(JSON.stringify(item));
                                var temp = dataItems[index-1];
                            dataItems.splice(index+1, 0, cloned);
                                dataItems[index-1] = dataItems[index];
                            saveData('Menduplikasi baris', null, rawContent, true);
                                dataItems[index] = temp;
                                saveData('Mengubah urutan', $(this), rawContent);
                            }
                        });
                         $btnDown.on('click', function() {
                             if(index < dataItems.length-1) {
                                var temp = dataItems[index+1];
                                dataItems[index+1] = dataItems[index];
                                dataItems[index] = temp;
                                saveData('Mengubah urutan', $(this), rawContent);
                            }
                         });
                         });


                         $actionGroup.append($editIcon).append($cloneIcon);
                         var $editIcon = $('<button class="md-btn-icon edit-btn" style="padding:6px 12px; margin-top:4px;">' + svgEdit + ' Edit</button>');
                         $row.append($actionGroup);
                        $editIcon.on('click', function() { showForm(index, rawContent); });
 
                        var $orderWrap = $('<div style="display:flex; gap:4px; justify-content:flex-end;"></div>').append($btnUp).append($btnDown);
                        $actionsGroup.append($orderWrap).append($editIcon);
                         $row.append($actionsGroup);
                     }
                     }
                    // Simple Drag and Drop Event Binding
                    $row.on('dragstart', function(e) { $(this).addClass('dragging'); e.originalEvent.dataTransfer.setData('text/plain', index); });
                    $row.on('dragend', function() { $(this).removeClass('dragging'); });
                    $row.on('dragover', function(e) { e.preventDefault(); $(this).css('border-top', '3px solid var(--md-primary)'); });
                    $row.on('dragleave', function() { $(this).css('border-top', ''); });
                    $row.on('drop', function(e) {
                        e.preventDefault(); $(this).css('border-top', '');
                        var oldIdx = parseInt(e.originalEvent.dataTransfer.getData('text/plain'), 10);
                        var newIdx = parseInt($(this).data('index'), 10);
                        if (oldIdx === newIdx) return;
                        var movedItem = dataItems.splice(oldIdx, 1)[0];
                        dataItems.splice(newIdx, 0, movedItem);
                        saveData('Mengubah urutan baris', null, rawContent, true);
                    });
                     $list.append($row);
                     $list.append($row);
                 });
                 });
Baris 601: Baris 547:
         }
         }


        // Ekspor ke CSV Generator
         // 9. FORM EDIT DENGAN PRESET & PLATFORM LENGKAP
        function exportCSV() {
            if(dataItems.length === 0) return showToast('Tidak ada data untuk diekspor', 'error');
            var csv = 'Label,Nilai,Tipe Referensi,URL Referensi\n';
            dataItems.forEach(function(item) {
                var l = '"'+(item.prop||'').replace(/"/g,'""')+'"';
                var v = '"'+(item.val||'').replace(/"/g,'""')+'"';
                var rt = '"'+((item.ref && item.ref.type) ? item.ref.type : '')+'"';
                var ru = '"'+((item.ref && item.ref.url) ? item.ref.url : '')+'"';
                csv += [l, v, rt, ru].join(',') + '\n';
            });
            var blob = new Blob([csv], { type: 'text/csv;charset=utf-8;' });
            var link = document.createElement('a');
            var url = URL.createObjectURL(blob);
            link.setAttribute('href', url); link.setAttribute('download', 'Data_Mippedia_' + getTodayString() + '.csv');
            link.style.visibility = 'hidden'; document.body.appendChild(link); link.click(); document.body.removeChild(link);
            showToast('File CSV berhasil diunduh!', 'success');
        }
 
         // 9. FORM EDIT V8
         function showForm(index, rawContent) {
         function showForm(index, rawContent) {
             var $container = $('#md-form-container');
             var $container = $('#md-form-container');
Baris 627: Baris 554:
             var isNew = index === -1;
             var isNew = index === -1;
             var currentData = isNew ? { prop: '', val: '', link: false, linkTarget: '', linkSplit: false, ref: {}, isPersonOrg: false, socials: {} } : dataItems[index];
             var currentData = isNew ? { prop: '', val: '', link: false, linkTarget: '', linkSplit: false, ref: {}, isPersonOrg: false, socials: {} } : dataItems[index];
           
            // Cek Draft LocalStorage
            var draftKey = 'md_draft_' + pageName;
            var savedDraft = localStorage.getItem(draftKey);
            if (isNew && savedDraft) {
                try {
                    currentData = JSON.parse(savedDraft);
                    showToast('Memulihkan draft yang belum tersimpan...', 'warning');
                } catch(e) {}
            }
             var currentRef = currentData.ref || {};
             var currentRef = currentData.ref || {};
             var currentSocials = currentData.socials || {};
             var currentSocials = currentData.socials || {};


             var $form = $('<div class="md-form-box"></div>');
             var $form = $('<div class="md-form-box"></div>');
             var $closeIcon = $('<button style="background:none;border:none;cursor:pointer;color:var(--md-text-sub);font-size:1.2rem;line-height:1;">&times;</button>');
             $form.append('<h4 class="md-form-title">' + (isNew ? 'Tambah Data Baru' : 'Edit Data Terstruktur') + '</h4>');
            $closeIcon.on('click', function(){ $container.empty(); });
           
            var $titleWrap = $('<div class="md-form-title"></div>').append('<span>' + (isNew ? 'Tambah Data Baru' : 'Edit Data Terstruktur') + '</span>').append($closeIcon);
            $form.append($titleWrap);
           
            // Label Data + Auto Capitalize + Presets
            var $propGroup = $('<div class="md-form-group"><label>Label Data (Kategori)</label></div>');
            var $propInp = $('<input type="text" id="md-inp-prop" class="md-input" placeholder="Misal: Tanggal Lahir" value="' + (currentData.prop || '') + '">');
            $propInp.on('blur', function() { $(this).val(toTitleCase($(this).val())); }); // Auto Format
            $propGroup.append($propInp);
              
              
             var $presetWrap = $('<div style="margin-top:6px;"></div>');
            // Label Data
             var $propGroup = $('<div class="md-form-group"><label>Label Data (Cth: Pekerjaan, Sutradara)</label><input type="text" id="md-inp-prop" class="md-input md-track-draft" value="' + (currentData.prop || '') + '"></div>');
            var $presetWrap = $('<div class="md-preset-wrapper"></div>');
             PRESET_LABELS.forEach(function(lbl) {
             PRESET_LABELS.forEach(function(lbl) {
                 var $pill = $('<span class="md-preset-pill">' + lbl + '</span>');
                 var $pill = $('<span class="md-preset-pill">' + lbl + '</span>');
                 $pill.on('click', function() { $propInp.val(lbl); $propInp.removeClass('error'); });
                 $pill.on('click', function() { $('#md-inp-prop').val(lbl).trigger('input'); });
                 $presetWrap.append($pill);
                 $presetWrap.append($pill);
             });
             });
Baris 652: Baris 582:
             $form.append($propGroup);
             $form.append($propGroup);
              
              
             // Nilai Data & Char Counter
             // Nilai Data
             var $valBox = $('<div class="md-form-group"></div>');
             var $valBox = $('<div class="md-form-group"></div>');
             $valBox.append('<label>Nilai Data Utama</label>');
             $valBox.append('<label>Nilai / Konten Data</label><input type="text" id="md-inp-val" class="md-input md-track-draft" value="' + (currentData.val || '') + '">');
            var $valInp = $('<input type="text" id="md-inp-val" class="md-input" value="' + (currentData.val || '') + '">');
           
             var $charCount = $('<span class="md-char-count">0</span>');
             var $wikilinkOpts = $('<div style="margin-top:10px; display:flex; flex-direction:column; gap:8px; background:#f8fafc; padding:12px; border-radius:10px; border:1px solid #e2e8f0;"></div>');
             $valInp.on('input', function() { $charCount.text($(this).val().length); }).trigger('input');
             var chkLink = currentData.link ? 'checked' : '';
            var chkSplit = currentData.linkSplit ? 'checked' : '';
           
            $wikilinkOpts.append('<label style="display:flex; align-items:center; gap:8px; font-size:0.85rem; font-weight:700; cursor:pointer;"><input type="checkbox" id="md-inp-link" class="md-track-draft" ' + chkLink + '> Jadikan Wikilink Standar</label>');
            $wikilinkOpts.append('<label style="display:flex; align-items:center; gap:8px; font-size:0.85rem; font-weight:700; cursor:pointer;"><input type="checkbox" id="md-inp-split" class="md-track-draft" ' + chkSplit + '> Smart Split Wikilink (Pecah koma/dan)</label>');
              
              
             $valBox.append($valInp).append($charCount);
             var $pipedGroup = $('<div style="margin-top:6px;"><label style="font-size:0.8rem; color:#475569;">Target Halaman Piped (Opsional):</label><input type="text" id="md-inp-target" class="md-input md-track-draft" style="padding:8px 12px; font-size:0.85rem;" placeholder="Contoh: Diskografi Rumi Haitami" value="' + (currentData.linkTarget || '') + '"></div>');
            $wikilinkOpts.append($pipedGroup);
              
              
            var $wikilinkOpts = $('<div style="margin-top:8px; display:flex; flex-direction:column; gap:8px; background:var(--md-surface); padding:10px; border-radius:8px; border:1px solid var(--md-border);"></div>');
            $wikilinkOpts.append('<label style="display:flex; align-items:center; gap:8px; font-size:0.82rem; font-weight:700; cursor:pointer;"><input type="checkbox" id="md-inp-link" ' + (currentData.link?'checked':'') + '> Buat Wikilink Standar</label>');
            $wikilinkOpts.append('<label style="display:flex; align-items:center; gap:8px; font-size:0.82rem; font-weight:700; cursor:pointer;"><input type="checkbox" id="md-inp-split" ' + (currentData.linkSplit?'checked':'') + '> Pisah Otomatis (Dan/Atau/Koma)</label>');
            $wikilinkOpts.append('<div style="margin-top:4px;"><label style="font-size:0.75rem; color:var(--md-text-sub);">Halaman Target (Opsional):</label><input type="text" id="md-inp-target" class="md-input" style="padding:6px; font-size:0.8rem;" value="' + (currentData.linkTarget || '') + '"></div>');
             $valBox.append($wikilinkOpts);
             $valBox.append($wikilinkOpts);
             $form.append($valBox);
             $form.append($valBox);


             // SOSIAL MEDIA
             // MEDIA SOSIAL
             var $socialSec = $('<div class="md-form-group" style="margin-top:16px;"></div>');
             var $socialSec = $('<div class="md-form-group" style="margin-top:20px;"></div>');
             $socialSec.append('<label style="display:flex; align-items:center; gap:8px; cursor:pointer; background:rgba(79,70,229,0.1); padding:10px; border-radius:8px; font-weight:700; color:var(--md-primary);"><input type="checkbox" id="md-chk-person" ' + (currentData.isPersonOrg?'checked':'') + '> Aktifkan Profil Sosial / Musik</label>');
            var chkPerson = currentData.isPersonOrg ? 'checked' : '';
             $socialSec.append('<label style="display:flex; align-items:center; gap:8px; cursor:pointer; background:#e0e7ff; padding:12px; border-radius:10px; font-weight:800; color:#3730a3;"><input type="checkbox" id="md-chk-person" class="md-track-draft" ' + chkPerson + '> Aktifkan Profil Sosmed & Musik</label>');
              
              
             var $socialGrid = $('<div class="md-social-grid" id="md-social-box" style="display:' + (currentData.isPersonOrg ? 'grid' : 'none') + '; margin-top:8px;"></div>');
             var $socialGrid = $('<div class="md-social-grid" id="md-social-box" style="display:' + (currentData.isPersonOrg ? 'grid' : 'none') + '; margin-top:10px;"></div>');
             Object.keys(SOCIAL_PLATFORMS).forEach(function(key) {
             Object.keys(SOCIAL_PLATFORMS).forEach(function(key) {
                 var p = SOCIAL_PLATFORMS[key];
                 var p = SOCIAL_PLATFORMS[key];
                 $socialGrid.append('<div><label style="font-size:0.75rem; color:var(--md-text-sub);">' + p.name + '</label><input type="text" id="md-soc-' + key + '" class="md-input" placeholder="@username" value="' + (currentSocials[key]||'') + '"></div>');
                var valUname = currentSocials[key] || '';
                 $socialGrid.append('<div><label style="font-size:0.8rem; color:#334155; font-weight:700;">' + p.name + '</label><input type="text" id="md-soc-' + key + '" class="md-input md-track-draft" placeholder="Username" value="' + valUname + '"></div>');
             });
             });
             $socialSec.append($socialGrid);
             $socialSec.append($socialGrid);
             $form.append($socialSec);
             $form.append($socialSec);


             // REFERENSI
             // RUJUKAN LENGKAP (Otomatis deteksi domain)
             var $refArea = $('<div class="md-form-group" style="margin-top:20px;"></div>');
             var $refArea = $('<div class="md-form-group" style="margin-top:24px;"></div>');
             $refArea.append('<label style="font-size:0.95rem; font-weight:800; color:var(--md-text-main); border-bottom:1px solid var(--md-border); padding-bottom:5px;">Sumber Referensi</label>');
             $refArea.append('<label style="font-size:1.05rem; font-weight:800; color:#0f172a; border-bottom:2px solid #e2e8f0; padding-bottom:8px;">Sumber Referensi</label>');
           
            var $refGrid = $('<div class="md-ref-grid" style="margin-top:12px;"></div>');
              
              
            var $refGrid = $('<div class="md-ref-grid" style="margin-top:10px;"></div>');
             var $typeSel = $('<select id="md-ref-type" class="md-select md-track-draft"><option value="">-- Pilih Kategori --</option></select>');
             var $typeSel = $('<select id="md-ref-type" class="md-select"><option value="">-- Tipe Utama --</option></select>');
             Object.keys(REF_TYPES).forEach(function(t) {
             Object.keys(REF_TYPES).forEach(function(t) { $typeSel.append('<option value="'+t+'" '+(currentRef.type===t?'selected':'')+'>'+t+'</option>'); });
                var sel = currentRef.type === t ? 'selected' : '';
             var $subTypeSel = $('<select id="md-ref-subtype" class="md-select"><option value="">-- Sub-Tipe --</option></select>');
                $typeSel.append('<option value="' + t + '" ' + sel + '>' + t + '</option>');
            });
             var $subTypeSel = $('<select id="md-ref-subtype" class="md-select md-track-draft"><option value="">-- Sub Kategori --</option></select>');
              
              
             function updateSubTypes(mainType, selectedSub) {
             function updateSubTypes(mainType, selectedSub) {
                 $subTypeSel.empty().append('<option value="">-- Sub-Tipe --</option>');
                 $subTypeSel.empty().append('<option value="">-- Sub Kategori --</option>');
                 if (mainType && REF_TYPES[mainType]) {
                 if (mainType && REF_TYPES[mainType]) {
                     REF_TYPES[mainType].forEach(function(st) { $subTypeSel.append('<option value="'+st+'" '+(selectedSub===st?'selected':'')+'>'+st+'</option>'); });
                     REF_TYPES[mainType].forEach(function(st) {
                        var sel = selectedSub === st ? 'selected' : '';
                        $subTypeSel.append('<option value="' + st + '" ' + sel + '>' + st + '</option>');
                    });
                 }
                 }
             }
             }
Baris 698: Baris 638:
             updateSubTypes(currentRef.type, currentRef.subType);
             updateSubTypes(currentRef.type, currentRef.subType);


             $refGrid.append('<div><label style="font-size:0.75rem;">Tipe Utama</label></div>').find('div').last().append($typeSel);
             $refGrid.append('<div><label style="font-size:0.8rem;">Kategori</label></div>').find('div').last().append($typeSel);
             $refGrid.append('<div><label style="font-size:0.75rem;">Sub-Tipe</label></div>').find('div').last().append($subTypeSel);
             $refGrid.append('<div><label style="font-size:0.8rem;">Sub Kategori</label></div>').find('div').last().append($subTypeSel);


            // Auto-Fill URL Logic
             var $urlInput = $('<input type="url" id="md-ref-url" class="md-input md-track-draft" placeholder="https://..." value="' + (currentRef.url || '') + '">');
             var $urlInput = $('<input type="url" id="md-ref-url" class="md-input" placeholder="https://..." value="' + (currentRef.url || '') + '">');
            var $siteInp = $('<input type="text" id="md-ref-site" class="md-input" placeholder="Nama Situs" value="' + (currentRef.site || '') + '">');
            var $titleInp = $('<input type="text" id="md-ref-title" class="md-input" placeholder="Judul Halaman" value="' + (currentRef.title || '') + '">');
           
             $urlInput.on('blur', function() {
             $urlInput.on('blur', function() {
                 var u = ensureHttps($(this).val()); $(this).val(u);
                 var u = ensureHttps($(this).val());
                 if (u) {
                $(this).val(u);
                var $siteInp = $('#md-ref-site');
                // Fitur Baru: Otomatis isi nama situs dari URL
                 if (u && !$siteInp.val().trim()) {
                     var domain = extractDomain(u);
                     var domain = extractDomain(u);
                     if (!$siteInp.val().trim()) $siteInp.val(domain);
                     $siteInp.val(domain.charAt(0).toUpperCase() + domain.slice(1));
                    if (!$titleInp.val().trim()) $titleInp.val(domain);
                     $siteInp.trigger('input');
                    // Auto Select Tipe
                    if(u.indexOf('youtube.com') !== -1 || u.indexOf('youtu.be') !== -1) $typeSel.val('Video').trigger('change');
                     else if(u.indexOf('instagram.com') !== -1 || u.indexOf('twitter.com') !== -1 || u.indexOf('x.com') !== -1) $typeSel.val('Media Sosial').trigger('change');
                 }
                 }
             });
             });


             $refGrid.append('<div class="md-grid-full"><label style="font-size:0.75rem;">URL Rujukan</label></div>').find('div').last().append($urlInput);
             $refGrid.append('<div class="md-grid-full"><label style="font-size:0.8rem;">URL Website (Link)</label></div>').find('div').last().append($urlInput);
             $refGrid.append('<div><label style="font-size:0.75rem;">Judul Halaman</label></div>').find('div').last().append($titleInp);
             $refGrid.append('<div><label style="font-size:0.8rem;">Judul Halaman / Artikel</label><input type="text" id="md-ref-title" class="md-input md-track-draft" placeholder="Judul" value="' + (currentRef.title || '') + '"></div>');
             $refGrid.append('<div><label style="font-size:0.75rem;">Nama Situs</label></div>').find('div').last().append($siteInp);
             $refGrid.append('<div><label style="font-size:0.8rem;">Nama Situs / Portal</label><input type="text" id="md-ref-site" class="md-input md-track-draft" placeholder="Nama Situs" value="' + (currentRef.site || '') + '"></div>');
             $refGrid.append('<div><label style="font-size:0.75rem;">Penulis/Kreator</label><input type="text" id="md-ref-author" class="md-input" value="' + (currentRef.author || '') + '"></div>');
             $refGrid.append('<div><label style="font-size:0.8rem;">Penulis (Opsional)</label><input type="text" id="md-ref-author" class="md-input md-track-draft" placeholder="Nama Penulis" value="' + (currentRef.author || '') + '"></div>');
             $refGrid.append('<div><label style="font-size:0.75rem;">Penerbit (Opsional)</label><input type="text" id="md-ref-publisher" class="md-input" value="' + (currentRef.publisher || '') + '"></div>');
             $refGrid.append('<div><label style="font-size:0.8rem;">Penerbit (Opsional)</label><input type="text" id="md-ref-publisher" class="md-input md-track-draft" placeholder="Penerbit" value="' + (currentRef.publisher || '') + '"></div>');
              
              
             var $dateBox = $('<div><label style="font-size:0.75rem;">Tgl Akses</label></div>');
             var $dateBox = $('<div><label style="font-size:0.8rem;">Tanggal Akses</label></div>');
             var $dateInpWrap = $('<div style="display:flex; gap:4px;"></div>');
             var $dateInpWrap = $('<div style="display:flex; gap:8px;"></div>');
             var $dateInp = $('<input type="date" id="md-ref-date" class="md-input" value="' + (currentRef.date || '') + '">');
             var $dateInp = $('<input type="date" id="md-ref-date" class="md-input md-track-draft" value="' + (currentRef.date || '') + '">');
             var $todayBtn = $('<button type="button" class="md-btn-icon" style="padding:4px 6px;" title="Set Hari Ini">Cetak H.Ini</button>');
             var $todayBtn = $('<button type="button" class="md-btn-icon" style="padding:6px 10px; font-size:0.8rem; border-color:#cbd5e1;" title="Set Hari Ini">Hari Ini</button>');
             $todayBtn.on('click', function() { $dateInp.val(getTodayString()); });
             $todayBtn.on('click', function() { $dateInp.val(getTodayString()).trigger('input'); });
             $dateInpWrap.append($dateInp).append($todayBtn);
             $dateInpWrap.append($dateInp).append($todayBtn);
             $dateBox.append($dateInpWrap);
             $dateBox.append($dateInpWrap);
Baris 736: Baris 672:
             $form.append($refArea);
             $form.append($refArea);


             // Edit Summary & Actions
             // TOMBOL AKSI FORM
            var $summaryBox = $('<div class="md-form-group" style="margin-top:10px;"><input type="text" id="md-edit-summary" class="md-input" placeholder="Ringkasan suntingan (opsional)..." style="font-size:0.8rem; background:var(--md-bg);"></div>');
            var $minorChk = $('<label style="font-size:0.75rem; margin-left:10px;"><input type="checkbox" id="md-edit-minor"> Suntingan Kecil</label>');
            $summaryBox.append($minorChk);
            $form.append($summaryBox);
 
             var $actions = $('<div class="md-form-actions"></div>');
             var $actions = $('<div class="md-form-actions"></div>');
             var $btnSave = $('<button class="md-btn md-btn-save">Simpan Perubahan</button>');
             var $btnSave = $('<button class="md-btn md-btn-save">Simpan & Terbitkan<span class="md-spinner"></span></button>');
             var $btnCancel = $('<button class="md-btn md-btn-cancel">Batal</button>');
             var $btnCancel = $('<button class="md-btn md-btn-cancel">Batal</button>');
           
             $actions.append($btnSave).append($btnCancel);
             $actions.append($btnSave).append($btnCancel);
              
              
             if (!isNew) {
             if (!isNew) {
                 var $btnDelete = $('<button class="md-btn md-btn-delete">Hapus Baris</button>');
                 var $btnDelete = $('<button class="md-btn md-btn-delete">Hapus Data<span class="md-spinner"></span></button>');
                 $btnDelete.on('click', function() {
                 $btnDelete.on('click', function() {
                     if(confirm('Yakin ingin membuang data ini ke tong sampah?')) {
                     if(confirm('Yakin ingin menghapus item data ini permanen?')) {
                         dataItems.splice(index, 1);
                         dataItems.splice(index, 1);
                         saveData('Menghapus data (' + currentData.prop + ')', $(this), rawContent, false);
                         saveData('Menghapus data terstruktur', $(this), rawContent);
                     }
                     }
                 });
                 });
Baris 761: Baris 693:
             $container.append($form);
             $container.append($form);


            // Interaksi Form
             $('#md-chk-person').on('change', function() {
             $('#md-chk-person').on('change', function() {
                 if($(this).is(':checked')) $('#md-social-box').slideDown(200).css('display', 'grid');
                 if($(this).is(':checked')) $('#md-social-box').slideDown(200).css('display', 'grid');
Baris 767: Baris 698:
             });
             });


            // Animasi Scroll
             $('html, body').animate({ scrollTop: $form.offset().top - 80 }, 300);
             $('html, body').animate({ scrollTop: $form.offset().top - 80 }, 300);
            $btnCancel.on('click', function() { $container.empty(); });
              
              
            // Hotkeys (Ctrl+S & Esc)
             $btnCancel.on('click', function() {  
             $form.on('keydown', function(e) {
                 localStorage.removeItem(draftKey);
                 if (e.ctrlKey && e.key === 's') { e.preventDefault(); $btnSave.click(); }
                 $container.empty();  
                 if (e.key === 'Escape') $btnCancel.click();
             });
             });
            $propInp.focus(); // Auto focus
            $btnSave.on('click', function() {
                // Validation
                $propInp.removeClass('error'); $valInp.removeClass('error');
                var newProp = $propInp.val().trim();
                var newVal = $valInp.val().trim();
               
                if (!newProp || !newVal) {
                    if(!newProp) $propInp.addClass('error');
                    if(!newVal) $valInp.addClass('error');
                    showToast("Label dan Nilai wajib diisi!", "error");
                    return;
                }


                var isPerson = $('#md-chk-person').is(':checked');
            // FITUR BARU: Auto-Save Draft
            function gatherFormData() {
                 var socObj = {};
                 var socObj = {};
                 if (isPerson) {
                 if ($('#md-chk-person').is(':checked')) {
                     Object.keys(SOCIAL_PLATFORMS).forEach(function(k) {
                     Object.keys(SOCIAL_PLATFORMS).forEach(function(k) {
                         var valU = $('#md-soc-' + k).val().trim();
                         var valU = $('#md-soc-' + k).val().trim();
Baris 798: Baris 715:
                     });
                     });
                 }
                 }
                 var refObj = {
                 var refObj = {
                     type: $typeSel.val(), subType: $subTypeSel.val(),
                     type: $('#md-ref-type').val(),
                     url: ensureHttps($urlInput.val()), title: $titleInp.val().trim(),
                    subType: $('#md-ref-subtype').val(),
                     site: $siteInp.val().trim(), author: $('#md-ref-author').val().trim(),
                     url: ensureHttps($('#md-ref-url').val()),
                     publisher: $('#md-ref-publisher').val().trim(), date: $dateInp.val()
                    title: $('#md-ref-title').val().trim(),
                     site: $('#md-ref-site').val().trim(),
                    author: $('#md-ref-author').val().trim(),
                     publisher: $('#md-ref-publisher').val().trim(),
                    date: $('#md-ref-date').val()
                 };
                 };
                // Clean empty refs
                 Object.keys(refObj).forEach(function(key) { if (!refObj[key]) delete refObj[key]; });
                 Object.keys(refObj).forEach(function(key) { if (!refObj[key]) delete refObj[key]; });
                 if (Object.keys(refObj).length === 0) refObj = null;
                 if (Object.keys(refObj).length === 0) refObj = null;


                 var newItem = {
                 return {
                     prop: newProp, val: newVal,
                     prop: $('#md-inp-prop').val().trim(),
                     link: $('#md-inp-link').is(':checked'), linkSplit: $('#md-inp-split').is(':checked'),
                    val: $('#md-inp-val').val().trim(),
                     link: $('#md-inp-link').is(':checked'),
                    linkSplit: $('#md-inp-split').is(':checked'),
                     linkTarget: $('#md-inp-target').val().trim(),
                     linkTarget: $('#md-inp-target').val().trim(),
                     isPersonOrg: isPerson, socials: socObj, ref: refObj
                     isPersonOrg: $('#md-chk-person').is(':checked'),
                    socials: socObj,
                    ref: refObj
                 };
                 };
            }
            if (isNew) {
                $('.md-track-draft').on('input change', function() {
                    localStorage.setItem(draftKey, JSON.stringify(gatherFormData()));
                });
            }
            $btnSave.on('click', function() {
                var newItem = gatherFormData();
                if (!newItem.prop || !newItem.val) {
                    showToast("Peringatan: Label Data dan Nilai wajib diisi!", 'warning');
                    $('#md-inp-prop').focus();
                    return;
                }


                 if (isNew) dataItems.push(newItem);  
                 if (isNew) dataItems.push(newItem);  
                 else dataItems[index] = newItem;  
                 else dataItems[index] = newItem;  


                 var cSum = $('#md-edit-summary').val().trim();
                 saveData(isNew ? 'Tambah data' : 'Edit data', $(this), rawContent);
                var sumMsg = cSum ? cSum : (isNew ? 'Tambah data ' + newProp : 'Edit data ' + newProp);
                var isMin = $('#md-edit-minor').is(':checked');
               
                saveData(sumMsg, $(this), rawContent, isMin);
             });
             });
         }
         }


         // 10. JSON EXPORT & IMPORT (MODAL V8)
         // 10. FITUR BARU: JSON EXPORT & IMPORT KE FILE
         function showJsonModal(rawContent) {
         function showJsonModal(rawContent) {
             var $container = $('#md-form-container');
             var $container = $('#md-form-container');
Baris 835: Baris 769:
             var jsonStr = JSON.stringify(dataItems, null, 2);
             var jsonStr = JSON.stringify(dataItems, null, 2);
             var $box = $('<div class="md-form-box"></div>');
             var $box = $('<div class="md-form-box"></div>');
             $box.append('<h4 class="md-form-title">Console Data (JSON)</h4>');
             $box.append('<h4 class="md-form-title">Ekspor / Impor File JSON</h4>');
             $box.append('<p style="font-size:0.8rem; color:var(--md-text-sub); margin-bottom:10px;">Gunakan ini untuk backup data atau migrasi cepat antar halaman.</p>');
             $box.append('<p style="font-size:0.85rem; color:#64748b; margin-bottom:12px;">Anda dapat mendownload struktur data ini sebagai file <b>.json</b> untuk cadangan, atau paste kode JSON untuk memulihkan.</p>');
              
              
             var $txt = $('<textarea class="md-textarea" rows="12" style="font-family:monospace; font-size:0.8rem; background:#1e1e1e; color:#d4d4d4;"></textarea>').val(jsonStr);
             var $txt = $('<textarea class="md-textarea" rows="12" style="font-family:monospace; font-size:0.8rem; background:#1e293b; color:#10b981; border:none;"></textarea>').val(jsonStr);
             $box.append($txt);
             $box.append($txt);


             var $actions = $('<div class="md-form-actions"></div>');
             var $actions = $('<div class="md-form-actions"></div>');
             var $btnImport = $('<button class="md-btn md-btn-save">Timpa Data dengan JSON di Atas</button>');
           
             var $btnCopy = $('<button class="md-btn" style="background:#10b981;">Salin Kode</button>');
             var $btnDownload = $('<button class="md-btn" style="background:#10b981;">Download File JSON</button>');
             var $btnImport = $('<button class="md-btn md-btn-save">Timpa & Impor Data <span class="md-spinner"></span></button>');
             var $btnCancel = $('<button class="md-btn md-btn-cancel">Tutup</button>');
             var $btnCancel = $('<button class="md-btn md-btn-cancel">Tutup</button>');


             $actions.append($btnImport).append($btnCopy).append($btnCancel);
            $btnDownload.on('click', function() {
                var blob = new Blob([$txt.val()], {type: "application/json;charset=utf-8"});
                var url = URL.createObjectURL(blob);
                var a = document.createElement('a');
                a.href = url;
                a.download = 'Mippedia_Data_' + pageName.replace(/ /g, '_') + '.json';
                a.click();
                URL.revokeObjectURL(url);
                showToast('File JSON berhasil didownload!', 'success');
            });
 
             $actions.append($btnDownload).append($btnImport).append($btnCancel);
             $box.append($actions);
             $box.append($actions);
             $container.append($box);
             $container.append($box);
            $('html, body').animate({ scrollTop: $box.offset().top - 80 }, 300);


             $btnCancel.on('click', function() { $container.empty(); });
             $btnCancel.on('click', function() { $container.empty(); });
            $btnCopy.on('click', function() { navigator.clipboard.writeText($txt.val()); showToast('JSON Disalin!', 'success'); });
           
             $btnImport.on('click', function() {
             $btnImport.on('click', function() {
                 try {
                 try {
                     var parsed = JSON.parse($txt.val());
                     var parsed = JSON.parse($txt.val());
                     if (Array.isArray(parsed)) {
                     if (Array.isArray(parsed)) {
                         dataItems = parsed;
                         if(confirm('PERHATIAN! Ini akan menimpa seluruh data yang ada. Lanjutkan?')) {
                        saveData('Impor massal dari JSON', $(this), rawContent, false);
                            dataItems = parsed;
                     } else showToast("Format JSON salah! Harus berawal [ dan berakhir ]", "error");
                            saveData('Impor massal dari JSON', $(this), rawContent);
                 } catch(e) { showToast("Error JSON: " + e.message, "error"); }
                        }
                     } else {
                        showToast("Format Error: JSON harus berupa Array (diawali dan diakhiri kurung siku).", 'error');
                    }
                 } catch(e) {
                    showToast("Format JSON tidak valid!", 'error');
                }
             });
             });
         }
         }


         // 11. EKSEKUSI UTAMA
         // 11. EKSEKUSI
         loadData().then(function(rawContent) { buildUI(rawContent); });
         loadData().then(function(rawContent) { buildUI(rawContent); });
     });
     });


})(jQuery, mediaWiki)
})(jQuery, mediaWiki);


/* ==========================================================
/* ==========================================================

Revisi per 18 Agustus 2026 00.38

/**
 * ====================================================================
 * MIPPEDIA DATA - ADVANCED STRUCTURED DATA SYSTEM (V8.0 ULTIMATE PRO)
 * Fitur Baru: Accordion References, Visit Site Button, Toast Notifs,
 * Auto-Save Drafts, Reorder Data (Up/Down), File Export/Import, 
 * 30+ Social Platforms, Glassmorphism UI, Mobile Perfect Animations.
 * ====================================================================
 */
(function($, mw) {
    'use strict';

    if (mw.config.get('wgNamespaceNumber') !== 0 || mw.config.get('wgIsMainPage')) return;
    if (mw.config.get('wgAction') !== 'view') return;

    mw.loader.using(['mediawiki.api', 'mediawiki.util']).then(function() {
        
        var pageName = mw.config.get('wgPageName');
        var isSysop = mw.config.get('wgUserGroups').indexOf('sysop') !== -1;
        var dataItems = [];
        var isLocked = false;
        var api = new mw.Api();

        // 1. DATA MASTER PLATFORM MEDIA SOSIAL & MUSIK (DITAMBAH BANYAK PLATFORM)
        var SOCIAL_PLATFORMS = {
            applemusic: { name: 'Apple Music', base: 'https://music.apple.com/artist/', color: '#fc3c44', icon: '<svg width="13" height="13" viewBox="0 0 24 24" fill="currentColor"><path d="M12 2C6.477 2 2 6.477 2 12s4.477 10 10 10 10-4.477 10-10S17.523 2 12 2zm3.32 12.383c-.328.232-.82.418-1.32.418-1.238 0-1.922-.828-1.922-2.191v-4.14l4.312-.868v1.398l-2.91.586v2.805c0 .734.336 1.148.977 1.148.336 0 .617-.094.863-.258v1.102z"/></svg>' },
            spotify: { name: 'Spotify', base: 'https://open.spotify.com/artist/', color: '#1db954', icon: '<svg width="13" height="13" viewBox="0 0 24 24" fill="currentColor"><path d="M12 2C6.477 2 2 6.477 2 12s4.477 10 10 10 10-4.477 10-10S17.523 2 12 2zm4.586 14.424c-.18.295-.563.387-.857.207-2.35-1.434-5.308-1.758-8.793-.963-.335.077-.67-.133-.746-.468-.077-.334.132-.67.467-.745 3.816-.87 7.092-.493 9.72 1.112.294.18.386.563.209.857zm1.213-2.71c-.226.368-.703.483-1.07.258-2.688-1.652-6.785-2.13-9.965-1.164-.413.125-.85-.108-.975-.522-.125-.413.108-.85.522-.975 3.633-1.102 8.157-.568 11.23 1.332.368.226.483.703.258 1.071zm.14-2.827c-3.225-1.915-8.54-2.092-11.614-1.16-.503.153-1.037-.133-1.19-.636-.152-.503.133-1.037.636-1.19 3.532-1.072 9.404-.865 13.115 1.338.45.267.598.85.33 1.3-.267.45-.85.598-1.3.33z"/></svg>' },
            soundcloud: { name: 'SoundCloud', base: 'https://soundcloud.com/', color: '#ff5500', icon: '<svg width="13" height="13" viewBox="0 0 24 24" fill="currentColor"><path d="M1.175 12.225c-.062 0-.115.053-.115.116v4.636c0 .062.053.115.115.115h.411c.063 0 .116-.053.116-.115v-4.636c0-.063-.053-.116-.116-.116h-.411zm1.312-1.28c-.062 0-.115.052-.115.115v6.52c0 .063.053.115.115.115h.43c.062 0 .115-.052.115-.115v-6.52c0-.063-.053-.115-.115-.115h-.43zm1.33-1.258c-.063 0-.115.052-.115.115v8.322c0 .063.052.115.115.115h.43c.063 0 .115-.052.115-.115V9.802c0-.063-.052-.115-.115-.115h-.43zm1.33-.86c-.063 0-.115.053-.115.116v9.542c0 .063.052.115.115.115h.43c.063 0 .115-.052.115-.115V8.942c0-.063-.052-.116-.115-.116h-.43zm21.43 3.652c-.413 0-.802.08-1.157.228-.312-2.73-2.613-4.858-5.422-4.858-1.08 0-2.083.315-2.928.858-.2-.702-.592-1.332-1.12-1.826-.78-.727-1.812-1.13-2.882-1.13-.815 0-1.6.236-2.272.684v10.822c0 .063.052.115.115.115h15.666c1.666 0 3.018-1.352 3.018-3.018 0-1.666-1.352-3.018-3.018-3.018z"/></svg>' },
            tidal: { name: 'Tidal', base: 'https://tidal.com/browse/artist/', color: '#000000', icon: '<svg width="13" height="13" viewBox="0 0 24 24" fill="currentColor"><path d="M12 4l4 4-4 4-4-4 4-4zm0 8l4 4-4 4-4-4 4-4zm8-8l4 4-4 4-4-4 4-4z"/></svg>' },
            youtube: { name: 'YouTube', base: 'https://youtube.com/@', color: '#ff0000', icon: '<svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M22.54 6.42a2.78 2.78 0 0 0-1.94-2C18.88 4 12 4 12 4s-6.88 0-8.6.46a2.78 2.78 0 0 0-1.94 2A29 29 0 0 0 1 11.75a29 29 0 0 0 .46 5.33A2.78 2.78 0 0 0 3.4 19c1.72.46 8.6.46 8.6.46s6.88 0 8.6-.46a2.78 2.78 0 0 0 1.94-2 29 29 0 0 0 .46-5.25 29 29 0 0 0-.46-5.33z"></path><polygon points="9.75 15.02 15.5 11.75 9.75 8.48 9.75 15.02"></polygon></svg>' },
            instagram: { name: 'Instagram', base: 'https://instagram.com/', color: '#e1306c', icon: '<svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><rect x="2" y="2" width="20" height="20" rx="5" ry="5"></rect><path d="M16 11.37A4 4 0 1 1 12.63 8 4 4 0 0 1 16 11.37z"></path><line x1="17.5" y1="6.5" x2="17.51" y2="6.5"></line></svg>' },
            tiktok: { name: 'TikTok', base: 'https://www.tiktok.com/@', color: '#000000', icon: '<svg width="13" height="13" viewBox="0 0 24 24" fill="currentColor"><path d="M19.59 6.69a4.83 4.83 0 0 1-3.77-4.25V2h-3.45v13.67a2.89 2.89 0 1 1-5.2-1.74 2.89 2.89 0 0 1 2.31-2.22V8.2a6.34 6.34 0 0 0-5 6.13 6.34 6.34 0 1 0 10.7-4.52A8.25 8.25 0 0 0 20 10.56V6.69z"/></svg>' },
            twitter: { name: 'X / Twitter', base: 'https://x.com/', color: '#0f1419', icon: '<svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M23 3a10.9 10.9 0 0 1-3.14 1.53 4.48 4.48 0 0 0-7.86 3v1A10.66 10.66 0 0 1 3 4s-4 9 5 13a11.64 11.64 0 0 1-7 2c9 5 20 0 20-11.5a4.5 4.5 0 0 0-.08-.83A7.72 7.72 0 0 0 23 3z"></path></svg>' },
            threads: { name: 'Threads', base: 'https://www.threads.net/@', color: '#000000', icon: '<svg width="13" height="13" viewBox="0 0 24 24" fill="currentColor"><path d="M12 2C6.477 2 2 6.477 2 12s4.477 10 10 10 10-4.477 10-10S17.523 2 12 2zm3.842 12.338c-.288 1.83-1.85 3.09-3.842 3.09-2.298 0-4.043-1.68-4.043-4.135 0-2.454 1.745-4.134 4.043-4.134 1.583 0 2.875.836 3.447 2.083l-1.28.625c-.39-.817-1.182-1.328-2.167-1.328-1.55 0-2.613 1.15-2.613 2.754 0 1.603 1.063 2.753 2.613 2.753 1.258 0 2.19-.77 2.37-1.808h-2.37v-1.38h3.842v1.48z"/></svg>' },
            facebook: { name: 'Facebook', base: 'https://facebook.com/', color: '#1877f2', icon: '<svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M18 2h-3a5 5 0 0 0-5 5v3H7v4h3v8h4v-8h3l1-4h-4V7a1 1 0 0 1 1-1h3z"></path></svg>' },
            linkedin: { name: 'LinkedIn', base: 'https://linkedin.com/in/', color: '#0a66c2', icon: '<svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M16 8a6 6 0 0 1 6 6v7h-4v-7a2 2 0 0 0-2-2 2 2 0 0 0-2 2v7h-4v-7a6 6 0 0 1 6-6z"></path><rect x="2" y="9" width="4" height="12"></rect><circle cx="4" cy="4" r="2"></circle></svg>' },
            twitch: { name: 'Twitch', base: 'https://twitch.tv/', color: '#9146FF', icon: '<svg width="13" height="13" viewBox="0 0 24 24" fill="currentColor"><path d="M11.571 4.714h1.715v5.143H11.57zm4.715 0H18v5.143h-1.714zM6 0L1.714 4.286v15.428h5.143V24l4.286-4.286h3.428L22.286 12V0zm14.571 11.143l-3.428 3.428h-3.429l-3 3v-3H6.857V1.714h13.714Z"/></svg>' },
            discord: { name: 'Discord', base: 'https://discord.gg/', color: '#5865F2', icon: '<svg width="13" height="13" viewBox="0 0 24 24" fill="currentColor"><path d="M20.317 4.37a19.791 19.791 0 0 0-4.885-1.515.074.074 0 0 0-.079.037c-.21.375-.444.864-.608 1.25a18.27 18.27 0 0 0-5.487 0 12.64 12.64 0 0 0-.617-1.25.077.077 0 0 0-.079-.037A19.736 19.736 0 0 0 3.677 4.37a.07.07 0 0 0-.032.027C.533 9.046-.32 13.58.099 18.057a.082.082 0 0 0 .031.057 19.9 19.9 0 0 0 5.993 3.03.078.078 0 0 0 .084-.028 14.09 14.09 0 0 0 1.226-1.994.076.076 0 0 0-.041-.106 13.107 13.107 0 0 1-1.872-.892.077.077 0 0 1-.008-.128 10.2 10.2 0 0 0 .372-.292.074.074 0 0 1 .077-.01c3.928 1.793 8.18 1.793 12.062 0a.074.074 0 0 1 .078.01c.12.098.246.198.373.292a.077.077 0 0 1-.006.127 12.299 12.299 0 0 1-1.873.892.077.077 0 0 0-.041.107c.36.698.772 1.362 1.225 1.993a.076.076 0 0 0 .084.028 19.839 19.839 0 0 0 6.002-3.03.077.077 0 0 0 .032-.054c.5-5.177-.838-9.674-3.549-13.66a.061.061 0 0 0-.031-.028zM8.02 15.33c-1.183 0-2.157-1.085-2.157-2.419 0-1.333.956-2.419 2.157-2.419 1.21 0 2.176 1.096 2.157 2.42 0 1.333-.956 2.418-2.157 2.418zm7.975 0c-1.183 0-2.157-1.085-2.157-2.419 0-1.333.955-2.419 2.157-2.419 1.21 0 2.176 1.096 2.157 2.42 0 1.333-.946 2.418-2.157 2.418z"/></svg>' },
            pinterest: { name: 'Pinterest', base: 'https://pinterest.com/', color: '#e60023', icon: '<svg width="13" height="13" viewBox="0 0 24 24" fill="currentColor"><path d="M12 0C5.373 0 0 5.372 0 12c0 5.084 3.163 9.426 7.627 11.174-.105-.949-.2-2.405.042-3.441.218-.937 1.407-5.965 1.407-5.965s-.359-.719-.359-1.782c0-1.668.967-2.914 2.171-2.914 1.023 0 1.518.769 1.518 1.69 0 1.029-.655 2.568-.994 3.995-.283 1.194.599 2.169 1.777 2.169 2.133 0 3.772-2.249 3.772-5.495 0-2.873-2.064-4.882-5.012-4.882-3.414 0-5.418 2.561-5.418 5.207 0 1.031.397 2.138.893 2.738.098.119.112.224.083.345l-.333 1.36c-.053.22-.174.267-.402.161-1.499-.698-2.436-2.889-2.436-4.649 0-3.785 2.75-7.262 7.929-7.262 4.163 0 7.398 2.967 7.398 6.931 0 4.136-2.607 7.464-6.227 7.464-1.216 0-2.359-.631-2.75-1.378l-.748 2.853c-.271 1.043-1.002 2.35-1.492 3.146C9.57 23.812 10.763 24 12 24c6.627 0 12-5.373 12-12 0-6.628-5.373-12-12-12z"/></svg>' }
        };

        // 2. PRESET TEMPLATES
        var PRESET_LABELS = [
            "Nama Lahir", "Tanggal Lahir", "Tempat Lahir", "Pekerjaan", "Gelar",
            "Kebangsaan", "Genre", "Instrumen", "Label Rekaman", "Zodiak",
            "Tahun Aktif", "Situs Web Resmi", "Pasangan", "Orang Tua", "Pendidikan"
        ];

        // 3. MASTER TIPE RUJUKAN
        var REF_TYPES = {
            "Berita": ["Berita Online", "Berita Cetak / Koran", "Wawancara Eksklusif", "Siaran Radio / TV"],
            "Website": ["Situs Resmi", "Portal Informasi", "Database Web", "Forum Diskusi"],
            "Buku": ["Buku Cetak", "E-Book", "Bab / Bagian Buku", "Biografi Cetak"],
            "Jurnal": ["Jurnal Ilmiah", "Paper Konferensi", "Artikel Review", "Tesis / Disertasi"],
            "Musik & Video": ["MusicBrainz", "Discogs", "Spotify", "YouTube", "Film Dokumenter"],
            "Lainnya": ["Siaran Pers", "Dokumen PDF", "Postingan Medsos", "Arsip Web"]
        };

        // 4. IKON SISTEM (SVG Ditingkatkan)
        var svgEdit = '<svg class="md-icon" width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M11 4H4a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-7"></path><path d="M18.5 2.5a2.121 2.121 0 0 1 3 3L12 15l-4 1 1-4 9.5-9.5z"></path></svg>';
        var svgLock = '<svg class="md-icon" width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><rect x="3" y="11" width="18" height="11" rx="2" ry="2"></rect><path d="M7 11V7a5 5 0 0 1 10 0v4"></path></svg>';
        var svgUnlock = '<svg class="md-icon" width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><rect x="3" y="11" width="18" height="11" rx="2" ry="2"></rect><path d="M7 11V7a5 5 0 0 1 9.9-1"></path></svg>';
        var svgRef = '<svg class="md-icon" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"></path><path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"></path></svg>';
        var svgCopy = '<svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><rect x="9" y="9" width="13" height="13" rx="2" ry="2"></rect><path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"></path></svg>';
        var svgSearch = '<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="11" cy="11" r="8"></circle><line x1="21" y1="21" x2="16.65" y2="16.65"></line></svg>';
        var svgCode = '<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><polyline points="16 18 22 12 16 6"></polyline><polyline points="8 6 2 12 8 18"></polyline></svg>';
        var svgChevronDown = '<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><polyline points="6 9 12 15 18 9"></polyline></svg>';
        var svgExternal = '<svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6"></path><polyline points="15 3 21 3 21 9"></polyline><line x1="10" y1="14" x2="21" y2="3"></line></svg>';
        var svgArrowUp = '<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><line x1="12" y1="19" x2="12" y2="5"></line><polyline points="5 12 12 5 19 12"></polyline></svg>';
        var svgArrowDown = '<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><line x1="12" y1="5" x2="12" y2="19"></line><polyline points="19 12 12 19 5 12"></polyline></svg>';
        var svgDownload = '<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"></path><polyline points="7 10 12 15 17 10"></polyline><line x1="12" y1="15" x2="12" y2="3"></line></svg>';

        // 5. HELPER UTILITY (Notifikasi Toast, Extract Domain, dll)
        function showToast(message, type) {
            var bg = type === 'error' ? '#dc2626' : (type === 'warning' ? '#d97706' : '#16a34a');
            var $toast = $('<div style="position:fixed; bottom:20px; right:20px; background:'+bg+'; color:#fff; padding:12px 20px; border-radius:8px; box-shadow:0 4px 12px rgba(0,0,0,0.15); z-index:9999; font-weight:600; font-size:0.9rem; opacity:0; transform:translateY(20px); transition:all 0.3s ease;">'+message+'</div>');
            $('body').append($toast);
            setTimeout(function() { $toast.css({opacity: 1, transform: 'translateY(0)'}); }, 10);
            setTimeout(function() {
                $toast.css({opacity: 0, transform: 'translateY(20px)'});
                setTimeout(function() { $toast.remove(); }, 300);
            }, 3000);
        }

        function formatIndonesianDate(dateStr) {
            if (!dateStr) return '';
            var parts = dateStr.split('-');
            if (parts.length !== 3) return dateStr;
            var months = ['Januari', 'Februari', 'Maret', 'April', 'Mei', 'Juni', 'Juli', 'Agustus', 'September', 'Oktober', 'November', 'Desember'];
            var day = parseInt(parts[2], 10);
            var monthIdx = parseInt(parts[1], 10) - 1;
            var year = parts[0];
            if (isNaN(day) || monthIdx < 0 || monthIdx > 11 || isNaN(year)) return dateStr;
            return day + ' ' + months[monthIdx] + ' ' + year;
        }

        function extractDomain(urlStr) {
            try {
                if (!urlStr.match(/^https?:\/\//i)) urlStr = 'https://' + urlStr;
                var parsed = new URL(urlStr);
                return parsed.hostname.replace(/^www\./, '');
            } catch(e) {
                return urlStr.replace(/^https?:\/\/(www\.)?/, '').split('/')[0];
            }
        }

        function ensureHttps(urlStr) {
            if (!urlStr) return '';
            urlStr = urlStr.trim();
            if (urlStr && !urlStr.match(/^https?:\/\//i)) {
                return 'https://' + urlStr;
            }
            return urlStr;
        }

        function getTodayString() {
            var now = new Date();
            var y = now.getFullYear();
            var m = String(now.getMonth() + 1).padStart(2, '0');
            var d = String(now.getDate()).padStart(2, '0');
            return y + '-' + m + '-' + d;
        }

        // 6. STYLESHEET MODERN V8.0 PRO
        var css = `
            #mippedia-data-app {
                background: #ffffff; border-radius: 16px; box-shadow: 0 8px 30px rgba(0,0,0,0.04);
                padding: 24px; margin: 24px 0; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
                border: 1px solid #f1f5f9; max-width: 100%; box-sizing: border-box; overflow: hidden;
            }
            
            .md-header {
                display: flex; flex-wrap: wrap; justify-content: space-between; align-items: center;
                gap: 12px; margin-bottom: 20px; padding-bottom: 16px; border-bottom: 2px solid #f8fafc;
            }
            .md-title-container { display: flex; align-items: center; gap: 10px; flex: 1 1 auto; min-width: 180px; }
            .md-title { font-size: 1.35rem; font-weight: 800; color: #0f172a; margin: 0; white-space: nowrap; letter-spacing: -0.5px; }
            .md-actions { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; }
            
            .md-btn-icon {
                background: #f8fafc; border: 1px solid #e2e8f0; cursor: pointer; color: #4f46e5;
                padding: 8px 14px; border-radius: 10px; transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);
                display: inline-flex; align-items: center; gap: 6px; font-size: 0.85rem; font-weight: 700; white-space: nowrap;
            }
            .md-btn-icon:hover:not(:disabled) { background: #e0e7ff; border-color: #c7d2fe; transform: translateY(-2px); box-shadow: 0 4px 12px rgba(79, 70, 229, 0.1); }
            .md-btn-icon:active:not(:disabled) { transform: translateY(0); }
            .md-btn-lock { color: #e11d48; background: #fff1f2; border-color: #fecdd3; }
            .md-btn-lock:hover:not(:disabled) { background: #ffe4e6; border-color: #fda4af; box-shadow: 0 4px 12px rgba(225, 29, 72, 0.1); }

            .md-search-box { position: relative; margin-bottom: 20px; width: 100%; box-sizing: border-box; }
            .md-search-input {
                width: 100%; padding: 12px 16px 12px 40px; border: 2px solid #f1f5f9; border-radius: 12px;
                font-size: 0.9rem; font-weight: 500; box-sizing: border-box; background: #f8fafc; transition: 0.3s;
            }
            .md-search-input:focus { background: #fff; border-color: #6366f1; outline: none; box-shadow: 0 0 0 4px rgba(99, 102, 241, 0.1); }
            .md-search-icon { position: absolute; left: 14px; top: 50%; transform: translateY(-50%); color: #94a3b8; }

            /* Row Display Fix */
            .md-row-display {
                display: flex; justify-content: space-between; align-items: flex-start;
                padding: 16px; border: 1px solid transparent; border-bottom: 1px solid #f1f5f9; transition: all 0.2s;
                border-radius: 12px; gap: 12px; margin-bottom: 8px; background: #fff; position: relative;
            }
            .md-row-display:hover { background: #fafafa; border-color: #f1f5f9; box-shadow: 0 4px 12px rgba(0,0,0,0.02); }
            
            .md-data-group { display: flex; flex-direction: column; gap: 8px; flex: 1; min-width: 0; }
            .md-data-label { font-size: 0.72rem; color: #64748b; font-weight: 800; text-transform: uppercase; letter-spacing: 0.8px; }
            .md-data-value-wrap { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
            .md-data-value { font-size: 1.1rem; color: #0f172a; line-height: 1.4; font-weight: 700; word-break: break-word; }
            
            .md-btn-copy {
                background: #f1f5f9; border: none; color: #64748b; cursor: pointer; padding: 4px 6px;
                border-radius: 6px; transition: 0.2s; display: inline-flex; align-items: center;
            }
            .md-btn-copy:hover { color: #4f46e5; background: #e0e7ff; transform: scale(1.05); }

            .md-row-actions { display: flex; flex-direction: column; gap: 6px; }

            /* Tampilan Referensi V8.0 (ACCORDION COLLAPSIBLE) */
            .md-ref-container { margin-top: 12px; width: 100%; max-width: 450px; box-sizing: border-box; }
            .md-ref-summary {
                background: #f8fafc; padding: 8px 12px; border-radius: 8px; border: 1px solid #e2e8f0;
                display: flex; justify-content: space-between; align-items: center; cursor: pointer;
                transition: all 0.2s; user-select: none;
            }
            .md-ref-summary:hover { background: #f1f5f9; border-color: #cbd5e1; }
            .md-ref-summary.open { border-bottom-left-radius: 0; border-bottom-right-radius: 0; border-bottom-color: transparent; background: #f1f5f9; }
            .md-ref-tag { font-size: 0.8rem; font-weight: 700; color: #4f46e5; display: flex; align-items: center; gap: 6px; }
            .md-ref-toggle { color: #94a3b8; transition: transform 0.3s; display: flex; align-items: center; }
            .md-ref-summary.open .md-ref-toggle { transform: rotate(180deg); color: #4f46e5; }
            
            .md-ref-body {
                background: #fff; padding: 12px; border: 1px solid #e2e8f0; border-top: none;
                border-bottom-left-radius: 8px; border-bottom-right-radius: 8px; font-size: 0.85rem;
                display: none; box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.05);
            }
            .md-ref-header { font-weight: 800; color: #0f172a; margin-bottom: 8px; display: block; word-break: break-word; line-height: 1.3; }
            .md-ref-details-grid { display: flex; flex-direction: column; gap: 4px; margin-bottom: 12px; }
            .md-ref-detail-row { display: flex; flex-wrap: wrap; gap: 4px; font-size: 0.82rem; }
            .md-ref-lbl { font-weight: 700; color: #64748b; }
            .md-ref-val { color: #334155; font-weight: 500; }
            
            .md-btn-visit {
                display: inline-flex; align-items: center; gap: 6px; background: #eff6ff; color: #2563eb;
                padding: 6px 12px; border-radius: 6px; font-weight: 700; font-size: 0.8rem; text-decoration: none;
                transition: 0.2s; border: 1px solid #bfdbfe; width: max-content;
            }
            .md-btn-visit:hover { background: #dbeafe; text-decoration: none; transform: translateY(-1px); }

            /* Media Sosial Badges V8 */
            .md-social-group { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 10px; }
            .md-social-badge {
                display: inline-flex; align-items: center; gap: 6px; padding: 6px 12px; border-radius: 20px;
                font-size: 0.8rem; font-weight: 700; color: white; text-decoration: none; transition: all 0.2s;
                box-shadow: 0 2px 4px rgba(0,0,0,0.1);
            }
            .md-social-badge:hover { transform: translateY(-2px) scale(1.02); opacity: 0.95; box-shadow: 0 4px 8px rgba(0,0,0,0.15); color: white; text-decoration: none; }

            /* Preset Pill Badges */
            .md-preset-wrapper { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 8px; }
            .md-preset-pill {
                background: #f8fafc; border: 1px solid #e2e8f0; padding: 4px 10px; border-radius: 12px;
                font-size: 0.75rem; font-weight: 700; color: #64748b; cursor: pointer; transition: 0.2s;
            }
            .md-preset-pill:hover { background: #4f46e5; color: #fff; border-color: #4f46e5; }

            /* Form Elements */
            .md-form-box { background: #ffffff; border-radius: 16px; padding: 24px; margin-top: 24px; border: 1px solid #e2e8f0; box-shadow: 0 10px 40px rgba(0,0,0,0.06); animation: slideDown 0.3s ease; }
            @keyframes slideDown { from { opacity: 0; transform: translateY(-10px); } to { opacity: 1; transform: translateY(0); } }
            
            .md-form-title { font-size: 1.15rem; font-weight: 800; color: #0f172a; margin: 0 0 20px 0; border-bottom: 2px solid #f1f5f9; padding-bottom: 12px; }
            .md-form-group { margin-bottom: 18px; }
            .md-form-group label { display: block; font-size: 0.85rem; font-weight: 700; margin-bottom: 8px; color: #334155; }
            .md-input, .md-select, .md-textarea {
                width: 100%; padding: 10px 14px; border: 2px solid #e2e8f0; border-radius: 10px;
                box-sizing: border-box; font-family: inherit; font-size: 0.95rem; transition: 0.2s; background: #fafafa;
            }
            .md-input:focus, .md-select:focus, .md-textarea:focus { border-color: #6366f1; background: #fff; outline: none; box-shadow: 0 0 0 4px rgba(99, 102, 241, 0.1); }
            
            .md-ref-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; background: #f8fafc; padding: 16px; border-radius: 12px; border: 1px dashed #cbd5e1; }
            .md-social-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; background: #f1f5f9; padding: 16px; border-radius: 12px; border: 1px solid #e2e8f0; max-height: 320px; overflow-y: auto; }
            .md-grid-full { grid-column: span 2; }
            
            .md-form-actions { display: flex; gap: 12px; align-items: center; margin-top: 24px; padding-top: 16px; border-top: 1px solid #e2e8f0; flex-wrap: wrap; }
            .md-btn {
                padding: 12px 20px; border: none; border-radius: 10px; font-weight: 800; cursor: pointer;
                color: white; font-size: 0.9rem; transition: 0.2s; display: inline-flex; align-items: center; gap: 8px; justify-content: center;
            }
            .md-btn:hover:not(:disabled) { transform: translateY(-2px); box-shadow: 0 4px 12px rgba(0,0,0,0.15); }
            .md-btn:active:not(:disabled) { transform: translateY(0); }
            .md-btn-save { background: linear-gradient(135deg, #4f46e5, #4338ca); flex: 1; min-width: 150px; }
            .md-btn-cancel { background: #64748b; }
            .md-btn-delete { background: #ef4444; margin-left: auto; }
            
            .md-spinner { display: none; width: 14px; height: 14px; border: 2px solid rgba(255,255,255,0.3); border-radius: 50%; border-top-color: #fff; animation: md-spin 0.8s linear infinite; }
            .is-loading .md-spinner { display: inline-block; }
            @keyframes md-spin { to { transform: rotate(360deg); } }

            @media (max-width: 600px) {
                #mippedia-data-app { padding: 16px; margin: 16px 0; border-radius: 14px; }
                .md-header { flex-direction: column; align-items: flex-start; gap: 12px; }
                .md-actions { width: 100%; justify-content: flex-start; overflow-x: auto; padding-bottom: 4px; }
                .md-btn-icon { padding: 8px 12px; font-size: 0.8rem; flex-shrink: 0; }
                .md-ref-grid, .md-social-grid { grid-template-columns: 1fr; }
                .md-grid-full { grid-column: span 1; }
                .md-form-actions { flex-direction: column; width: 100%; }
                .md-btn { width: 100%; margin: 0 !important; }
                .md-row-display { padding: 14px 10px; flex-direction: column; }
                .md-row-actions { flex-direction: row; width: 100%; justify-content: flex-end; margin-top: 10px; border-top: 1px dashed #e2e8f0; padding-top: 10px; }
            }
            .md-native-render { display: none; }
        `;
        $('<style>').text(css).appendTo('head');

        // 7. PARSER & PENYIMPANAN DATA
        function loadData() {
            return api.get({
                action: 'query', prop: 'revisions', titles: pageName, rvprop: 'content', rvslots: 'main', formatversion: 2
            }).then(function(data) {
                var content = data.query.pages[0].revisions[0].slots.main.content;
                var match = content.match(/<!-- MIPPEDIA_DATA_START \| (.*?) -->/);
                if (match) {
                    try {
                        var parsed = JSON.parse(match[1]);
                        dataItems = parsed.items || [];
                        isLocked = parsed.locked || false;
                    } catch(e) { console.error("JSON Error", e); showToast('Gagal memuat struktur JSON!', 'error'); }
                }
                return content; 
            });
        }

        function buildWikitextVal(item) {
            var val = item.val;
            if (item.linkTarget && item.linkTarget.trim() !== '') {
                return "[[" + item.linkTarget.trim() + "|" + val + "]]";
            }
            if (item.linkSplit) {
                return val.replace(/([a-zA-Z0-9_À-ÿ\- ]+)/g, function(match) {
                    var trimmed = match.trim();
                    if (trimmed.length > 2 && trimmed.toLowerCase() !== 'dan' && trimmed.toLowerCase() !== 'atau') {
                        return "[[" + trimmed + "]]";
                    }
                    return match;
                });
            }
            if (item.link) {
                return "[[" + val + "]]";
            }
            return val;
        }

        function buildWikitextRef(refObj) {
            if (!refObj) return "";
            var title = refObj.title || "Rujukan";
            var text = refObj.url ? "[" + ensureHttps(refObj.url) + " " + title + "]" : "'''" + title + "'''";
            var details = [];
            if (refObj.author) details.push("Penulis: " + refObj.author);
            if (refObj.site) details.push("Situs: " + refObj.site);
            if (refObj.publisher) details.push("Penerbit: " + refObj.publisher);
            if (refObj.date) details.push("Diakses: " + formatIndonesianDate(refObj.date));
            
            if (details.length > 0) text += " &mdash; <small>" + details.join(" &bull; ") + "</small>";
            return text;
        }

        function saveData(actionType, $btnEl, originalContent, callback) {
            if ($btnEl) $btnEl.addClass('is-loading').prop('disabled', true);
            
            var jsonStr = JSON.stringify({ locked: isLocked, items: dataItems });
            var wt = "<!-- MIPPEDIA_DATA_START | " + jsonStr + " -->\n";
            wt += "<div class=\"md-native-render\">\n{| class=\"wikitable\"\n! Data !! Nilai !! Referensi\n";
            
            dataItems.forEach(function(item) {
                var valTxt = buildWikitextVal(item);
                var refTxt = buildWikitextRef(item.ref);
                wt += "|-\n| " + item.prop + " || " + valTxt + " || " + refTxt + "\n";
            });
            wt += "|}\n</div>\n<!-- MIPPEDIA_DATA_END -->";

            var newContent;
            var regex = /<!-- MIPPEDIA_DATA_START \| .*? -->[\s\S]*?<!-- MIPPEDIA_DATA_END -->/;
            if (regex.test(originalContent)) {
                newContent = originalContent.replace(regex, wt);
            } else {
                newContent = originalContent.trim() + "\n\n" + wt;
            }

            api.postWithToken('csrf', {
                action: 'edit', title: pageName, text: newContent, summary: 'Mippedia Data V8: ' + actionType, minor: false
            }).done(function() {
                localStorage.removeItem('md_draft_' + pageName); // Hapus draft jika sukses
                if(callback) callback();
                else {
                    showToast('Berhasil disimpan! Memuat ulang...', 'success');
                    setTimeout(function() { window.location.href = location.pathname + "?refresh=" + new Date().getTime(); }, 1000);
                }
            }).fail(function(err) {
                if ($btnEl) $btnEl.removeClass('is-loading').prop('disabled', false);
                showToast("Gagal menyimpan: " + err, 'error');
            });
        }

        // 8. BUILDER UI UTAMA
        function buildUI(rawContent) {
            var $app = $('<div id="mippedia-data-app"></div>');
            
            // HEADER
            var $header = $('<div class="md-header"></div>');
            var $titleContainer = $('<div class="md-title-container"><h3 class="md-title">' + svgEdit + ' Data Terstruktur</h3></div>');
            var $actions = $('<div class="md-actions"></div>');
            
            // Tombol Ekspor/Impor JSON Baru
            var $jsonBtn = $('<button class="md-btn-icon" title="Ekspor/Impor File JSON">' + svgDownload + ' Data JSON</button>');
            $jsonBtn.on('click', function() { showJsonModal(rawContent); });
            $actions.append($jsonBtn);

            if (isSysop) {
                var $lockBtn = $('<button class="md-btn-icon ' + (isLocked ? 'md-btn-unlock' : 'md-btn-lock') + '">' + (isLocked ? svgUnlock + ' Buka Kunci' : svgLock + ' Kunci') + ' <span class="md-spinner"></span></button>');
                $lockBtn.on('click', function() {
                    isLocked = !isLocked;
                    saveData(isLocked ? 'Mengunci data' : 'Membuka kunci data', $(this), rawContent);
                });
                $actions.append($lockBtn);
            }

            if (!isLocked || isSysop) {
                var $addBtn = $('<button class="md-btn-icon" style="background:#4f46e5; color:white; border-color:#4338ca;">' + svgEdit + ' Tambah Baru</button>');
                $addBtn.on('click', function() { showForm(-1, rawContent); });
                $actions.append($addBtn);
            }

            $header.append($titleContainer).append($actions);
            $app.append($header);

            // SEARCH BAR
            if (dataItems.length > 2) {
                var $searchBox = $('<div class="md-search-box"><span class="md-search-icon">' + svgSearch + '</span><input type="text" class="md-search-input" placeholder="Cari data terstruktur (misal: Tanggal Lahir)..."></div>');
                $searchBox.find('input').on('keyup input', function() {
                    var q = $(this).val().toLowerCase();
                    $app.find('.md-row-display').each(function() {
                        var text = $(this).text().toLowerCase();
                        $(this).toggle(text.indexOf(q) !== -1);
                    });
                });
                $app.append($searchBox);
            }

            // DAFTAR BARIS DATA
            var $list = $('<div class="md-list"></div>');
            if (dataItems.length === 0) {
                $list.append('<div style="text-align:center; padding: 40px 20px; background:#f8fafc; border-radius:12px; border:2px dashed #cbd5e1; color:#64748b;"><h4>Belum ada data!</h4><p style="font-size:0.9rem; margin-top:8px;">Klik tombol <b>Tambah Baru</b> di atas untuk mulai membuat struktur.</p></div>');
            } else {
                dataItems.forEach(function(item, index) {
                    var $row = $('<div class="md-row-display"></div>');
                    var $info = $('<div class="md-data-group"></div>');
                    $info.append('<span class="md-data-label">' + item.prop + '</span>');
                    
                    // RENDER NILAI DATA
                    var displayValHtml = '';
                    var rawVal = item.val || '';

                    if (rawVal.match(/^https?:\/\//i)) {
                        var domain = extractDomain(rawVal);
                        displayValHtml = '<a href="' + rawVal + '" target="_blank" style="color:#2563eb; text-decoration:none;">' + domain + '</a>';
                    } else if (item.linkTarget && item.linkTarget.trim() !== '') {
                        displayValHtml = '<a href="' + mw.util.getUrl(item.linkTarget.trim()) + '" style="color:#2563eb; text-decoration:none;">' + rawVal + '</a>';
                    } else if (item.linkSplit) {
                        var parts = rawVal.split(/([,/\s]+dan\s+|[,/\s]+atau\s+|[,/]+)/gi);
                        displayValHtml = parts.map(function(p) {
                            var trimmed = p.trim();
                            if (trimmed && !p.match(/^[,/\s]+$/) && trimmed.toLowerCase() !== 'dan' && trimmed.toLowerCase() !== 'atau') {
                                return '<a href="' + mw.util.getUrl(trimmed) + '" style="color:#2563eb; text-decoration:none;">' + trimmed + '</a>';
                            }
                            return p;
                        }).join('');
                    } else if (item.link) {
                        displayValHtml = '<a href="' + mw.util.getUrl(rawVal) + '" style="color:#2563eb; text-decoration:none;">' + rawVal + '</a>';
                    } else {
                        displayValHtml = rawVal;
                    }

                    var $valWrap = $('<div class="md-data-value-wrap"></div>');
                    $valWrap.append('<span class="md-data-value">' + displayValHtml + '</span>');
                    
                    var $copyBtn = $('<button class="md-btn-copy" title="Salin nilai teks">' + svgCopy + '</button>');
                    $copyBtn.on('click', function() {
                        navigator.clipboard.writeText(rawVal);
                        showToast('Teks disalin!', 'success');
                    });
                    $valWrap.append($copyBtn);
                    $info.append($valWrap);

                    // RENDER MEDIA SOSIAL & MUSIK
                    if (item.isPersonOrg && item.socials) {
                        var $socialGroup = $('<div class="md-social-group"></div>');
                        var hasSocial = false;
                        Object.keys(SOCIAL_PLATFORMS).forEach(function(key) {
                            var uname = item.socials[key];
                            if (uname) {
                                hasSocial = true;
                                var platform = SOCIAL_PLATFORMS[key];
                                var fullUrl = platform.base + uname.replace(/^@/, '');
                                var $badge = $('<a class="md-social-badge" href="' + fullUrl + '" target="_blank" style="background:' + platform.color + ';">' + platform.icon + ' ' + platform.name + '</a>');
                                $socialGroup.append($badge);
                            }
                        });
                        if (hasSocial) $info.append($socialGroup);
                    }
                    
                    // RENDER REFERENSI EKSPLISIT (V8 ACCORDION)
                    if (item.ref && (item.ref.url || item.ref.title)) {
                        var ref = item.ref;
                        var $refContainer = $('<div class="md-ref-container"></div>');
                        
                        var siteNameLabel = ref.site || extractDomain(ref.url) || "Referensi";
                        var $refSummary = $('<div class="md-ref-summary" title="Klik untuk lihat detail referensi"><span class="md-ref-tag">' + svgRef + ' 1 Referensi (' + siteNameLabel + ')</span><span class="md-ref-toggle">' + svgChevronDown + '</span></div>');
                        var $refBody = $('<div class="md-ref-body"></div>');
                        
                        var refTitle = ref.title || "Sumber Rujukan";
                        $refBody.append('<span class="md-ref-header">' + refTitle + '</span>');

                        var $detailsGrid = $('<div class="md-ref-details-grid"></div>');
                        if (ref.author) $detailsGrid.append('<div class="md-ref-detail-row"><span class="md-ref-lbl">Penulis:</span><span class="md-ref-val">' + ref.author + '</span></div>');
                        if (ref.site) $detailsGrid.append('<div class="md-ref-detail-row"><span class="md-ref-lbl">Situs/Penerbit:</span><span class="md-ref-val">' + ref.site + (ref.publisher ? ' / ' + ref.publisher : '') + '</span></div>');
                        if (ref.date) $detailsGrid.append('<div class="md-ref-detail-row"><span class="md-ref-lbl">Diakses:</span><span class="md-ref-val">' + formatIndonesianDate(ref.date) + '</span></div>');
                        if (ref.type) $detailsGrid.append('<div class="md-ref-detail-row"><span class="md-ref-lbl">Tipe:</span><span class="md-ref-val">' + ref.type + (ref.subType ? ' - ' + ref.subType : '') + '</span></div>');
                        
                        $refBody.append($detailsGrid);

                        if (ref.url) {
                            var safeUrl = ensureHttps(ref.url);
                            $refBody.append('<a href="' + safeUrl + '" target="_blank" class="md-btn-visit">' + svgExternal + ' Kunjungi Situs</a>');
                        }

                        $refSummary.on('click', function() {
                            $refBody.slideToggle(200);
                            $(this).toggleClass('open');
                        });

                        $refContainer.append($refSummary).append($refBody);
                        $info.append($refContainer);
                    }
                    
                    $row.append($info);

                    if (!isLocked || isSysop) {
                        var $actionsGroup = $('<div class="md-row-actions"></div>');
                        
                        // Urutkan Atas/Bawah (Fitur Baru)
                        var $btnUp = $('<button class="md-btn-icon" style="padding:4px 6px;" title="Pindah ke Atas" ' + (index === 0 ? 'disabled style="opacity:0.3; cursor:not-allowed;"' : '') + '>' + svgArrowUp + '</button>');
                        var $btnDown = $('<button class="md-btn-icon" style="padding:4px 6px;" title="Pindah ke Bawah" ' + (index === dataItems.length-1 ? 'disabled style="opacity:0.3; cursor:not-allowed;"' : '') + '>' + svgArrowDown + '</button>');
                        
                        $btnUp.on('click', function() {
                            if(index > 0) {
                                var temp = dataItems[index-1];
                                dataItems[index-1] = dataItems[index];
                                dataItems[index] = temp;
                                saveData('Mengubah urutan', $(this), rawContent);
                            }
                        });
                        $btnDown.on('click', function() {
                            if(index < dataItems.length-1) {
                                var temp = dataItems[index+1];
                                dataItems[index+1] = dataItems[index];
                                dataItems[index] = temp;
                                saveData('Mengubah urutan', $(this), rawContent);
                            }
                        });

                        var $editIcon = $('<button class="md-btn-icon edit-btn" style="padding:6px 12px; margin-top:4px;">' + svgEdit + ' Edit</button>');
                        $editIcon.on('click', function() { showForm(index, rawContent); });

                        var $orderWrap = $('<div style="display:flex; gap:4px; justify-content:flex-end;"></div>').append($btnUp).append($btnDown);
                        $actionsGroup.append($orderWrap).append($editIcon);
                        $row.append($actionsGroup);
                    }
                    $list.append($row);
                });
            }
            $app.append($list);
            $app.append('<div id="md-form-container"></div>');

            var $infobox = $('.infobox').first();
            $('.md-native-render').hide(); 
            if ($infobox.length) $app.insertAfter($infobox);
            else $('#mw-content-text .mw-parser-output').append($app);
        }

        // 9. FORM EDIT DENGAN PRESET & PLATFORM LENGKAP
        function showForm(index, rawContent) {
            var $container = $('#md-form-container');
            $container.empty(); 

            var isNew = index === -1;
            var currentData = isNew ? { prop: '', val: '', link: false, linkTarget: '', linkSplit: false, ref: {}, isPersonOrg: false, socials: {} } : dataItems[index];
            
            // Cek Draft LocalStorage
            var draftKey = 'md_draft_' + pageName;
            var savedDraft = localStorage.getItem(draftKey);
            if (isNew && savedDraft) {
                try {
                    currentData = JSON.parse(savedDraft);
                    showToast('Memulihkan draft yang belum tersimpan...', 'warning');
                } catch(e) {}
            }

            var currentRef = currentData.ref || {};
            var currentSocials = currentData.socials || {};

            var $form = $('<div class="md-form-box"></div>');
            $form.append('<h4 class="md-form-title">' + (isNew ? 'Tambah Data Baru' : 'Edit Data Terstruktur') + '</h4>');
            
            // Label Data
            var $propGroup = $('<div class="md-form-group"><label>Label Data (Cth: Pekerjaan, Sutradara)</label><input type="text" id="md-inp-prop" class="md-input md-track-draft" value="' + (currentData.prop || '') + '"></div>');
            var $presetWrap = $('<div class="md-preset-wrapper"></div>');
            PRESET_LABELS.forEach(function(lbl) {
                var $pill = $('<span class="md-preset-pill">' + lbl + '</span>');
                $pill.on('click', function() { $('#md-inp-prop').val(lbl).trigger('input'); });
                $presetWrap.append($pill);
            });
            $propGroup.append($presetWrap);
            $form.append($propGroup);
            
            // Nilai Data
            var $valBox = $('<div class="md-form-group"></div>');
            $valBox.append('<label>Nilai / Konten Data</label><input type="text" id="md-inp-val" class="md-input md-track-draft" value="' + (currentData.val || '') + '">');
            
            var $wikilinkOpts = $('<div style="margin-top:10px; display:flex; flex-direction:column; gap:8px; background:#f8fafc; padding:12px; border-radius:10px; border:1px solid #e2e8f0;"></div>');
            var chkLink = currentData.link ? 'checked' : '';
            var chkSplit = currentData.linkSplit ? 'checked' : '';
            
            $wikilinkOpts.append('<label style="display:flex; align-items:center; gap:8px; font-size:0.85rem; font-weight:700; cursor:pointer;"><input type="checkbox" id="md-inp-link" class="md-track-draft" ' + chkLink + '> Jadikan Wikilink Standar</label>');
            $wikilinkOpts.append('<label style="display:flex; align-items:center; gap:8px; font-size:0.85rem; font-weight:700; cursor:pointer;"><input type="checkbox" id="md-inp-split" class="md-track-draft" ' + chkSplit + '> Smart Split Wikilink (Pecah koma/dan)</label>');
            
            var $pipedGroup = $('<div style="margin-top:6px;"><label style="font-size:0.8rem; color:#475569;">Target Halaman Piped (Opsional):</label><input type="text" id="md-inp-target" class="md-input md-track-draft" style="padding:8px 12px; font-size:0.85rem;" placeholder="Contoh: Diskografi Rumi Haitami" value="' + (currentData.linkTarget || '') + '"></div>');
            $wikilinkOpts.append($pipedGroup);
            
            $valBox.append($wikilinkOpts);
            $form.append($valBox);

            // MEDIA SOSIAL
            var $socialSec = $('<div class="md-form-group" style="margin-top:20px;"></div>');
            var chkPerson = currentData.isPersonOrg ? 'checked' : '';
            $socialSec.append('<label style="display:flex; align-items:center; gap:8px; cursor:pointer; background:#e0e7ff; padding:12px; border-radius:10px; font-weight:800; color:#3730a3;"><input type="checkbox" id="md-chk-person" class="md-track-draft" ' + chkPerson + '> Aktifkan Profil Sosmed & Musik</label>');
            
            var $socialGrid = $('<div class="md-social-grid" id="md-social-box" style="display:' + (currentData.isPersonOrg ? 'grid' : 'none') + '; margin-top:10px;"></div>');
            Object.keys(SOCIAL_PLATFORMS).forEach(function(key) {
                var p = SOCIAL_PLATFORMS[key];
                var valUname = currentSocials[key] || '';
                $socialGrid.append('<div><label style="font-size:0.8rem; color:#334155; font-weight:700;">' + p.name + '</label><input type="text" id="md-soc-' + key + '" class="md-input md-track-draft" placeholder="Username" value="' + valUname + '"></div>');
            });
            $socialSec.append($socialGrid);
            $form.append($socialSec);

            // RUJUKAN LENGKAP (Otomatis deteksi domain)
            var $refArea = $('<div class="md-form-group" style="margin-top:24px;"></div>');
            $refArea.append('<label style="font-size:1.05rem; font-weight:800; color:#0f172a; border-bottom:2px solid #e2e8f0; padding-bottom:8px;">Sumber Referensi</label>');
            
            var $refGrid = $('<div class="md-ref-grid" style="margin-top:12px;"></div>');
            
            var $typeSel = $('<select id="md-ref-type" class="md-select md-track-draft"><option value="">-- Pilih Kategori --</option></select>');
            Object.keys(REF_TYPES).forEach(function(t) {
                var sel = currentRef.type === t ? 'selected' : '';
                $typeSel.append('<option value="' + t + '" ' + sel + '>' + t + '</option>');
            });
            var $subTypeSel = $('<select id="md-ref-subtype" class="md-select md-track-draft"><option value="">-- Sub Kategori --</option></select>');
            
            function updateSubTypes(mainType, selectedSub) {
                $subTypeSel.empty().append('<option value="">-- Sub Kategori --</option>');
                if (mainType && REF_TYPES[mainType]) {
                    REF_TYPES[mainType].forEach(function(st) {
                        var sel = selectedSub === st ? 'selected' : '';
                        $subTypeSel.append('<option value="' + st + '" ' + sel + '>' + st + '</option>');
                    });
                }
            }
            $typeSel.on('change', function() { updateSubTypes($(this).val(), ''); });
            updateSubTypes(currentRef.type, currentRef.subType);

            $refGrid.append('<div><label style="font-size:0.8rem;">Kategori</label></div>').find('div').last().append($typeSel);
            $refGrid.append('<div><label style="font-size:0.8rem;">Sub Kategori</label></div>').find('div').last().append($subTypeSel);

            var $urlInput = $('<input type="url" id="md-ref-url" class="md-input md-track-draft" placeholder="https://..." value="' + (currentRef.url || '') + '">');
            $urlInput.on('blur', function() {
                var u = ensureHttps($(this).val());
                $(this).val(u);
                var $siteInp = $('#md-ref-site');
                // Fitur Baru: Otomatis isi nama situs dari URL
                if (u && !$siteInp.val().trim()) {
                    var domain = extractDomain(u);
                    $siteInp.val(domain.charAt(0).toUpperCase() + domain.slice(1));
                    $siteInp.trigger('input');
                }
            });

            $refGrid.append('<div class="md-grid-full"><label style="font-size:0.8rem;">URL Website (Link)</label></div>').find('div').last().append($urlInput);
            $refGrid.append('<div><label style="font-size:0.8rem;">Judul Halaman / Artikel</label><input type="text" id="md-ref-title" class="md-input md-track-draft" placeholder="Judul" value="' + (currentRef.title || '') + '"></div>');
            $refGrid.append('<div><label style="font-size:0.8rem;">Nama Situs / Portal</label><input type="text" id="md-ref-site" class="md-input md-track-draft" placeholder="Nama Situs" value="' + (currentRef.site || '') + '"></div>');
            $refGrid.append('<div><label style="font-size:0.8rem;">Penulis (Opsional)</label><input type="text" id="md-ref-author" class="md-input md-track-draft" placeholder="Nama Penulis" value="' + (currentRef.author || '') + '"></div>');
            $refGrid.append('<div><label style="font-size:0.8rem;">Penerbit (Opsional)</label><input type="text" id="md-ref-publisher" class="md-input md-track-draft" placeholder="Penerbit" value="' + (currentRef.publisher || '') + '"></div>');
            
            var $dateBox = $('<div><label style="font-size:0.8rem;">Tanggal Akses</label></div>');
            var $dateInpWrap = $('<div style="display:flex; gap:8px;"></div>');
            var $dateInp = $('<input type="date" id="md-ref-date" class="md-input md-track-draft" value="' + (currentRef.date || '') + '">');
            var $todayBtn = $('<button type="button" class="md-btn-icon" style="padding:6px 10px; font-size:0.8rem; border-color:#cbd5e1;" title="Set Hari Ini">Hari Ini</button>');
            $todayBtn.on('click', function() { $dateInp.val(getTodayString()).trigger('input'); });
            $dateInpWrap.append($dateInp).append($todayBtn);
            $dateBox.append($dateInpWrap);
            $refGrid.append($dateBox);

            $refArea.append($refGrid);
            $form.append($refArea);

            // TOMBOL AKSI FORM
            var $actions = $('<div class="md-form-actions"></div>');
            var $btnSave = $('<button class="md-btn md-btn-save">Simpan & Terbitkan<span class="md-spinner"></span></button>');
            var $btnCancel = $('<button class="md-btn md-btn-cancel">Batal</button>');
            
            $actions.append($btnSave).append($btnCancel);
            
            if (!isNew) {
                var $btnDelete = $('<button class="md-btn md-btn-delete">Hapus Data<span class="md-spinner"></span></button>');
                $btnDelete.on('click', function() {
                    if(confirm('Yakin ingin menghapus item data ini permanen?')) {
                        dataItems.splice(index, 1);
                        saveData('Menghapus data terstruktur', $(this), rawContent);
                    }
                });
                $actions.append($btnDelete);
            }

            $form.append($actions);
            $container.append($form);

            $('#md-chk-person').on('change', function() {
                if($(this).is(':checked')) $('#md-social-box').slideDown(200).css('display', 'grid');
                else $('#md-social-box').slideUp(200);
            });

            // Animasi Scroll
            $('html, body').animate({ scrollTop: $form.offset().top - 80 }, 300);
            
            $btnCancel.on('click', function() { 
                localStorage.removeItem(draftKey);
                $container.empty(); 
            });

            // FITUR BARU: Auto-Save Draft
            function gatherFormData() {
                var socObj = {};
                if ($('#md-chk-person').is(':checked')) {
                    Object.keys(SOCIAL_PLATFORMS).forEach(function(k) {
                        var valU = $('#md-soc-' + k).val().trim();
                        if (valU) socObj[k] = valU;
                    });
                }
                var refObj = {
                    type: $('#md-ref-type').val(),
                    subType: $('#md-ref-subtype').val(),
                    url: ensureHttps($('#md-ref-url').val()),
                    title: $('#md-ref-title').val().trim(),
                    site: $('#md-ref-site').val().trim(),
                    author: $('#md-ref-author').val().trim(),
                    publisher: $('#md-ref-publisher').val().trim(),
                    date: $('#md-ref-date').val()
                };
                Object.keys(refObj).forEach(function(key) { if (!refObj[key]) delete refObj[key]; });
                if (Object.keys(refObj).length === 0) refObj = null;

                return {
                    prop: $('#md-inp-prop').val().trim(),
                    val: $('#md-inp-val').val().trim(),
                    link: $('#md-inp-link').is(':checked'),
                    linkSplit: $('#md-inp-split').is(':checked'),
                    linkTarget: $('#md-inp-target').val().trim(),
                    isPersonOrg: $('#md-chk-person').is(':checked'),
                    socials: socObj,
                    ref: refObj
                };
            }

            if (isNew) {
                $('.md-track-draft').on('input change', function() {
                    localStorage.setItem(draftKey, JSON.stringify(gatherFormData()));
                });
            }

            $btnSave.on('click', function() {
                var newItem = gatherFormData();

                if (!newItem.prop || !newItem.val) {
                    showToast("Peringatan: Label Data dan Nilai wajib diisi!", 'warning'); 
                    $('#md-inp-prop').focus();
                    return;
                }

                if (isNew) dataItems.push(newItem); 
                else dataItems[index] = newItem; 

                saveData(isNew ? 'Tambah data' : 'Edit data', $(this), rawContent);
            });
        }

        // 10. FITUR BARU: JSON EXPORT & IMPORT KE FILE
        function showJsonModal(rawContent) {
            var $container = $('#md-form-container');
            $container.empty();

            var jsonStr = JSON.stringify(dataItems, null, 2);
            var $box = $('<div class="md-form-box"></div>');
            $box.append('<h4 class="md-form-title">Ekspor / Impor File JSON</h4>');
            $box.append('<p style="font-size:0.85rem; color:#64748b; margin-bottom:12px;">Anda dapat mendownload struktur data ini sebagai file <b>.json</b> untuk cadangan, atau paste kode JSON untuk memulihkan.</p>');
            
            var $txt = $('<textarea class="md-textarea" rows="12" style="font-family:monospace; font-size:0.8rem; background:#1e293b; color:#10b981; border:none;"></textarea>').val(jsonStr);
            $box.append($txt);

            var $actions = $('<div class="md-form-actions"></div>');
            
            var $btnDownload = $('<button class="md-btn" style="background:#10b981;">Download File JSON</button>');
            var $btnImport = $('<button class="md-btn md-btn-save">Timpa & Impor Data <span class="md-spinner"></span></button>');
            var $btnCancel = $('<button class="md-btn md-btn-cancel">Tutup</button>');

            $btnDownload.on('click', function() {
                var blob = new Blob([$txt.val()], {type: "application/json;charset=utf-8"});
                var url = URL.createObjectURL(blob);
                var a = document.createElement('a');
                a.href = url;
                a.download = 'Mippedia_Data_' + pageName.replace(/ /g, '_') + '.json';
                a.click();
                URL.revokeObjectURL(url);
                showToast('File JSON berhasil didownload!', 'success');
            });

            $actions.append($btnDownload).append($btnImport).append($btnCancel);
            $box.append($actions);
            $container.append($box);

            $('html, body').animate({ scrollTop: $box.offset().top - 80 }, 300);

            $btnCancel.on('click', function() { $container.empty(); });
            $btnImport.on('click', function() {
                try {
                    var parsed = JSON.parse($txt.val());
                    if (Array.isArray(parsed)) {
                        if(confirm('PERHATIAN! Ini akan menimpa seluruh data yang ada. Lanjutkan?')) {
                            dataItems = parsed;
                            saveData('Impor massal dari JSON', $(this), rawContent);
                        }
                    } else {
                        showToast("Format Error: JSON harus berupa Array (diawali dan diakhiri kurung siku).", 'error');
                    }
                } catch(e) {
                    showToast("Format JSON tidak valid!", 'error');
                }
            });
        }

        // 11. EKSEKUSI
        loadData().then(function(rawContent) { buildUI(rawContent); });
    });

})(jQuery, mediaWiki);

/* ==========================================================
   ⚡ MIPPEDIA SPEED OPTIMIZER - PURE SPEED & STABLE (V1.1)
   Features: Instant Link Pre-fetching Engine (No Animation/Pure Performance).
   Optimization: Zero-flicker, scoped lifecycle protection, advanced anti-cache clutter.
   Target: Built for maximum long-term stability and bulletproof caching.
   ========================================================= */

(function() {
    // Ambil nama host secara dinamis (contoh: data.mippedia.org)
    var currentHost = window.location.hostname;

    // --- 🗲 ENGINE PRE-FETCH CORES ---
    function injectPrefetchLink(url) {
        // Jaring Pengaman 1: Jangan injeksi jika link prefetch untuk URL ini sudah ada di head browser
        if (document.querySelector('link[href="' + url + '"]')) return;

        var prefetcher = document.createElement('link');
        prefetcher.rel = 'prefetch';
        prefetcher.href = url;
        
        // Jaring Pengaman 2: Failsafe anti-eror cache jika network mendadak sibuk
        prefetcher.onerror = function() { prefetcher.remove(); };
        
        document.head.appendChild(prefetcher);
    }

    function initPrefetchDispatch(href) {
        // Memanfaatkan requestIdleCallback agar proses prefetch hanya berjalan saat browser senggang 
        // sehingga tidak akan membuat scrolling halaman terasa berat/patah-patah
        if (window.requestIdleCallback) {
            window.requestIdleCallback(function() { injectPrefetchLink(href); });
        } else {
            setTimeout(function() { injectPrefetchLink(href); }, 20);
        }
    }

    // --- 🎮 COGNITIVE EVENT LISTENERS (UNIVERSAL HOVER & TOUCH) ---
    // Mendengarkan area konten utama MediaWiki (Desktop & Tampilan Mobile HP)
    $(document).on('mouseenter pointerdown', '#mw-content-text a, .mw-body-content a, #bodyContent a, .mw-parser-output a', function() {
        var $link = $(this);
        var href = $link.attr('href');

        // --- 🛡️ FILTER STRATA TINGGI: ABREVIASI LINK BERGUNA (ANTI CRASH CACHE) ---
        // 1. Abaikan link kosong, javascript void, atau buka tab baru (_blank)
        if (!href || href.startsWith('#') || href.startsWith('javascript:') || $link.attr('target') === '_blank') return;
        
        // 2. Abaikan link merah (artikel belum ada), link sunting teks, riwayat versi, dan aksi form MediaWiki
        if ($link.hasClass('new') || href.includes('action=') || href.includes('diff=') || href.includes('oldid=')) return;
        
        // 3. Abaikan link perkakas krusial pengurus / sistem otentikasi (hindari prefetch logout tidak sengaja)
        if (href.includes('Istimewa:') || href.includes('Special:') || href.includes('do=logout')) return;

        // Pastikan hanya mengeksekusi routing internal ekosistem Mippedia
        var isInternal = href.indexOf(currentHost) !== -1 || href.startsWith('/') || !href.includes('://');
        if (isInternal) {
            initPrefetchDispatch(href);
        }
    });
})();

/* ==========================================================
   🧠 MIPPEDIA DATA - SMART CONTEXT + AUTO THUMBNAIL (V10.1)
   Features: Priority Check (ID > EN > CONCISE), Auto-Age, 
             Auto-Bold, Smart Links, Dynamic Context,
             Targeted Isolation (Safe for Forms), Dynamic Noindex,
             Aesthetic Centered Empty State + 🚀 Instant Action Hub (3 Buttons)
   Fixes: Mobile View Visibility & Custom Short URL Route (No /w/)
   ========================================================= */
(function() {
    $(document).ready(function() {
        var $descSection = $('#mip-desc-section'), $descBox = $('#mip-auto-description'),
            $sourceInfo = $('#mip-source-info'), $portalLinks = $('#mip-portal-links'),
            $projectPortal = $('#mip-project-portal'), $mainContent = $('#mw-content-text');
        
        if (!$descBox.length) return;

        var pageTitle = mw.config.get('wgPageName').replace(/_/g, ' '),
            cacheKey = 'mip_smart_context_thumb_' + pageTitle, now = new Date().getTime(),
            currentYear = 2026;

        // --- KONFIGURASI PROYEK ---
        var projects = [
            { id: 'id', name: 'Mippedia bahasa Indonesia', url: 'https://id.mippedia.org/api.php', base: 'https://id.mippedia.org/wiki/', label: 'Mippedia Indonesia' },
            { id: 'en', name: 'Mippedia bahasa Inggris', url: 'https://en.mippedia.org/api.php', base: 'https://en.mippedia.org/wiki/', label: 'Mippedia Inggris' },
            { id: 'concise', name: 'Mippedia bahasa Indonesia ringkas', url: 'https://concise.mippedia.org/api.php', base: 'https://concise.mippedia.org/wiki/', label: 'Mippedia Ringkas' }
        ];

        // --- 🎨 ANIMASI, HOVER EFFECT & RESPONSIVE STYLE ---
        if (!$('#mip-clean-style').length) {
            $('head').append(
                '<style id="mip-clean-style">' +
                    '@keyframes mipFadeInUp {' +
                        'from { opacity: 0; transform: translateY(15px); }' +
                        'to { opacity: 1; transform: translateY(0); }' +
                    '}' +
                    '#mip-empty-state-notice {' +
                        'display: block !important;' + /* Memaksa tampil di seluler/mobile */
                        'animation: mipFadeInUp 0.6s cubic-bezier(0.16, 1, 0.3, 1) forwards;' +
                    '}' +
                    '.mip-btn-container {' +
                        'display: flex;' +
                        'flex-wrap: wrap;' + /* Supaya otomatis turun ke bawah kalau di HP */
                        'justify-content: center;' +
                        'margin-bottom: 30px;' +
                        'padding-top: 5px;' +
                    '}' +
                    '.mip-action-btn {' +
                        'display: inline-flex; align-items: center; justify-content: center;' +
                        'padding: 10px 18px; margin: 6px; font-size: 0.88em; font-weight: 600;' +
                        'color: #6a5acd !important; background: #ffffff; border: 1.5px solid #6a5acd;' +
                        'border-radius: 30px; text-decoration: none !important; cursor: pointer;' +
                        'transition: all 0.25s ease-in-out; box-shadow: 0 2px 5px rgba(106,92,205,0.08);' +
                        'flex-grow: 1; max-width: 220px; min-width: 150px;' + /* Penyesuaian porsi tombol di HP */
                    '}' +
                    '.mip-action-btn:hover {' +
                        'color: #ffffff !important; background: #6a5acd;' +
                        'transform: translateY(-2px); box-shadow: 0 4px 12px rgba(106,92,205,0.2);' +
                    '}' +
                    '.mip-action-btn:active {' +
                        'transform: translateY(0);' +
                    '}' +
                '</style>'
            );
        }

        // --- FUNGSI TOOLS ---
        function applyAutoBold(text) { return text.replace(new RegExp('(' + pageTitle + ')', 'gi'), '<strong>$1</strong>'); }
        function cleanExtract(text) { return text.replace(/\[\d+\]/g, '').replace(/\{\{[^}]+\}\}/g, '').replace(/\(\s*\)/g, '').replace(/\s\s+/g, ' ').trim(); }
        
        function applyDynamicContext(text) {
            var date = new Date();
            var hari = ["Minggu", "Senin", "Selasa", "Rabu", "Kamis", "Jumat", "Sabtu"];
            var bulan = ["Januari", "Februari", "Maret", "April", "Mei", "Juni", "Juli", "Agustus", "September", "Oktober", "November", "Desember"];
            var tglSkrg = hari[date.getDay()] + ", " + date.getDate() + " " + bulan[date.getMonth()] + " " + date.getFullYear();
            return text.replace(/(hari ini|saat ini|sekarang)/gi, '$1 (' + tglSkrg + ')')
                .replace(/(\d{1,2}\s(?:Januari|Februari|Maret|April|Mei|Juni|Juli|Agustus|September|Oktober|November|Desember)\s(\d{4}))/gi, function(m, f, y) { 
                    return f + " <span style='color: #444; font-weight: bold;'>– usia " + (currentYear - parseInt(y)) + " tahun</span>"; 
                })
                .replace(/(sejak|tahun)\s(\d{4})/gi, function(m, k, y) {
                    var gap = currentYear - parseInt(y);
                    if (gap > 0 && gap < 100) return k + " " + y + " <small style='color: #888;'>(" + gap + " thn lalu)</small>";
                    return m;
                });
        }

        function applySummary(text) {
            var limit = 250;
            if (text.length <= limit) return '<span>' + text + '</span>';
            return '<span>' + text.substring(0, limit) + '</span><span class="mip-dots">... </span><span class="mip-more" style="display:none;">' + text.substring(limit) + '</span><span class="mip-read-btn" style="color: #6a5acd; cursor: pointer; font-weight: bold; margin-left: 5px;">Baca selengkapnya</span>';
        }

        // --- SMART LINKS PORTAL ---
        function buildSmartLinks(currentId, validatedEnTitle) {
            $portalLinks.empty();
            var validLinks = [];
            
            var checkRequests = projects.filter(p => p.id !== currentId).map(function(p) {
                var targetTitle = (p.id === 'en' && validatedEnTitle) ? validatedEnTitle : pageTitle;
                if (p.id === 'en' && !validatedEnTitle) return $.Deferred().resolve();

                return $.ajax({ url: p.url, data: { action: 'query', titles: targetTitle, format: 'json', origin: '*' }, dataType: 'json' })
                    .then(function(data) { 
                        if (data.query.pages["-1"] === undefined) { 
                            validLinks.push('<a href="' + p.base + encodeURIComponent(targetTitle) + '" target="_blank" style="color: #6a5acd; text-decoration: underline; font-weight: bold;">' + p.label + '</a>'); 
                        } 
                    });
            });

            $.when.apply($, checkRequests).done(function() {
                if (validLinks.length > 0) { $portalLinks.html(validLinks.join(' <span style="color:#ccc; margin: 0 5px;">•</span> ')); $projectPortal.fadeIn(); }
            });
        }

        // --- 🧠 RENDER EMPTY STATE + INTERACTIVE HUB ---
        function toggleMippediaLayout(isEmpty) {
            var $existingNotice = $('#mip-empty-state-notice');
            var userGroups = mw.config.get('wgUserGroups') || [];
            var isSysop = userGroups.indexOf('sysop') !== -1;

            var $wikiDataElements = $mainContent.children().not('#mip-empty-state-notice, #mip-desc-section, script, style, .printfooter');
            var $editElements = $('#ca-edit, .mw-editsection, .wb-editsection, .mip-edit-trigger, [id*="edit"], [class*="edit-pencil"]');
            var $metaRobots = $('meta[name="robots"]');

            if (isEmpty) {
                if (!$existingNotice.length) {
                    // Perbaikan Jalur URL tanpa sub-folder /w/ langsung menembak Short URL root parameter
                    var createUrlID = 'https://id.mippedia.org/index.php?title=' + encodeURIComponent(pageTitle) + '&action=edit';
                    var createUrlEN = 'https://en.mippedia.org/index.php?title=' + encodeURIComponent(pageTitle) + '&action=edit';
                    var createUrlConcise = 'https://concise.mippedia.org/index.php?title=' + encodeURIComponent(pageTitle) + '&action=edit';

                    var noticeHtml = 
                        '<div id="mip-empty-state-notice" style="text-align: center; max-width: 600px; margin: 40px auto; padding: 10px; font-family: -apple-system, BlinkMacSystemFont, \'Segoe UI\', Roboto, sans-serif;">' +
                            '<!-- Ikon Warning Besar -->' +
                            '<div style="margin-bottom: 22px; display: inline-block;">' +
                                '<svg width="64" height="64" viewBox="0 0 24 24" fill="none" stroke="#d9534f" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round">' +
                                    '<path d="M10.29 3.86L1.82 18a2 2 0 0 0 1.71 3h16.94a2 2 0 0 0 1.71-3L13.71 3.86a2 2 0 0 0-3.42 0z"></path>' +
                                    '<line x1="12" y1="9" x2="12" y2="13"></line>' +
                                    '<line x1="12" y1="17" x2="12.01" y2="17"></line>' +
                                '</' + 'svg>' +
                            '</div>' +
                            '<!-- Judul Utama -->' +
                            '<h4 style="color: #2c3e50; margin: 0 0 12px 0; font-size: 1.35em; font-weight: 700; letter-spacing: -0.3px;">Item Data Struktur Tidak Memiliki Sumber Artikel</h4>' +
                            '<!-- Deskripsi Utama -->' +
                            '<p style="color: #555; margin: 0 0 25px 0; font-size: 0.98em; line-height: 1.6;">' +
                                'Item data ini saat ini <strong>tidak memiliki artikel rujukan satu pun</strong> di Mippedia Indonesia, Mippedia Inggris, maupun Mippedia Indonesia Ringkas.' +
                            '</p>' +
                            
                            '<!-- 🚀 INSTANT ACTION HUB (Flexbox-Responsive Mobile & URL No /w/) -->' +
                            '<div class="mip-btn-container">' +
                                '<a href="' + createUrlID + '" target="_blank" class="mip-action-btn">' +
                                    '<span style="margin-right: 6px;"></span>Buat Artikel ID' +
                                '</a>' +
                                '<a href="' + createUrlEN + '" target="_blank" class="mip-action-btn">' +
                                    '<span style="margin-right: 6px;"></span>Buat Artikel EN' +
                                '</a>' +
                                '<a href="' + createUrlConcise + '" target="_blank" class="mip-action-btn">' +
                                    '<span style="margin-right: 6px;"></span>Buat Artikel Ringkas' +
                                '</a>' +
                            '</div>' +

                            '<!-- Catatan Kaki Info Kecil -->' +
                            '<div style="font-size: 0.85em; color: #a0a0a0; line-height: 1.5; font-style: italic; border-top: 1px solid #f0f0f0; padding-top: 15px;">' +
                                'Informasi: Item data yang tidak terikat dengan artikel ensiklopedia apa pun dalam ekosistem Mippedia akan dihapus secara otomatis oleh pengurus dalam waktu dekat.' +
                            '</div>' +
                        '</div>';
                    $mainContent.prepend(noticeHtml);
                }

                $wikiDataElements.hide();
                $descSection.hide();

                if (!isSysop) {
                    $editElements.css({ 'pointer-events': 'none', 'opacity': '0.3', 'cursor': 'not-allowed' }).hide();
                    $(document).on('keydown.miplock', function(e) {
                        if (e.key.toLowerCase() === 'e' && !$(e.target).is('input, textarea')) {
                            e.preventDefault();
                            return false;
                        }
                    });
                }

                mw.config.set('wgRobotsPolicies', { 'index': 'noindex', 'follow': 'nofollow' });
                if ($metaRobots.length) {
                    $metaRobots.attr('content', 'noindex, nofollow');
                } else {
                    $('head').append('<meta name="robots" content="noindex, nofollow">');
                }

            } else {
                if ($existingNotice.length) $existingNotice.remove();
                
                $wikiDataElements.show();
                $descSection.show();

                if (!isSysop) {
                    $(document).off('keydown.miplock');
                }

                mw.config.set('wgRobotsPolicies', { 'index': 'index', 'follow': 'follow' });
                if ($metaRobots.length) {
                    $metaRobots.attr('content', 'index, follow');
                }
            }
        }

        // --- SISTEM PRIORITAS ---
        var cached = JSON.parse(localStorage.getItem(cacheKey) || "{}");
        var globalEnTitle = cached.enTitle || ""; 

        function init() {
            var pPrimary = projects[0]; 
            $.ajax({
                url: pPrimary.url,
                data: { action: 'query', prop: 'revisions|pageimages|langlinks', lllang: 'en', rvprop: 'timestamp', piprop: 'thumbnail', pithumbsize: 150, titles: pageTitle, format: 'json', origin: '*' },
                dataType: 'json',
                success: function(res) {
                    var pg = res.query.pages, id = Object.keys(pg)[0];
                    var latestTS = (id != "-1") ? pg[id].revisions[0].timestamp : "0";
                    var thumbUrl = (id != "-1" && pg[id].thumbnail) ? pg[id].thumbnail.source : "";
                    
                    if (id != "-1" && pg[id].langlinks && pg[id].langlinks[0]) {
                        globalEnTitle = pg[id].langlinks[0]['*'];
                    }

                    if (cached.content && cached.ts === latestTS && latestTS !== "0" && !cached.isEmpty) {
                        toggleMippediaLayout(false);
                        renderAll(cached.p, cached.content, cached.isTrans, cached.orig, cached.img, cached.customUrl, cached.enTitle);
                    } else { 
                        fetchPriorityData(0, latestTS, thumbUrl); 
                    }
                },
                error: function() { 
                    if (cached.content) {
                        toggleMippediaLayout(cached.isEmpty || false);
                        if (!cached.isEmpty) renderAll(cached.p, cached.content, cached.isTrans, cached.orig, cached.img, cached.customUrl, cached.enTitle);
                    } 
                }
            });
        }

        function fetchPriorityData(index, newTS, img) {
            if (index >= projects.length) {
                localStorage.setItem(cacheKey, JSON.stringify({isEmpty: true, ts: newTS, content: ""}));
                toggleMippediaLayout(true);
                return;
            }

            var p = projects[index];

            if (p.id === 'en') {
                if (!globalEnTitle) {
                    $.ajax({
                        url: 'https://concise.mippedia.org/api.php',
                        data: { action: 'query', prop: 'langlinks', lllang: 'en', titles: pageTitle, format: 'json', origin: '*' },
                        dataType: 'json',
                        async: false, 
                        success: function(cRes) {
                            var cPg = cRes.query.pages, cId = Object.keys(cPg)[0];
                            if (cId != "-1" && cPg[cId].langlinks && cPg[cId].langlinks[0]) {
                                globalEnTitle = cPg[cId].langlinks[0]['*'];
                            }
                        }
                    });
                }

                if (globalEnTitle) {
                    $.ajax({
                        url: p.url,
                        data: { action: 'query', prop: 'extracts', exintro: 1, explaintext: 1, titles: globalEnTitle, format: 'json', origin: '*' },
                        dataType: 'json',
                        success: function(data) {
                            var pages = data.query.pages, pageId = Object.keys(pages)[0];
                            if (pageId != "-1" && pages[pageId].extract) {
                                var extract = cleanExtract(pages[pageId].extract);
                                finalize(p, extract, false, "", newTS, img, p.base + encodeURIComponent(globalEnTitle), globalEnTitle);
                            } else {
                                fetchPriorityData(index + 1, newTS, img);
                            }
                        },
                        error: function() { fetchPriorityData(index + 1, newTS, img); }
                    });
                } else {
                    fetchPriorityData(index + 1, newTS, img);
                }
            } else {
                $.ajax({
                    url: p.url,
                    data: { action: 'query', prop: 'extracts', exintro: 1, explaintext: 1, titles: pageTitle, format: 'json', origin: '*' },
                    dataType: 'json',
                    success: function(data) {
                        var pages = data.query.pages, pageId = Object.keys(pages)[0];
                        if (pageId != "-1" && pages[pageId].extract) {
                            var extract = cleanExtract(pages[pageId].extract);
                            finalize(p, extract, false, "", newTS, img, p.base + encodeURIComponent(pageTitle), globalEnTitle); 
                        } else {
                            fetchPriorityData(index + 1, newTS, img);
                        }
                    },
                    error: function() { fetchPriorityData(index + 1, newTS, img); }
                });
            }
        }

        function finalize(p, c, t, o, ts, img, customUrl, enTitle) {
            localStorage.setItem(cacheKey, JSON.stringify({isEmpty: false, p:p, content:c, isTrans:t, orig:o, ts:ts, img:img, customUrl: customUrl, enTitle: enTitle}));
            toggleMippediaLayout(false); 
            renderAll(p, c, t, o, img, customUrl, enTitle);
        }

        function renderAll(p, currentText, isTranslated, originalText, img, customUrl, enTitle) {
            var processedText = applyAutoBold(applyDynamicContext(currentText));
            var thumbHtml = img ? '<div style="float: right; margin-left: 15px; margin-bottom: 10px; border: 1px solid #ddd; padding: 3px; background: #fff; border-radius: 4px; box-shadow: 0 2px 4px rgba(0,0,0,0.1);"><img src="'+img+'" style="max-width: 100px; display: block; height: auto;"></div>' : '';

            if (!$mainContent.find('#mip-desc-section').length) {
                $mainContent.prepend($descSection);
            }

            $descSection.show();
            $descBox.show().html(thumbHtml + applySummary(processedText) + '<div style="clear:both;"></div>');
            
            var targetLink = customUrl ? customUrl : p.base + encodeURIComponent(pageTitle);
            var footer = '<div style="font-size: 0.9em; color: #777;">Sumber : <a href="' + targetLink + '" target="_blank" style="color: #6a5acd; font-weight: bold; text-decoration: none;">' + p.name + '.</a>';
            if (isTranslated) { footer += '<br><span style="font-size: 0.85em; font-style: italic;">(Diterjemahkan secara otomatis)</span> <span id="mip-toggle-orig" style="color: #6a5acd; cursor: pointer; text-decoration: underline; margin-left: 5px;">Tampilkan versi asli</span>'; }
            $sourceInfo.show().html(footer);
            
            buildSmartLinks(p.id, enTitle);
            
            $(document).off('click', '.mip-read-btn').on('click', '.mip-read-btn', function() { $(this).hide(); $('.mip-dots').hide(); $('.mip-more').fadeIn(); });
            $(document).off('click', '#mip-toggle-orig').on('click', '#mip-toggle-orig', function() {
                var isOrig = ($(this).text() === 'Tampilkan versi asli');
                var textToDisplay = applyAutoBold(applyDynamicContext(isOrig ? originalText : currentText));
                $descBox.html(thumbHtml + applySummary(textToDisplay) + '<div style="clear:both;"></div>');
                $(this).text(isOrig ? 'Tampilkan terjemahan' : 'Tampilkan versi asli');
            });
        }

        init();
    });
})();

/* ==========================================================
   🚀 MIPPEDIA DATA - CORE SYSTEM (ULTIMATE BUNDLE)
   Status: FINAL & REVISED (Visual Fix + Permission Logic)
   Fix: Mobile Responsive Notification Position
   ========================================================== */

(function() {
    $(document).ready(function() {
        // --- 1. FILTER GLOBAL (Namespace 0 & Bukan Halaman Utama) ---
        if (mw.config.get('wgNamespaceNumber') !== 0 || 
            mw.config.get('wgIsMainPage') || 
            mw.config.get('wgAction') !== 'view') return;

        var pageTitle = mw.config.get('wgPageName');
        var dataPage = 'MediaWiki:Sitelinks-Data.json';
        var userGroups = mw.config.get('wgUserGroups');
        var isAdmin = userGroups.includes('sysop') || userGroups.includes('interface-admin');

        var projects = {
            'id': { name: 'ID', url: 'https://id.mippedia.org/api.php', base: 'https://id.mippedia.org/wiki/', color: '#6a5acd' },
            'en': { name: 'EN', url: 'https://en.mippedia.org/api.php', base: 'https://en.mippedia.org/wiki/', color: '#4169e1' },
            'concise': { name: 'Concise', url: 'https://concise.mippedia.org/api.php', base: 'https://concise.mippedia.org/wiki/', color: '#20b2aa' }
        };

        // --- 2. KOTAK NOTIFIKASI INFORMASI MODERN (FIXED MOBILE POSITION) ---
        function showBoxNotif(title, msg, type) {
            $('.mip-box-notif').remove();
            var theme = type === 'success' ? {bg:'#e6fffa', border:'#38b2ac', text:'#234e52', icon:''} : 
                        {bg:'#fff5f5', border:'#f56565', text:'#742a2a', icon:''};
            
            // Logika CSS Responsif untuk posisi
            var isMobile = window.innerWidth <= 768;
            var desktopStyle = "top:25px; right:25px; width:350px;";
            var mobileStyle = "top:15px; left:50%; transform:translateX(-50%); width:90%; max-width:400px;";
            var finalPos = isMobile ? mobileStyle : desktopStyle;

            var $notif = $('<div class="mip-box-notif" style="position:fixed; ' + finalPos + ' background:'+theme.bg+'; border-left:6px solid '+theme.border+'; padding:18px; z-index:10001; border-radius:12px; box-shadow:0 15px 35px rgba(0,0,0,0.2); font-family:sans-serif; animation:mipSlideIn 0.4s ease-out;">' +
                '<div style="display:flex; align-items:center; gap:12px; margin-bottom:8px;">' +
                    '<span style="font-size:20px;">'+theme.icon+'</span>' +
                    '<strong style="color:'+theme.text+'; font-size:15px; letter-spacing:-0.3px;">'+title+'</strong>' +
                '</div>' +
                '<p style="margin:0; font-size:13px; color:'+theme.text+'; line-height:1.6; opacity:0.9;">'+msg+'</p>' +
            '</div>').appendTo('body');

            setTimeout(function() { $notif.fadeOut(function(){ $(this).remove(); }); }, 5500);
        }

        // --- 3. UI GENERATOR (DIPERTEBAL) ---

      // A. Header Pro
        var headerHtml = '<div id="mip-header" style="background:#f8f9fa; border:1px solid #ddd; border-left:6px solid #6a5acd; padding:18px; margin-bottom:25px; border-radius:6px; box-shadow:inset 0 0 10px rgba(0,0,0,0.02);">' +
            '<div style="display:flex; align-items:center; gap:10px; margin-bottom:8px;">' +
            '<span style="background:#6a5acd; color:white; padding:3px 10px; border-radius:4px; font-size:11px; font-weight:bold; text-transform:uppercase; letter-spacing:0.5px;">Basis Data Terstruktur</span>' +
            '<strong style="color:#111; font-size:16px;"></strong></div>' +
            '<p style="margin:0; font-size:13px; color:#444; line-height:1.6;">' +
            'Halaman ini adalah metadata entitas repositori pusat yang disinkronisasi secara otomatis lintas ekosistem. ' +
            'Informasi di bawah ini bersifat teknis dan bebas digunakan sebagai referensi data terbuka bagi semua orang di seluruh dunia berdasarkan lisensi atribusi yang sesuai.' +
            '</p></div>';

        // B. Connector Box
        var editBtn = '<span id="mip-open-editor" style="cursor:pointer; font-size:20px; color:#6a5acd; opacity:0.8; transition:0.3s;" onmouseover="this.style.opacity=1" onmouseout="this.style.opacity=0.8">✎</span>';
        var connectorHtml = '<div id="mip-connector" style="background:#fff; border:1px solid #e2e8f0; border-radius:16px; padding:22px; margin-top:30px; box-shadow:0 10px 25px rgba(0,0,0,0.04);">' +
            '<div style="display:flex; justify-content:space-between; align-items:center; margin-bottom:20px;">' +
            '<strong style="font-size:15px; color:#1a202c; display:flex; align-items:center; gap:8px;">ID situs</strong>'+editBtn+'</div>' +
            '<div id="mip-display" style="display:flex; gap:12px; flex-wrap:wrap;"><small style="color:#a0aec0;">Mensinkronisasi basis data...</small></div>' +
            '<div id="mip-editor" style="display:none; margin-top:20px; border-top:2px solid #f7fafc; padding-top:20px;">' +
                Object.keys(projects).map(p => '<div style="margin-bottom:12px; display:flex; gap:10px;"><span style="width:75px; font-size:11px; font-weight:bold; background:#edf2f7; display:flex; align-items:center; justify-content:center; border-radius:8px; color:#4a5568;">'+projects[p].name+'</span><input type="text" id="in-'+p+'" placeholder="Judul artikel di '+projects[p].name+'..." style="flex:1; padding:10px; font-size:13px; border:1.5px solid #e2e8f0; border-radius:10px; outline:none; transition:0.2s;" onfocus="this.style.borderColor=\'#6a5acd\'"></div>').join('') +
                '<button id="mip-save" style="width:100%; padding:14px; background:#6a5acd; color:white; border:none; border-radius:12px; font-size:14px; font-weight:bold; cursor:pointer; box-shadow:0 4px 12px rgba(106,90,205,0.3); transition:0.3s;">Terbitkan</button>' +
            '</div></div>';

        // C. Footer Lisensi Lengkap
        var footerHtml = '<div id="mip-footer" style="background:#fafafa; border:1px solid #eee; border-radius:10px; padding:20px; margin-top:30px; text-align:center;">' +
            '<div style="font-size:11px; color:#718096; font-weight:800; text-transform:uppercase; letter-spacing:1px; margin-bottom:10px;">Lisensi, Atribusi & Penggunaan Data</div>' +
            '<p style="margin:0 0 10px; font-size:13px; color:#4a5568; line-height:1.6;">' +
            'Seluruh data terstruktur yang tersaji dalam repositori ini merupakan milik publik dan tersedia di bawah lisensi resmi ' +
            '<a href="https://creativecommons.org/licenses/by-sa/4.0/" target="_blank" style="color:#6a5acd; text-decoration:none; font-weight:700;">Creative Commons Attribution-ShareAlike 4.0 International</a>.' +
            '</p>' +
            '<p style="margin:0; font-size:12px; color:#a0aec0;">Akses API dan penggunaan data secara massal wajib mencantumkan atribusi kepada <strong>Mippedia Community</strong> selaku pengelola proyek.</p></div>';

        // Injeksi
        $('#mw-content-text').prepend(headerHtml);
        $('#mw-content-text').append(connectorHtml).append(footerHtml);

        // --- 4. LOGIC ENGINE ---
        function loadLinks() {
            new mw.Api().get({ action: 'query', prop: 'revisions', titles: dataPage, rvprop: 'content', formatversion: 2 }).done(function(d) {
                var json = d.query.pages[0].revisions ? JSON.parse(d.query.pages[0].revisions[0].content) : {};
                var data = json[pageTitle] || {};
                var $box = $('#mip-display').empty();
                var found = false;
                Object.keys(projects).forEach(p => {
                    if (data[p]) {
                        found = true;
                        $box.append('<a style="background:'+projects[p].color+'; color:white; padding:8px 16px; border-radius:10px; font-size:12px; font-weight:bold; text-decoration:none; border-bottom:3px solid rgba(0,0,0,0.15);" href="'+projects[p].base+encodeURIComponent(data[p])+'" target="_blank">Mippedia '+projects[p].name+': '+data[p]+'</a>');
                        $('#in-' + p).val(data[p]);
                    }
                });
                if (!found) $box.html('<em style="color:#cbd5e0; font-size:13px;">Entitas ini belum terhubung ke cabang Mippedia manapun.</em>');
            });
        }

        $(document).on('click', '#mip-save', function() {
            // CEK IZIN: Tolak user biasa
            if (!isAdmin) {
                showBoxNotif('Suntingan anda tidak di terbitkan', 'Halaman ini dilindungi. Hanya <b>Pengurus</b> yang memiliki otoritas untuk memodifikasi metadata ekosistem secara langsung.', 'error');
                return;
            }

            var $btn = $(this).text('Sedang Memvalidasi...').prop('disabled', true);
            var api = new mw.Api();
            var newData = {}, promises = [], invalid = [], isDel = true;

            Object.keys(projects).forEach(p => {
                var v = $('#in-' + p).val().trim();
                if (v) {
                    isDel = false;
                    promises.push($.ajax({ url: projects[p].url, data: { action: 'query', titles: v, format: 'json', origin: '*' }, dataType: 'json' }).done(function(res){
                        if (res.query.pages["-1"]) invalid.push(projects[p].name); else newData[p] = v;
                    }));
                }
            });

            $.when.apply($, promises).then(function() {
                if (invalid.length > 0) {
                    showBoxNotif('Suntingan anda tidak di terbitkan', 'Artikel dengan judul tersebut tidak ditemukan di basis data Mippedia cabang: ' + invalid.join(', ') + '. Periksa kembali ejaan dan kapitalisasi.', 'error');
                    $btn.text('Terbitkan').prop('disabled', false); return;
                }
                
                api.get({ action: 'query', prop: 'revisions', titles: dataPage, rvprop: 'content', formatversion: 2 }).done(function(r) {
                    var full = r.query.pages[0].revisions ? JSON.parse(r.query.pages[0].revisions[0].content) : {};
                    if (isDel) delete full[pageTitle]; else full[pageTitle] = newData;
                    
                    api.postWithEditToken({ action: 'edit', title: dataPage, text: JSON.stringify(full, null, 2), summary: 'Sync Metadata: ' + pageTitle })
                    .done(function() {
                        showBoxNotif('Suntingan anda berhasil di terbitkan!', 'Metadata entitas berhasil disinkronisasi ke seluruh jaringan ekosistem Mippedia.', 'success');
                        setTimeout(function(){ location.reload(); }, 1500);
                    }).fail(function(c) {
                        showBoxNotif('Gagal Menyimpan', 'Terjadi kesalahan pada token API atau koneksi server. Kode: ' + c, 'error');
                        $btn.text('Simpan & Sinkronkan Data').prop('disabled', false);
                    });
                });
            });
        });

        $(document).on('click', '#mip-open-editor', function() { $('#mip-editor').slideToggle(); });
        loadLinks();
    });
})();

(function() {
    // Fungsi utama suntik teks
    function forcePreload() {
        var ns = mw.config.get('wgNamespaceNumber');
        var pageExists = mw.config.get('wgArticleId') > 0;
        
        // Cek Namespace Utama & Halaman Baru
        if (ns === 0 && !pageExists) {
            // Cari textarea secara spesifik (Desktop & Mobile punya selector beda)
            var $textbox = $('#wpTextbox1, textarea.mw-ui-input, .editor-container textarea');
            
            if ($textbox.length && $textbox.val().trim() === "") {
                var pageName = mw.config.get('wgTitle');
                $textbox.val('{{Infobox umum\n|nama = ' + pageName + '\n}}');
                console.log("Mippedia: Infobox injected!");
            }
        }
    }

    // 1. Jalankan pas halaman beres load
    $(document).ready(forcePreload);

    // 2. Jalankan tiap ada klik (karena mobile buka editor pake klik tanpa refresh)
    $(document).on('click', function() {
        setTimeout(forcePreload, 800); // Kasih delay dikit nunggu overlay muncul
    });

    // 3. Pake MutationObserver buat mantau elemen yang baru muncul secara gaib
    var observer = new MutationObserver(function() {
        forcePreload();
    });
    observer.observe(document.body, { childList: true, subtree: true });
})();

/* ==========================================================
   🚀 MIPPEDIA DATA - CONTENT GUARD (MODIFIED FOR RELATED)
   ========================================================== */
(function() {
    function handleBlock(e) {
        var ns = mw.config.get('wgNamespaceNumber');
        if (ns !== 0 || mw.config.get('wgIsMainPage')) return;

        var $el = $(e.currentTarget);
        
        if ($el.closest('.mw-parser-output').length && $el.text().toLowerCase().includes('buat item')) {
            return; 
        }

        var $textbox = $('#wpTextbox1, .editor-container textarea, textarea.mw-ui-input');
        
        if ($textbox.length) {
            var content = $textbox.val() || "";
            
            // Pengecekan: Harus ada {{Infobox ATAU setidaknya ada kode #related
            var hasInfobox = content.includes('{{Infobox');
            var hasRelated = content.includes('#related:');

            if (!hasInfobox && !hasRelated) {
                e.preventDefault();
                e.stopPropagation();
                e.stopImmediatePropagation();

                window.alert("SUNTINGAN ANDA TIDAK BISA DI TERBITKAN!\n\nMippedia Data bukan tempat untuk menulis artikel ensiklopedia, Jika anda ingin membuat artikel ensiklopedia bukan di sini tempat nya.\n");
                return false;
            }
        }
    }

    $(document).on('click mousedown touchstart', 
        '#wpSave, .editor-save, .mw-ui-button.primary, button[type="submit"], .save-button, .header-action button', 
        function(e) {
            handleBlock(e);
        }
    );

    window.addEventListener('submit', function(e) {
        handleBlock(e);
    }, true);
})();

/* ==========================================================
   🛡️ MIPPEDIA CORE SYSTEM - NEURAL ENGINE V12
   Update: Brain Upgrade - Semantic Search & Anti-Duplicate
   Semua fitur asli (Patroli, Promo, Kategori) tetap UTUH.
   ========================================================== */
mw.hook('postEdit').add(function() {
    var rawUser = mw.config.get('wgUserName');
    var userName = rawUser ? rawUser.replace(/_/g, ' ') : 'Anonim';
    var isPatroli = (userName === 'Admin');
    
    if (mw.config.get('wgNamespaceNumber') !== 0) return;

    var api = new mw.Api();
    var pageTitle = mw.config.get('wgPageName').replace(/_/g, ' ');

    api.get({
        action: 'query',
        titles: pageTitle,
        prop: 'revisions|categories|links',
        rvprop: 'content',
        clshow: '!hidden',
        pllimit: 'max'
    }).done(function(resData) {
        var page = resData.query.pages[Object.keys(resData.query.pages)[0]];
        if (!page || !page.revisions) return;

        var rawContent = page.revisions[0]['*'];
        var content = rawContent;
        var summaryParts = [];

        // --- 2. SUPER INTELLIGENCE RELATED (UPGRADE OTAK V12) ---
        // Cek jumlah related saat ini
        var currentRelatedMatch = content.match(/\{\{#related:.*?\}\}/g) || [];
        
        // Jika kurang dari 3, kita jalankan otak pencarian canggih
        if (currentRelatedMatch.length < 3) {
            // Hapus yang lama dulu agar tidak ada duplikat atau "pake yang bekas"
            content = content.replace(/\n*\{\{#related:.*?\}\}/g, '');

            // Langkah A: Ambil kandidat dari Search Engine (Ranking Skor)
            api.get({
                action: 'query',
                list: 'search',
                srsearch: pageTitle, // Gunakan judul sebagai basis pencarian semantic
                srlimit: 15,
                srprop: ''
            }).done(function(searchRes) {
                var candidates = {};

                // Masukkan hasil pencarian ke pool skor
                if (searchRes.query && searchRes.query.search) {
                    searchRes.query.search.forEach(function(item, index) {
                        if (item.title === pageTitle) return;
                        candidates[item.title] = (15 - index); // Skor berdasarkan urutan relevansi
                    });
                }

                // Langkah B: Tambah skor jika artikel ada di daftar Link Internal
                if (page.links) {
                    page.links.forEach(function(link) {
                        if (link.title === pageTitle) return;
                        candidates[link.title] = (candidates[link.title] || 0) + 5; // Bonus skor link
                    });
                }

                // Langkah C: Urutkan berdasarkan skor tertinggi (yang paling nyambung)
                var sortedTitles = Object.keys(candidates).sort(function(a, b) {
                    return candidates[b] - candidates[a];
                });

                // Ambil TOP 3
                var finalRelated = sortedTitles.filter(t => t.indexOf(':') === -1).slice(0, 3);

                if (finalRelated.length > 0) {
                    var relatedTags = '\n\n' + finalRelated.map(t => '{{#related: ' + t + '}}').join('\n');
                    content += relatedTags;
                    summaryParts.push('NeuralRelated');
                }
                
                runPatroliAndSave();
            });
        } else {
            runPatroliAndSave();
        }

        function runPatroliAndSave() {
            // --- 3. PATROLI ENGINE (FITUR ASLI - TETAP BERFUNGSI) ---
            if (isPatroli) {
                var placeholders = [];
                // Lindungi Brankas: Template, Header, Kategori, Ref, dan Kalimat Pembuka
                content = content.replace(/(\{\{[\s\S]*?\}\}|==+.*?==+|\[\[Kategori:.*?\]\]|<ref[\s\S]*?<\/ref>|^.*?adalah)/gi, function(match) {
                    placeholders.push(match);
                    return '___MIP_SKIP_' + (placeholders.length - 1) + '___';
                });

                // Proses Auto-Link (Wajib ambil daftar AllPages dulu)
                api.get({ action: 'query', list: 'allpages', apnamespace: 0, aplimit: 'max' }).done(function(apData) {
                    var allTitles = apData.query.allpages.map(p => p.title);
                    var lowerTitles = allTitles.map(t => t.toLowerCase());

                    var tokens = content.split(/(\s+|\[\[|\]\])/);
                    var inLink = false;
                    for (var i = 0; i < tokens.length; i++) {
                        if (tokens[i] === '[[' ) { inLink = true; continue; }
                        if (tokens[i] === ']]' ) { inLink = false; continue; }
                        if (inLink || tokens[i].trim().length < 3 || tokens[i].includes('___MIP_SKIP_')) continue;

                        var wordsInToken = tokens[i].match(/\b\w+\b/g);
                        if (wordsInToken) {
                            wordsInToken.forEach(function(word) {
                                var idx = lowerTitles.indexOf(word.toLowerCase());
                                if (idx !== -1 && allTitles[idx] !== pageTitle) {
                                    tokens[i] = tokens[i].replace(new RegExp('\\b' + word + '\\b', 'g'), '[[' + allTitles[idx] + '|' + word + ']]');
                                }
                            });
                        }
                    }
                    content = tokens.join('');
                    
                    // Kembalikan dari Brankas
                    content = content.replace(/___MIP_SKIP_(\d+)___/g, function(match, id) { return placeholders[id]; });

                    // Bersihkan Link Merah
                    content = content.replace(/\[\[([^|\]:]+)\]\]/g, function(match, p1) {
                        return lowerTitles.includes(p1.toLowerCase()) ? match : p1;
                    });

                    saveAction();
                });
            } else {
                saveAction();
            }
        }

        function saveAction() {
            // --- 4. EKSEKUSI ---
            if (content.trim() !== rawContent.trim()) {
                api.postWithToken('edit', {
                    action: 'edit',
                    title: pageTitle,
                    text: content,
                    summary: 'Mippedia Neural Engine V12: ' + summaryParts.join(', '),
                    bot: true, markasbot: true
                }).done(function() { location.reload(); });
            }
        }
    });
});

/* ==========================================================
   🌐 MIPPEDIA SHORTDESC - DATA CENTER (PREMIUM UI)
   Status: INDEPENDENT & REFINED VISUAL
   Storage: MediaWiki:ShortDesc-Data.json
   ========================================================== */
(function($, mw) {
    "use strict";
    $(document).ready(function() {
        if (mw.config.get('wgNamespaceNumber') !== 0 || mw.config.get('wgIsMainPage')) return;

        var pageTitle = mw.config.get('wgPageName');
        var storagePage = 'MediaWiki:ShortDesc-Data.json';
        var isAdmin = mw.config.get('wgUserGroups').some(g => ['sysop', 'interface-admin'].includes(g));

        var langs = {
            id: { label: 'Mippedia bahasa Indonesia', short: 'ID', color: '#6366f1' },
            en: { label: 'Mippedia bahasa Inggris', short: 'EN', color: '#3b82f6' },
            concise: { label: 'Mippedia bahasa Indonesia ringkas', short: 'CON', color: '#14b8a6' }
        };

        // UI Box dengan Spasi dan Desain Baru
        var html = `
            <div id="desc-manager" style="background:#ffffff; border:1px solid #f1f5f9; border-left:4px solid #6366f1; border-radius:12px; padding:20px; margin: 20px 0 25px 0; box-shadow:0 4px 12px rgba(0,0,0,0.03); font-family: -apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,sans-serif;">
                <div style="display:flex; justify-content:space-between; align-items:center; margin-bottom:12px;">
                    <span style="font-size:13px; font-weight:700; color:#475569; text-transform:uppercase; letter-spacing:0.5px; display:flex; align-items:center; gap:6px;">
                        Label Deskripsi
                    </span>
                    <span id="desc-open-editor" style="cursor:pointer; padding:5px; transition:0.2s;" title="Edit Deskripsi">
                        <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="#94a3b8" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M11 4H4a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-7"></path><path d="M18.5 2.5a2.121 2.121 0 0 1 3 3L12 15l-4 1 1-4 9.5-9.5z"></path></svg>
                    </span>
                </div>
                
                <div id="desc-status-display" style="display:flex; flex-direction:column; gap:8px;">
                    <small style="color:#94a3b8; font-style:italic;">Sinkronisasi data...</small>
                </div>

                <div id="desc-editor" style="display:none; margin-top:18px; border-top:1px dashed #e2e8f0; padding-top:18px;">
                    ${Object.keys(langs).map(k => `
                        <div style="margin-bottom:12px;">
                            <label style="display:block; font-size:11px; font-weight:bold; color:#64748b; margin-bottom:4px;">${langs[k].label}</label>
                            <input type="text" id="desc-in-${k}" placeholder="Tulis deskripsi..." style="width:100%; padding:10px; font-size:13px; border:1px solid #e2e8f0; border-radius:8px; box-sizing:border-box; outline:none; focus:border-color:#6366f1;">
                        </div>
                    `).join('')}
                    <button id="desc-save" style="width:100%; padding:12px; background:#6366f1; color:white; border:none; border-radius:8px; font-size:13px; font-weight:600; cursor:pointer; margin-top:5px;">Terbitkan</button>
                </div>
            </div>`;

        $('.mw-parser-output').prepend(html);

        function loadDescStatus() {
            new mw.Api().get({ action: 'query', prop: 'revisions', titles: storagePage, rvprop: 'content', formatversion: 2 }).done(function(res) {
                var content = res.query.pages[0].revisions ? res.query.pages[0].revisions[0].content : "{}";
                var fullData = JSON.parse(content);
                var myData = fullData[pageTitle] || {};
                var $statusBox = $('#desc-status-display').empty();
                var foundAny = false;

                Object.keys(langs).forEach(k => {
                    var val = myData[k];
                    if (val && val.trim() !== "") {
                        foundAny = true;
                        $statusBox.append(`
                            <div style="display:flex; align-items:center; gap:10px;">
                                <span style="background:${langs[k].color}15; color:${langs[k].color}; padding:3px 10px; border-radius:20px; font-size:10px; font-weight:800; border:1px solid ${langs[k].color}30; min-width:35px; text-align:center;">${langs[k].short}</span>
                                <span style="font-size:13px; color:#334155; line-height:1.4;">${val}</span>
                            </div>
                        `);
                        $('#desc-in-' + k).val(val);
                    }
                });

                if (!foundAny) {
                    $statusBox.html('<div style="color:#cbd5e0; font-size:13px; background:#f8fafc; padding:10px; border-radius:8px; border:1px dashed #e2e8f0;">Belum ada metadata deskripsi yang dikaitkan dengan entitas ini.</div>');
                }
            });
        }

        $(document).on('click', '#desc-open-editor', function() { $('#desc-editor').slideToggle(); });

        $(document).on('click', '#desc-save', function() {
            if (!isAdmin) { alert('Akses ditolak. Anda memerlukan izin pengurus.'); return; }
            var $btn = $(this).text('Proses Sinkronisasi...').css('opacity','0.7');
            var api = new mw.Api();
            var newData = { id: $('#desc-in-id').val().trim(), en: $('#desc-in-en').val().trim(), concise: $('#desc-in-concise').val().trim() };

            api.get({ action: 'query', prop: 'revisions', titles: storagePage, rvprop: 'content', formatversion: 2 }).done(function(r) {
                var json = r.query.pages[0].revisions ? JSON.parse(r.query.pages[0].revisions[0].content) : {};
                if (!newData.id && !newData.en && !newData.concise) { delete json[pageTitle]; } else { json[pageTitle] = newData; }

                api.postWithEditToken({
                    action: 'edit',
                    title: storagePage,
                    text: JSON.stringify(json, null, 2),
                    summary: 'Update Entity Description: ' + pageTitle
                }).done(function() { location.reload(); });
            });
        });

        loadDescStatus();
    });
})(jQuery, mediaWiki);

/* ==========================================================
   📍 MIPPEDIA DATA - ULTIMATE TEXT-TO-MAP LOCATOR
   Fitur: Deteksi lokasi dari teks dengan database label lengkap
   ========================================================== */
(function() {
    $(document).ready(function() {
        var locationText = "";
        
        // --- DAFTAR LABEL SUPER LENGKAP & MASUK AKAL ---
        var locationLabels = [
            // Umum & Geografis
            'lokasi', 'tempat', 'wilayah', 'daerah', 'koordinat', 'alamat',
            // Orang (Biografi)
            'tempat lahir', 'asal', 'kediaman', 'domisili', 'negara asal',
            // Organisasi & Perusahaan
            'kantor pusat', 'markas', 'cabang utama', 'titik operasi',
            // Makanan & Budaya
            'asal wilayah', 'daerah asal', 'negara sumber', 'kawasan',
            // Sejarah & Bangunan
            'letak', 'posisi', 'titik temu', 'orbit'
        ];

        // Jalankan pencarian di tabel data (infobox atau wikitable)
        $('.wikitable tr, .infobox tr, .mip-data-table tr').each(function() {
            var label = $(this).find('th').text().toLowerCase().trim();
            // Hilangkan karakter spesial kayak titik dua biar matching-nya akurat
            label = label.replace(/[:]/g, '');

            var isMatch = locationLabels.some(function(target) {
                return label === target || label.includes(target);
            });

            if (isMatch) {
                var rawValue = $(this).find('td').text().trim();
                // Ambil bagian utama sebelum tanda koma, kurung, atau titik koma
                // Misal: "Bandung, Jawa Barat" -> ambil "Bandung"
                locationText = rawValue.split(/[,(\[;]/)[0].trim(); 
                
                if (locationText.length > 2) return false; // Stop jika sudah ketemu yang valid
            }
        });

        // Eksekusi Render Peta
        if (locationText && locationText.length > 2) {
            var $mapWrapper = $('<div>').css({
                'margin': '15px 0',
                'padding': '12px',
                'border': '1px solid #ddd',
                'background': '#ffffff',
                'border-radius': '10px',
                'box-shadow': '0 4px 12px rgba(0,0,0,0.08)'
            });

            $mapWrapper.append('<div style="font-weight:bold; font-size:0.9em; margin-bottom:10px; color:#444; display:flex; align-items:center;">' +
                               '<span style="margin-right:8px;">🗺️</span>Pratinjau Lokasi : ' + locationText + '</div>');

            // Embed URL dengan pencarian teks (Nominatim)
            var embedUrl = "https://www.openstreetmap.org/export/embed.html?layer=mapnik&q=" + encodeURIComponent(locationText);

            var $iframe = $('<iframe>').attr({
                'src': embedUrl,
                'width': '100%',
                'height': '280',
                'frameborder': '0',
                'style': 'border-radius: 8px; border: 1px solid #eee;'
            });

            $mapWrapper.append($iframe);
            
            // Link eksternal yang lebih rapi
            var gMapsUrl = "https://www.google.com/maps/search/" + encodeURIComponent(locationText);
            $mapWrapper.append('<div style="text-align:right; margin-top:8px;">' +
                               '<a href="' + gMapsUrl + '" target="_blank" style="font-size:0.75em; color:#6a5acd; font-weight:bold; text-decoration:none; text-transform:uppercase; letter-spacing:0.5px;">Buka di Google Maps →</a></div>');

            // Masukkan ke bawah section deskripsi otomatis
            if ($('#mip-desc-section').length) {
                $('#mip-desc-section').after($mapWrapper);
            }
        }
    });
})();