/** * TAROT ENGINE - 78 Card Deck * 22 Major Arcana + 56 Minor Arcana */ const MAJOR_ARCANA = [ { id: 0, nama: 'Si Bodoh', inggris: 'The Fool', arti: 'Awal baru, kepolosan, petualangan' }, { id: 1, nama: 'Si Penyihir', inggris: 'The Magician', arti: 'Kemampuan, kepercayaan diri, manifestasi' }, { id: 2, nama: 'Imam Besar', inggris: 'The High Priestess', arti: 'Intuisi, misteri, kebijaksanaan batin' }, { id: 3, nama: 'Permaisuri', inggris: 'The Empress', arti: 'Kesuburan, keibuan, kelimpahan' }, { id: 4, nama: 'Kaisar', inggris: 'The Emperor', arti: 'Otoritas, struktur, perlindungan' }, { id: 5, nama: 'Hierophant', inggris: 'The Hierophant', arti: 'Tradisi, spiritualitas, bimbingan' }, { id: 6, nama: 'Pecinta', inggris: 'The Lovers', arti: 'Cinta, pilihan, harmoni' }, { id: 7, nama: 'Kereta', inggris: 'The Chariot', arti: 'Kemenangan, kemauan keras, tekad' }, { id: 8, nama: 'Kekuatan', inggris: 'Strength', arti: 'Kekuatan batin, keberanian, kasih sayang' }, { id: 9, nama: 'Pertapa', inggris: 'The Hermit', arti: 'Kesendirian, introspeksi, pencarian' }, { id: 10, nama: 'Roda Keberuntungan', inggris: 'Wheel of Fortune', arti: 'Perubahan, siklus, takdir' }, { id: 11, nama: 'Keadilan', inggris: 'Justice', arti: 'Keadilan, keseimbangan, kebenaran' }, { id: 12, nama: 'Orang Tergantung', inggris: 'The Hanged Man', arti: 'Mengorbankan, perspektif baru, jeda' }, { id: 13, nama: 'Kematian', inggris: 'Death', arti: 'Transformasi, akhir, awal baru' }, { id: 14, nama: 'Kesederhanaan', inggris: 'Temperance', arti: 'Keseimbangan, moderasi, kesabaran' }, { id: 15, nama: 'Iblis', inggris: 'The Devil', arti: 'Keterikatan, materialisme, bayangan' }, { id: 16, nama: 'Menara', inggris: 'The Tower', arti: 'Kehancuran, perubahan mendadak, pencerahan' }, { id: 17, nama: 'Bintang', inggris: 'The Star', arti: 'Harapan, inspirasi, ketenangan' }, { id: 18, nama: 'Bulan', inggris: 'The Moon', arti: 'Ilusi, ketakutan, alam bawah sadar' }, { id: 19, nama: 'Matahari', inggris: 'The Sun', arti: 'Kebahagiaan, kesuksesan, vitalitas' }, { id: 20, nama: 'Penghakiman', inggris: 'Judgement', arti: 'Kebangkitan, introspeksi, panggilan' }, { id: 21, nama: 'Dunia', inggris: 'The World', arti: 'Penyelesaian, pencapaian, perjalanan' } ]; const SUITS = ['Wands', 'Cups', 'Swords', 'Pentacles']; const SUITS_ID = ['Tongkat', 'Cawan', 'Pedang', 'Koin']; const SUITS_ARTI = ['Karir & Kreativitas', 'Emosi & Cinta', 'Pikiran & Tantangan', 'Materi & Keuangan']; const MINOR_VALUES = ['Ace', '2', '3', '4', '5', '6', '7', '8', '9', '10', 'Page', 'Knight', 'Queen', 'King']; const MINOR_VALUES_ID = ['As', 'Dua', 'Tiga', 'Empat', 'Lima', 'Enam', 'Tujuh', 'Delapan', 'Sembilan', 'Sepuluh', 'Halaman', 'Ksatria', 'Ratu', 'Raja']; const MINOR_MEANINGS = { 'Wands': { 'Ace': 'Awal baru, inspirasi, ide kreatif', '2': 'Perencanaan, keputusan, langkah maju', '3': 'Ekspansi, pertumbuhan, persiapan', '4': 'Perayaan, pencapaian, pesta', '5': 'Kompetisi, konflik, persaingan', '6': 'Kemenangan, pengakuan, kesuksesan', '7': 'Tantangan, bertahan, keteguhan', '8': 'Kecepatan, perubahan, gerakan maju', '9': 'Ketahanan, kekuatan, pertahanan', '10': 'Beban, tekanan, tanggung jawab', 'Page': 'Antusiasme, pesan, ide baru', 'Knight': 'Petualangan, tindakan, gairah', 'Queen': 'Kreativitas, kehangatan, karisma', 'King': 'Kepemimpinan, visi, ambisi' }, 'Cups': { 'Ace': 'Cinta baru, emosi, intuisi', '2': 'Kemitraan, cinta, persatuan', '3': 'Perayaan, persahabatan, kegembiraan', '4': 'Kekecewaan, apati, introspeksi', '5': 'Kehilangan, kesedihan, penyesalan', '6': 'Kenangan, nostalgia, masa lalu', '7': 'Ilusi, pilihan, kebingungan', '8': 'Meninggalkan, mencari, perjalanan spiritual', '9': 'Kepuasan, kemewahan, kebahagiaan', '10': 'Kebahagiaan, harmoni, keluarga', 'Page': 'Pesan cinta, intuisi, pemimpi', 'Knight': 'Lamaran, undangan, romansa', 'Queen': 'Intuisi, kasih sayang, pengasuhan', 'King': 'Kedewasaan emosi, kebaikan hati' }, 'Swords': { 'Ace': 'Kemenangan, kejelasan, ide baru', '2': 'Kebuntuan, sulit memutuskan, keseimbangan', '3': 'Patah hati, kesedihan, pengkhianatan', '4': 'Istirahat, meditasi, pemulihan', '5': 'Konflik, kekalahan, permusuhan', '6': 'Transisi, perubahan, perjalanan', '7': 'Penipuan, strategi, kelicikan', '8': 'Terjebak, keterbatasan, ketakutan', '9': 'Kecemasan, mimpi buruk, kekhawatiran', '10': 'Akhir yang menyakitkan, kehancuran', 'Page': 'Ide baru, komunikasi, kewaspadaan', 'Knight': 'Tindakan cepat, ambisi, konfrontasi', 'Queen': 'Kebijaksanaan, logika, kejujuran', 'King': 'Otoritas, intelektual, kebenaran' }, 'Pentacles': { 'Ace': 'Kemakmuran, awal finansial, peluang', '2': 'Manajemen keuangan, multitasking, adaptasi', '3': 'Kerja tim, keterampilan, pembelajaran', '4': 'Tabungan, keamanan, kekikiran', '5': 'Kesulitan finansial, kekurangan, isolasi', '6': 'Kemurahan hati, berbagi, bantuan', '7': 'Kesabaran, investasi, pertumbuhan lambat', '8': 'Kerja keras, ketekunan, magang', '9': 'Kemewahan, kemandirian, kenyamanan', '10': 'Warisan, tradisi, kestabilan', 'Page': 'Pelajar, berita finansial, ketekunan', 'Knight': 'Tanggung jawab, kerja keras, dedikasi', 'Queen': 'Kelimpahan, keibuan, alam', 'King': 'Kekayaan, kepemimpinan bisnis, kemakmuran' } }; function shuffleArray(arr) { const a = [...arr]; for (let i = a.length - 1; i > 0; i--) { const j = Math.floor(Math.random() * (i + 1)); [a[i], a[j]] = [a[j], a[i]]; } return a; } function getTarotDeck() { const deck = []; // Major Arcana for (const card of MAJOR_ARCANA) { deck.push({ type: 'major', id: card.id, nama: card.nama, inggris: card.inggris, arti: card.arti, position: '' }); } // Minor Arcana for (let s = 0; s < SUITS.length; s++) { for (let v = 0; v < MINOR_VALUES.length; v++) { const key = MINOR_VALUES[v]; const meanings = MINOR_MEANINGS[SUITS[s]]; deck.push({ type: 'minor', suit: SUITS[s], suitId: SUITS_ID[s], suitArti: SUITS_ARTI[s], value: key, valueId: MINOR_VALUES_ID[v], nama: MINOR_VALUES_ID[v] + ' ' + SUITS_ID[s], inggris: key + ' of ' + SUITS[s], arti: meanings ? (meanings[key] || 'Arti umum') : 'Arti umum', position: '' }); } } return deck; } function drawTarot(count = 3) { const deck = getTarotDeck(); const shuffled = shuffleArray(deck).slice(0, count); const positions = [ 'Masa Lalu (Apa yang telah terjadi)', 'Masa Kini (Apa yang sedang terjadi)', 'Masa Depan (Apa yang akan terjadi)' ]; shuffled.forEach((card, i) => { card.position = positions[i] || 'Posisi ' + (i + 1); card.reversed = Math.random() < 0.3; // 30% chance reversed }); return shuffled; } function drawSingleCard() { return drawTarot(1)[0]; } function drawThreeCards() { return drawTarot(3); } function drawCelticCross() { const deck = getTarotDeck(); const shuffled = shuffleArray(deck); const positions = [ 'Situasi Saat Ini', 'Tantangan', 'Masa Lalu', 'Masa Depan', 'Puncak', 'Sikap Diri', 'Pengaruh Luar', 'Harapan & Ketakutan', 'Hasil Akhir' ]; return shuffled.slice(0, 9).map((card, i) => ({ ...card, position: positions[i] || 'Posisi ' + (i + 1), reversed: Math.random() < 0.3 })); }