import json
import os
from typing import Callable

import aiofiles
import aiohttp
import ffmpeg
import requests
import wget
from PIL import Image, ImageDraw, ImageFont
from pyrogram import Client, filters
from pyrogram.errors import UserAlreadyParticipant
from pyrogram.types import InlineKeyboardButton, InlineKeyboardMarkup, Message
from Python_ARQ import ARQ
from youtube_search import YoutubeSearch

from musikku.config import BOT_NAME as bn
from musikku.config import DURATION_LIMIT
from musikku.config import UPDATES_CHANNEL as updateschannel
from musikku.config import que
from musikku.function.admins import admins as a
from musikku.helpers.admins import get_administrators
from musikku.helpers.channelmusic import get_chat_id
from musikku.helpers.decorators import authorized_users_only
from musikku.helpers.filters import command, other_filters
from musikku.helpers.gets import get_file_name
from musikku.services.callsmusic import callsmusic, queues
from musikku.services.callsmusic.callsmusic import client as USER
from musikku.services.converter.converter import convert
from musikku.services.downloaders import youtube

chat_id = None

def cb_admin_check(func: Callable) -> Callable:
    async def decorator(client, cb):
        admemes = a.get(cb.message.chat.id)
        if cb.from_user.id in admemes:
            return await func(client, cb)
        else:
            await cb.answer("You ain't allowed!", show_alert=True)
            return

    return decorator

def transcode(filename):
    ffmpeg.input(filename).output(
        "input.raw", format="s16le", acodec="pcm_s16le", ac=2, ar="48k"
    ).overwrite_output().run()
    os.remove(filename)

# Convert seconds to mm:ss
def convert_seconds(seconds):
    seconds = seconds % (24 * 3600)
    seconds %= 3600
    minutes = seconds // 60
    seconds %= 60
    return "%02d:%02d" % (minutes, seconds)

# Convert hh:mm:ss to seconds
def time_to_seconds(time):
    stringt = str(time)
    return sum(int(x) * 60 ** i for i, x in enumerate(reversed(stringt.split(":"))))

# Change image size
def changeImageSize(maxWidth, maxHeight, image):
    widthRatio = maxWidth / image.size[0]
    heightRatio = maxHeight / image.size[1]
    newWidth = int(widthRatio * image.size[0])
    newHeight = int(heightRatio * image.size[1])
    newImage = image.resize((newWidth, newHeight))
    return newImage

async def generate_cover(requested_by, title, views, duration, thumbnail):
    async with aiohttp.ClientSession() as session:
        async with session.get(thumbnail) as resp:
            if resp.status == 200:
                f = await aiofiles.open("background.png", mode="wb")
                await f.write(await resp.read())
                await f.close()

    image1 = Image.open("./background.png")
    image2 = Image.open("./etc/foreground.png")
    image3 = changeImageSize(1280, 720, image1)
    image4 = changeImageSize(1280, 720, image2)
    image5 = image3.convert("RGBA")
    image6 = image4.convert("RGBA")
    Image.alpha_composite(image5, image6).save("temp.png")
    img = Image.open("temp.png")
    draw = ImageDraw.Draw(img)
    font = ImageFont.truetype("etc/font.otf", 32)
    draw.text((205, 550), f"Title: {title}", (51, 215, 255), font=font)
    draw.text((205, 590), f"Duration: {duration}", (255, 255, 255), font=font)
    draw.text((205, 630), f"Views: {views}", (255, 255, 255), font=font)
    draw.text(
        (205, 670),
        f"Added By: {requested_by}",
        (255, 255, 255),
        font=font,
    )
    img.save("final.png")
    os.remove("temp.png")
    os.remove("background.png")

@Client.on_message(filters.command("playlist") & filters.group & ~filters.edited)
async def playlist(client, message):
    global que
    queue = que.get(message.chat.id)
    if not queue:
        await message.reply_text("Pemain menganggur")
    temp = []
    for t in queue:
        temp.append(t)
    now_playing = temp[0][0]
    by = temp[0][1].mention(style="md")
    msg = "**Sedang dimainkan** in {}".format(message.chat.title)
    msg += "\n- " + now_playing
    msg += "\n- Req by " + by
    temp.pop(0)
    if temp:
        msg += "\n\n"
        msg += "**Antre**"
        for song in temp:
            name = song[0]
            usr = song[1].mention(style="md")
            msg += f"\n- {name}"
            msg += f"\n- Req by {usr}\n"
    await message.reply_text(msg)

# ============================= Settings =========================================

def updated_stats(chat, queue, vol=100):
    if chat.id in callsmusic.pytgcalls.active_calls:
        # if chat.id in active_chats:
        stats = "Pengaturan di **{}**".format(chat.title)
        if len(que) > 0:
            stats += "\n\n"
            stats += "Volume : {}%\n".format(vol)
            stats += "Lagu dalam antrian : `{}`\n".format(len(que))
            stats += "Sedang dimainkan : **{}**\n".format(queue[0][0])
            stats += "Permintaan dari : {}".format(queue[0][1].mention)
    else:
        stats = None
    return stats

def r_ply(type_):
    if type_ == "play":
        pass
    else:
        pass
    mar = InlineKeyboardMarkup(
        [
            [
                InlineKeyboardButton("⏹", "leave"),
                InlineKeyboardButton("⏸", "puse"),
                InlineKeyboardButton("▶", "resume"),
                InlineKeyboardButton("⏭", "skip"),
            ],
            [
                InlineKeyboardButton("Playlist 📖", "playlist"),
            ],
            [InlineKeyboardButton("❌ Close", "cls")],
        ]
    )
    return mar

@Client.on_message(filters.command("current") & filters.group & ~filters.edited)
async def ee(client, message):
    queue = que.get(message.chat.id)
    stats = updated_stats(message.chat, queue)
    if stats:
        await message.reply(stats)
    else:
        await message.reply("Tidak ada instans VC yang berjalan dalam obrolan ini")

@Client.on_message(filters.command("player") & filters.group & ~filters.edited)
@authorized_users_only
async def settings(client, message):
    playing = None
    chat_id = get_chat_id(message.chat)
    if chat_id in callsmusic.pytgcalls.active_calls:
        playing = True
    queue = que.get(chat_id)
    stats = updated_stats(message.chat, queue)
    if stats:
        if playing:
            await message.reply(stats, reply_markup=r_ply("pause"))

        else:
            await message.reply(stats, reply_markup=r_ply("play"))
    else:
        await message.reply("Tidak ada instans VC yang berjalan dalam obrolan ini")

@Client.on_callback_query(filters.regex(pattern=r"^(playlist)$"))
async def p_cb(b, cb):
    global que
    que.get(cb.message.chat.id)
    type_ = cb.matches[0].group(1)
    cb.message.chat.id
    cb.message.chat
    cb.message.reply_markup.inline_keyboard[1][0].callback_data
    if type_ == "playlist":
        queue = que.get(cb.message.chat.id)
        if not queue:
            await cb.message.edit("Pemain menganggur")
        temp = []
        for t in queue:
            temp.append(t)
        now_playing = temp[0][0]
        by = temp[0][1].mention(style="md")
        msg = "**Sedang dimainkan** in {}".format(cb.message.chat.title)
        msg += "\n- " + now_playing
        msg += "\n- Req by " + by
        temp.pop(0)
        if temp:
            msg += "\n\n"
            msg += "**Antre**"
            for song in temp:
                name = song[0]
                usr = song[1].mention(style="md")
                msg += f"\n- {name}"
                msg += f"\n- Req by {usr}\n"
        await cb.message.edit(msg)

@Client.on_callback_query(
    filters.regex(pattern=r"^(play|pause|skip|leave|puse|resume|menu|cls)$")
)
@cb_admin_check
async def m_cb(b, cb):
    global que
    if (
        cb.message.chat.title.startswith("Channel Music: ")
        and chat.title[14:].isnumeric()
    ):
        chet_id = int(chat.title[13:])
    else:
        chet_id = cb.message.chat.id
    qeue = que.get(chet_id)
    type_ = cb.matches[0].group(1)
    cb.message.chat.id
    m_chat = cb.message.chat

    the_data = cb.message.reply_markup.inline_keyboard[1][0].callback_data
    if type_ == "pause":
        if (chet_id not in callsmusic.pytgcalls.active_calls) or (
            callsmusic.pytgcalls.active_calls[chet_id] == "paused"
        ):
            await cb.answer("Obrolan tidak terhubung!", show_alert=True)
        else:
            callsmusic.pytgcalls.pause_stream(chet_id)

            await cb.answer("Music Paused!")
            await cb.message.edit(
                updated_stats(m_chat, qeue), reply_markup=r_ply("play")
            )

    elif type_ == "play":
        if (chet_id not in callsmusic.pytgcalls.active_calls) or (
            callsmusic.pytgcalls.active_calls[chet_id] == "playing"
        ):
            await cb.answer("Obrolan tidak terhubung!", show_alert=True)
        else:
            callsmusic.pytgcalls.resume_stream(chet_id)
            await cb.answer("Music Resumed!")
            await cb.message.edit(
                updated_stats(m_chat, qeue), reply_markup=r_ply("pause")
            )

    elif type_ == "playlist":
        queue = que.get(cb.message.chat.id)
        if not queue:
            await cb.message.edit("Pemain menganggur")
        temp = []
        for t in queue:
            temp.append(t)
        now_playing = temp[0][0]
        by = temp[0][1].mention(style="md")
        msg = "**Sedang dimainkan** in {}".format(cb.message.chat.title)
        msg += "\n- " + now_playing
        msg += "\n- Req by " + by
        temp.pop(0)
        if temp:
            msg += "\n\n"
            msg += "**Antre**"
            for song in temp:
                name = song[0]
                usr = song[1].mention(style="md")
                msg += f"\n- {name}"
                msg += f"\n- Req by {usr}\n"
        await cb.message.edit(msg)

    elif type_ == "resume":
        if (chet_id not in callsmusic.pytgcalls.active_calls) or (
            callsmusic.pytgcalls.active_calls[chet_id] == "playing"
        ):
            await cb.answer("Obrolan tidak terhubung or already playng", show_alert=True)
        else:
            callsmusic.pytgcalls.resume_stream(chet_id)
            await cb.answer("Music Resumed!")
    elif type_ == "puse":
        if (chet_id not in callsmusic.pytgcalls.active_calls) or (
            callsmusic.pytgcalls.active_calls[chet_id] == "paused"
        ):
            await cb.answer("Obrolan tidak terhubung atau sudah dijeda", show_alert=True)
        else:
            callsmusic.pytgcalls.pause_stream(chet_id)

            await cb.answer("Music Paused!")
    elif type_ == "cls":
        await cb.answer("Closed menu")
        await cb.message.delete()

    elif type_ == "menu":
        stats = updated_stats(cb.message.chat, qeue)
        await cb.answer("Menu opened")
        marr = InlineKeyboardMarkup(
            [
                [
                    InlineKeyboardButton("⏹", "leave"),
                    InlineKeyboardButton("⏸", "puse"),
                    InlineKeyboardButton("▶", "resume"),
                    InlineKeyboardButton("⏭", "skip"),
                ],
                [
                    InlineKeyboardButton("Playlist 📖", "playlist"),
                ],
                [InlineKeyboardButton("❌ Close", "cls")],
            ]
        )
        await cb.message.edit(stats, reply_markup=marr)
    elif type_ == "skip":
        if qeue:
            qeue.pop(0)
        if chet_id not in callsmusic.pytgcalls.active_calls:
            await cb.answer("Obrolan tidak terhubung!", show_alert=True)
        else:
            callsmusic.queues.task_done(chet_id)

            if callsmusic.queues.is_empty(chet_id):
                callsmusic.pytgcalls.leave_group_call(chet_id)

                await cb.message.edit("- Tidak Ada Lagi Daftar Putar..\n- Keluar dari VC!")
            else:
                callsmusic.pytgcalls.change_stream(
                    chet_id, callsmusic.queues.get(chet_id)["file"]
                )
                await cb.answer("Skipped")
                await cb.message.edit((m_chat, qeue), reply_markup=r_ply(the_data))
                await cb.message.reply_text(
                    f"- Skipped track\n- Sedang dimainkan **{qeue[0][0]}**"
                )

    else:
        if chet_id in callsmusic.pytgcalls.active_calls:
            try:
                callsmusic.queues.clear(chet_id)
            except QueueEmpty:
                pass

            callsmusic.pytgcalls.leave_group_call(chet_id)
            await cb.message.edit("Berhasil Meninggalkan Obrolan!")
        else:
            await cb.answer("Obrolan tidak terhubung!", show_alert=True)

@Client.on_message(command("play") & other_filters)
async def play(_, message: Message):
    global que
    lel = await message.reply("🔄 **Sabar aja cuk**")
    administrators = await get_administrators(message.chat)
    chid = message.chat.id

    try:
        user = await USER.get_me()
    except:
        user.first_name = "helper"
    usar = user
    wew = usar.id
    try:
        # chatdetails = await USER.get_chat(chid)
        await _.get_chat_member(chid, wew)
    except:
        for administrator in administrators:
            if administrator == message.from_user.id:
                if message.chat.title.startswith("Channel Music: "):
                    await lel.edit(
                        "Ingatlah untuk menambahkan pembantu ke saluran Anda",
                    )
                    pass
                try:
                    invitelink = await _.export_chat_invite_link(chid)
                except:
                    await lel.edit(
                        "Tambahkan saya sebagai admin grup Anda terlebih dahulu",
                    )
                    return

                try:
                    await USER.join_chat(invitelink)
                    await USER.send_message(
                        message.chat.id, "Saya bergabung dengan grup ini untuk memutar musik di VC"
                    )
                    await lel.edit(
                        "helper userbot joined your chat",
                    )

                except UserAlreadyParticipant:
                    pass
                except Exception:
                    # print(e)
                    await lel.edit(
                        f"🔴 Kesalahan permintaan banjir 🔴 \nUser {user.first_name} tidak dapat bergabung dengan grup Anda karena banyak permintaan untuk userbot! Pastikan pengguna tidak diblokir di grup."
                        "\n\nAtau tambahkan asisten ke Grup Anda secara manual dan coba lagi",
                    )
    try:
        await USER.get_chat(chid)
        # lmoa = await client.get_chat_member(chid,wew)
    except:
        await lel.edit(
            f" {user.first_name} Userbot tidak ada dalam obrolan ini, Minta admin untuk mengirim perintah /play untuk pertama kalinya atau menambahkan {user.first_name} secara manual"
        )
        return
    message.from_user.id
    message.from_user.first_name
    await lel.edit("🔎 **Menemukan**")
    message.from_user.id
    user_id = message.from_user.id
    message.from_user.first_name
    user_name = message.from_user.first_name
    rpk = "[" + user_name + "](tg://user?id=" + str(user_id) + ")"
    audio = (
        (message.reply_to_message.audio or message.reply_to_message.voice)
        if message.reply_to_message
        else None
    )
    if audio:
        if round(audio.duration / 60) > DURATION_LIMIT:
            raise DurationLimitError(
                f"❌ Video lebih panjang dari {DURATION_LIMIT} minute(s) tidak diperbolehkan diputar!"
            )
        keyboard = InlineKeyboardMarkup(
            [
                [
                    InlineKeyboardButton("📖 Playlist", callback_data="playlist"),
                    InlineKeyboardButton("Menu ⏯ ", callback_data="menu"),
                ],
                [InlineKeyboardButton(text="Support Channel", url="https://t.me/levinachannel")],
                [InlineKeyboardButton(text="Close", callback_data="cls")],
            ]
        )
        file_name = get_file_name(audio)
        title = file_name
        thumb_name = "https://telegra.ph/file/f6086f8909fbfeb0844f2.png"
        thumbnail = thumb_name
        duration = round(audio.duration / 60)
        views = "Locally added"
        requested_by = message.from_user.first_name
        await generate_cover(requested_by, title, views, duration, thumbnail)
        file_path = await converter.convert(
            (await message.reply_to_message.download(file_name))
            if not path.isfile(path.join("downloads", file_name))
            else file_name
        )
    else:
        query = ""
        for i in message.command[1:]:
            query += " " + str(i)
        print(query)
        await lel.edit("🎵 **Sabar aja cuk**")
        ydl_opts = {"format": "bestaudio[ext=m4a]"}
        try:
            results = YoutubeSearch(query, max_results=1).to_dict()
            url = f"https://youtube.com{results[0]['url_suffix']}"
            # print(results)
            title = results[0]["title"][:40]
            thumbnail = results[0]["thumbnails"][0]
            thumb_name = f"thumb{title}.jpg"
            thumb = requests.get(thumbnail, allow_redirects=True)
            open(thumb_name, "wb").write(thumb.content)
            duration = results[0]["duration"]
            results[0]["url_suffix"]
            views = results[0]["views"]

        except Exception as e:
            await lel.edit(
                "Song not found.Try another song or maybe spell it properly."
            )
            print(str(e))
            return

        keyboard = InlineKeyboardMarkup(
            [
                [
                    InlineKeyboardButton("📖 Playlist", callback_data="playlist"),
                    InlineKeyboardButton("Menu ⏯ ", callback_data="menu"),
                ],
                [InlineKeyboardButton(text="Support Channel", url="https://t.me/levinachannel")],
                [InlineKeyboardButton(text="Close", callback_data="cls")],
            ]
        )
        requested_by = message.from_user.first_name
        await generate_cover(requested_by, title, views, duration, thumbnail)
        file_path = await convert(youtube.download(url))
    chat_id = get_chat_id(message.chat)
    if chat_id in callsmusic.pytgcalls.active_calls:
        position = await queues.put(chat_id, file=file_path)
        qeue = que.get(chat_id)
        s_name = title
        r_by = message.from_user
        loc = file_path
        appendable = [s_name, r_by, loc]
        qeue.append(appendable)
        await message.reply_photo(
            photo="final.png",
            caption=f"#⃣ Your requested song **queued** at position {position}!",
            reply_markup=keyboard,
        )
        os.remove("final.png")
        return await lel.delete()
    else:
        chat_id = get_chat_id(message.chat)
        que[chat_id] = []
        qeue = que.get(chat_id)
        s_name = title
        r_by = message.from_user
        loc = file_path
        appendable = [s_name, r_by, loc]
        qeue.append(appendable)
        try:
            callsmusic.pytgcalls.join_group_call(chat_id, file_path)
        except:
            message.reply("Group Call is not connected or I can't join it")
            return
        await message.reply_photo(
            photo="final.png",
            reply_markup=keyboard,
            caption="▶ **Playing** Permintaan dari {} via Youtube Music 😜".format(
                message.from_user.mention()
            ),
        )
        os.remove("final.png")
        return await lel.delete()

@Client.on_message(filters.command("dplay") & filters.group & ~filters.edited)
async def deezer(client: Client, message_: Message):
    global que
    lel = await message_.reply("🔄 **Sabar aja cuk**")
    administrators = await get_administrators(message_.chat)
    chid = message_.chat.id
    try:
        user = await USER.get_me()
    except:
        user.first_name = "MY-VCG"
    usar = user
    wew = usar.id
    try:
        # chatdetails = await USER.get_chat(chid)
        await client.get_chat_member(chid, wew)
    except:
        for administrator in administrators:
            if administrator == message_.from_user.id:
                if message_.chat.title.startswith("Channel Music: "):
                    await lel.edit(
                        "Ingatlah untuk menambahkan pembantu ke saluran Anda",
                    )
                    pass
                try:
                    invitelink = await client.export_chat_invite_link(chid)
                except:
                    await lel.edit(
                        "Tambahkan saya sebagai admin grup Anda terlebih dahulu",
                    )
                    return

                try:
                    await USER.join_chat(invitelink)
                    await USER.send_message(
                        message_.chat.id, "Saya bergabung dengan grup ini untuk memutar musik di VC"
                    )
                    await lel.edit(
                        "helper userbot joined your chat",
                    )

                except UserAlreadyParticipant:
                    pass
                except Exception:
                    # print(e)
                    await lel.edit(
                        f"🔴 Kesalahan permintaan banjir 🔴 \nUser {user.first_name} Sudo kagak sabi gabung."
                        "\n\nAtau tambahin secara manual",
                    )
    try:
        await USER.get_chat(chid)
        # lmoa = await client.get_chat_member(chid,wew)
    except:
        await lel.edit(
            f" {user.first_name} Kagak sabi gabung cuk, coba admin play dulu atau tambahin {user.first_name} manual"
        )
        return
    requested_by = message_.from_user.first_name

    text = message_.text.split(" ", 1)
    queryy = text[1]
    res = lel
    await res.edit(f"Mencari untuk `{queryy}` di deezer")
    try:
        r = await arq.deezer(query=queryy, limit=1)
        title = r[0]["title"]
        duration = int(r[0]["duration"])
        thumbnail = r[0]["thumbnail"]
        artist = r[0]["artist"]
        url = r[0]["url"]
    except:
        await res.edit("Tidak Menemukan Apa-apa, Coba pake bahasa inggris!")
        return
    keyboard = InlineKeyboardMarkup(
        [
            [
                InlineKeyboardButton("📖 Playlist", callback_data="playlist"),
                InlineKeyboardButton("Menu ⏯ ", callback_data="menu"),
            ],
            [InlineKeyboardButton(text="Support Channel", url=f"Https://t.me/levinachannel")],
            [InlineKeyboardButton(text="❌ Close", callback_data="cls")],
        ]
    )
    file_path = await convert(wget.download(url))
    await res.edit("Membuat Gambar Mini")
    await generate_cover(requested_by, title, artist, duration, thumbnail)
    chat_id = get_chat_id(message_.chat)
    if chat_id in callsmusic.pytgcalls.active_calls:
        await res.edit("menambahkan dalam antrian")
        position = await queues.put(chat_id, file=file_path)
        qeue = que.get(chat_id)
        s_name = title
        r_by = message_.from_user
        loc = file_path
        appendable = [s_name, r_by, loc]
        qeue.append(appendable)
        await res.edit_text(f"#⃣ Antri di posisi {position}")
    else:
        await res.edit_text(f"▶ Playing.....")

        que[chat_id] = []
        qeue = que.get(chat_id)
        s_name = title
        r_by = message_.from_user
        loc = file_path
        appendable = [s_name, r_by, loc]
        qeue.append(appendable)
        try:
            callsmusic.pytgcalls.join_group_call(chat_id, file_path)
        except:
            res.edit("Panggilan grup tidak terhubung karena saya tidak dapat bergabung")
            return

    await res.delete()

    m = await client.send_photo(
        chat_id=message_.chat.id,
        reply_markup=keyboard,
        photo="final.png",
        caption=f"Playing [{title}]({url}) Via Deezer",
    )
    os.remove("final.png")

@Client.on_message(filters.command("splay") & filters.group & ~filters.edited)
async def jiosaavn(client: Client, message_: Message):
    global que
    lel = await message_.reply("🔄 **Sabar aja cuk**")
    administrators = await get_administrators(message_.chat)
    chid = message_.chat.id
    try:
        user = await USER.get_me()
    except:
        user.first_name = "Geez-MusicProject"
    usar = user
    wew = usar.id
    try:
        # chatdetails = await USER.get_chat(chid)
        await client.get_chat_member(chid, wew)
    except:
        for administrator in administrators:
            if administrator == message_.from_user.id:
                if message_.chat.title.startswith("Channel Music: "):
                    await lel.edit(
                        "Ingatlah untuk menambahkan pembantu ke saluran Anda",
                    )
                    pass
                try:
                    invitelink = await client.export_chat_invite_link(chid)
                except:
                    await lel.edit(
                        "Tambahkan saya sebagai admin grup Anda terlebih dahulu",
                    )
                    return

                try:
                    await USER.join_chat(invitelink)
                    await USER.send_message(
                        message_.chat.id, "Saya bergabung dengan grup ini untuk memutar musik di VC"
                    )
                    await lel.edit(
                        "helper userbot joined your chat",
                    )

                except UserAlreadyParticipant:
                    pass
                except Exception:
                    # print(e)
                    await lel.edit(
                        f"🔴 Permintaan banjir 🔴 \nUser {user.first_name} tidak dapat bergabung dengan grup Anda karena banyaknya permintaan untuk userbot! Pastikan pengguna tidak dilarang di grup."
                        "\n\nAtau tambahkan BOT Asisten secara manual ke Grup Anda dan coba lagi",
                    )
    try:
        await USER.get_chat(chid)
        # lmoa = await client.get_chat_member(chid,wew)
    except:
        await lel.edit(
            " helper Userbot tidak ada dalam obrolan ini, Minta admin untuk mengirim / memutar perintah untuk pertama kalinya atau menambahkan asisten secara manual"
        )
        return
    requested_by = message_.from_user.first_name
    chat_id = message_.chat.id
    text = message_.text.split(" ", 1)
    query = text[1]
    res = lel
    await res.edit(f"Searching for `{query}` on jio saavn")
    try:
        async with aiohttp.ClientSession() as session:
            async with session.get(
                f"https://jiosaavnapi.bhadoo.uk/result/?query={query}"
            ) as resp:
                r = json.loads(await resp.text())
        sname = r[0]["song"]
        slink = r[0]["media_url"]
        ssingers = r[0]["singers"]
        sthumb = r[0]["image"]
        sduration = int(r[0]["duration"])
    except Exception as e:
        await res.edit("Found Literally Nothing!, You Should Work On Your English.")
        print(str(e))
        return
    keyboard = InlineKeyboardMarkup(
        [
            [
                InlineKeyboardButton("📖 Playlist", callback_data="playlist"),
                InlineKeyboardButton("Menu ⏯ ", callback_data="menu"),
            ],
            [
                InlineKeyboardButton(
                    text="Join Updates Channel", url=f"{updateschannel}"
                )
            ],
            [InlineKeyboardButton(text="❌ Close", callback_data="cls")],
        ]
    )
    file_path = await convert(wget.download(slink))
    chat_id = get_chat_id(message_.chat)
    if chat_id in callsmusic.pytgcalls.active_calls:
        position = await queues.put(chat_id, file=file_path)
        qeue = que.get(chat_id)
        s_name = sname
        r_by = message_.from_user
        loc = file_path
        appendable = [s_name, r_by, loc]
        qeue.append(appendable)
        await res.delete()
        m = await client.send_photo(
            chat_id=message_.chat.id,
            reply_markup=keyboard,
            photo="final.png",
            caption=f"#⃣ Antri di posisi {position}",
        )

    else:
        await res.edit_text(f"▶ Playing.....")
        que[chat_id] = []
        qeue = que.get(chat_id)
        s_name = sname
        r_by = message_.from_user
        loc = file_path
        appendable = [s_name, r_by, loc]
        qeue.append(appendable)
        try:
            callsmusic.pytgcalls.join_group_call(chat_id, file_path)
        except:
            res.edit("Panggilan grup tidak terhubung karena saya tidak dapat bergabung")
            return
    await res.edit("Membuat Gambar Mini.")
    await generate_cover(requested_by, sname, ssingers, sduration, sthumb)
    await res.delete()
    m = await client.send_photo(
        chat_id=message_.chat.id,
        reply_markup=keyboard,
        photo="final.png",
        caption=f"Playing {sname} Via Jiosaavn",
    )
    os.remove("final.png")

# Have u read all. If read RESPECT :-)


import requests

api_address='https://api.cartola.globo.com/partidas'
response = requests.get(api_address).json()
jogos=''
for i in range(len(response['partidas'])):
    clube_casa_id=response['partidas'][i]['clube_casa_id']
    clube_casa=response['clubes'][str(clube_casa_id)]['nome_fantasia']
    clube_visitante_id=response['partidas'][i]['clube_visitante_id']
    clube_visitante=response['clubes'][str(clube_visitante_id)]['nome_fantasia']
    jogos=jogos+"\n"+clube_casa+" x "+clube_visitante
print(jogos)


'''
import numpy as np
import matplotlib.pyplot as plt

filelist=[]

liimited_filelist = []

x = np.linspace(-1, 1, 200)
j = 1
for i in range(1,100):
    filelist.append("FVM_1S_B&W_{}.txt".format(i))
    liimited_filelist.append("BeamW_Limited_{}.txt".format(i))

for fname, fname1 in zip(filelist, liimited_filelist):
    plt.figure(figsize=(12,6))
    data=np.loadtxt(fname)
    data1=np.loadtxt(fname1)
    #initial_data = np.loadtxt(initial_file[0])
    #initial_data = np.loadtxt(filelist[0])
    plt.plot(x, data, color = 'orange', linewidth = 0.7, label = 'B&W unlimited')
    plt.plot(x, data1, marker = 'o', markersize = 4, linewidth = 1.3, color = 'blue', label = 'B&W Method 2nd Order')
    #plt.plot(x, data, marker = 'o', markersize = 4, linewidth = 2, color = 'darkorange', label = 'B&W method Van\nAlbada Slope Limited')
    plt.plot(-1,1, color = 'black', label = 'timestep {}'.format(j))
    plt.title('1D Linear Convection 2nd Order Beam & Warming FVM Analysis ', fontsize=15)
    plt.xlabel('u (m/s)', fontsize=15)
    plt.ylabel('time t(s)', fontsize=15)
    plt.ylim(-0.4, 1.4)
    plt.xlim(-1.1, 1.1)
    #plt.title("1D Linear Convection FVM")
    plt.legend(loc = 'upper right')
    plt.savefig('B&W{}.png'.format(j))
    plt.clf()
    plt.close()
    j += 1

#plt.legend()
plt.show()

'''

import numpy as np
import matplotlib.pyplot as plt
import matplotlib.cm as cm
filelist=[]

#liimited_filelist = []
#iC_square=np.loadtxt('Data.txt')

#d1 = np.loadtxt('sol_10.txt')
x = np.linspace(0, 1, 100)
j = 1
for i in range(1,200):
    #if i % 5 == 0:
    filelist.append("Burgers_{}.txt".format(i))
    #liimited_filelist.append("FROMM_UNLIMITED_{}.txt".format(i))

#colour=iter(cm.rainbow(np.linspace(0,20,860)))
#plt.plot(x, d1, marker = 'o', markersize = 1, linewidth = 2, color = 'blue', label = 't = 0.0 s')
#plt.plot(x, iC_square, marker = 'o', markersize = 1.6, linewidth = 2, color = 'darkblue', label = 'CFL = 0.5')

for fname  in filelist:
    plt.figure(figsize=(8,8))
    #c=next(colour)
    data=np.loadtxt(fname)
    #data1=np.loadtxt(fname1)
    #initial_data = np.loadtxt(initial_file[0])
    #initial_data = np.loadtxt(filelist[0])
    plt.plot(x, data, marker = 'o', markersize = 5, linewidth = 2, color = 'blue', label = 'CFL = 0.5')

    #plt.plot(x1, initial_data, color = 'orange', linewidth = 0.7, label = 'Initial Condition')
    #plt.plot(x, data, marker = 'o', markersize = 2.1, linewidth = 1.3, color = 'blue', label = 'FROMM Method 2nd Order')
    #plt.plot(x, data, marker = 'o', markersize = 4, linewidth = 2, color = 'darkorange', label = 'Fromm method Van\nAlbada Slope Limited')
    #plt.plot(-1,1, color = 'black', label = 'timestep {}'.format(j))
    #plt.title('1D Inviscid Burgers Sine wave ICs ', fontsize=15)
    plt.ylabel('u (m/s)', fontsize=15)
    plt.xlabel('u (m)', fontsize=15)
    plt.ylim(-0.25, 1.25)
    plt.xlim(0, 1)
    plt.title("1D Advection equation")
    plt.legend(loc = 'upper right')
    plt.savefig('A{}.png'.format(j))
    plt.clf()
    plt.close()

    j += 1

#plt.legend()
plt.show()

'''

import numpy as np
import matplotlib.pyplot as plt

filelist=[]

liimited_filelist = []

x = np.linspace(0, 2 * np.pi, 100)
x1 = np.linspace(0, 2 * np.pi, 100)
x2 = np.linspace(-1, 1, 100)
x4 = np.linspace(-1, 1, 200)
x_ICs = np.linspace(-1, 1, 206)

j = 1

#for i in range(1,5):
#    filelist.append("laxwendroff_limited_step{}.txt".format(i))

plt.figure(figsize = (10,8))
data1=np.loadtxt('Data.txt')
#data2=np.loadtxt('sol_9.txt')

#iC_square=np.loadtxt('Square_Initial_conditions.txt')
#iC_sine=np.loadtxt('Sine_Initial_Conditions.txt')
#data1=np.loadtxt(fname1)
    #initial_data = np.loadtxt(initial_file[0])
    #initial_data = np.loadtxt(filelist[0])
    #plt.plot(x1, initial_data, color = 'orange', linewidth = 0.7, label = 'Initial Condition')
#plt.plot(x, data1, marker = 'o', markersize = 4, linewidth = 1.3, color = 'blue', label = 'Lax Fromm Method 2nd Order')
#plt.plot(x_ICs, iC_square, linewidth = 2, linestyle = 'dashed', color = 'red', label = 'Initial Conditions')
plt.plot(x, data1, marker = 'o', markersize = 2, linewidth = 2, color = 'blue', label = 'limited')
#plt.plot(x1, data2, marker = 'o', markersize = 2, linewidth = 2, color = 'red', label = 'limited')

#plt.plot(x, data2, marker = 'o', markersize = 2, linewidth = 2.5, color = 'green', label = 'limited')
#plt.plot(x_ICs, iC_square,  linewidth = 1.6, color = 'red', linestyle='dashed', label = 'limited')

#plt.plot(x2, data3, marker = 'o', markersize = 2, linewidth = 1.7, color = 'red', label = 'NX = 100')

#plt.plot(x4, data4, marker = 'o', markersize = 2, linewidth = 1.7, color = 'darkturquoise', label = 'NX = 100')

#plt.plot(x_ICs, iC_sine, linewidth = 2, color = 'red', linestyle = 'dashed', label = 'Initial Conditions')
#plt.plot(-1,1, color = 'black', label = 'timestep {}'.format(j))
#plt.title('2nd Order Lax Wendroff Slope Limiter Comparison T = 2.0 s', fontsize=15)
#plt.xlabel('u (m/s)', fontsize=15)
#plt.ylabel('time t(s)', fontsize=15)
#plt.xlabel('u (m/s)', fontsize=15)
#plt.ylabel('time t(s)', fontsize=15)
#plt.ylim(-0.1, 1.2)
#plt.xlim(-0.1, 1.1)
#plt.xticks([-1, -0.5, 0, 0.5, 1])
#lt.yticks([0, 0.2, 0.4, 0.6, 0.8, 1])
#plt.title("F.O Lax Fredrichs:  Time = 2.0 s", fontsize = 20)
plt.legend(loc = 'upper right')

j += 1

#plt.legend()
plt.savefig("F.0.png")
plt.show()

'''
'''
import numpy as np
import matplotlib.pyplot as plt
import math

x = np.linspace(1,180, 180)
for i in range(len(x)):
    x[i] *= 0.0174533
print(x)
y = []
y1 = []
y2 = []

z = []
z1 = []
z2 = []

for i in range(len(x)):
    y.append(   (math.cos(x[i])**2 + (0.25 * 0.25) * math.sin(x[i])**2)**0.5  )
    y1.append(   (math.cos(x[i])**2 + (0.5 * 0.5) * math.sin(x[i])**2)**0.5  )
    y2.append(   (math.cos(x[i])**2 + (0.8 * 0.8) * math.sin(x[i])**2)**0.5  )
    z.append(   (math.atan(.25 * math.tan(x[i])) / (.25 * x[i])))
    z1.append(   (math.atan(.5 * math.tan(x[i])) / (.5 * x[i])))
    z2.append(   (math.atan(.8 * math.tan(x[i])) / (.8 * x[i])))

fig, (ax,ax2) = plt.subplots(1,2, figsize=(13,5))
plt.title("Lax Fredrichs Diffusion Error")
ax.grid(b=True, which='major', color='#666666', linestyle='-')
ax.minorticks_on()
ax.grid(b=True, which='minor', color='#999999', linestyle='-', alpha=0.2)

ax2.grid(b=True, which='major', color='#666666', linestyle='-')
ax2.minorticks_on()
ax2.grid(b=True, which='minor', color='#999999', linestyle='-', alpha=0.2)

ax2.plot(x, z, label = 'Sigma = 0.25', linewidth = 2)
ax2.plot(x, z1, label = 'Sigma = 0.5', linestyle = 'dashdot', linewidth = 2)
ax2.plot(x, z2,label = 'Sigma = 0.8', linestyle = 'dashed', linewidth = 2)

ax.plot(x, y, label = 'Sigma = 0.25', linewidth = 2)
ax.plot(x, y1, label = 'Sigma = 0.5', linestyle = 'dashdot', linewidth = 2)
ax.plot(x, y2,label = 'Sigma = 0.8', linestyle = 'dashed', linewidth = 2)

ax.set_xlabel("Phase angle radians")
ax.set_ylabel("Sigma")
ax2.set_xlabel("Phase angle radians")
ax2.set_ylabel("Sigma")

#ax.set_ylim(0, 6)
ax.set_xlim(0, np.pi)

ax2.set_ylim(0, 6)
ax2.set_xlim(0, np.pi/2.1)

plt.legend()
plt.show()

plt.savefig("Lax-Fredrichs-Diffusion-Error-Plot.png")
'''


class CheckCard:
    def __init__(self):
        self.data = ""

    def get_data(self):
        return self.data

    def set_data(self, data):
        while not self.check_valid(data):
            data = input("Invalid data! Please, re-enter the data:")
        self.data = data

    @staticmethod
    def check_valid(data):
        num_blocks = data.split("-")
        if len(num_blocks) != 4:
            return False
        else:
            block_len = len(num_blocks[0])
            for i in num_blocks:
                if len(i) != block_len or not i.isdigit():
                    return False
            return True

    @staticmethod
    def compare(card1, card2):
        return card1.data == card2.data

    def display(self):
        print("Card data:")
        print(self.data)

card = CheckCard()
card1 = CheckCard()
data = input("Please, enter card data:")
card.set_data(data)
card1.set_data(data)
print("Current data is: ", card.get_data())
card.display()
print("Cards are same? ", CheckCard.compare(card, card1))


#standard imports
from datetime import datetime as dt
import utils
import Rooms.Room as Room
#room specific imports
import Rooms.Hallway as Hallway
import Rooms.Armory as Armory
import Rooms.Guards_Room as Guards_Room
import Puzzles.hangman as hangman
import win_lose as win_lose

class Main_Chamber(Room.Room):

    def __init__(self, player, starttime):
        super().__init__(
            "Main_Chamber",
            "You find yourself in a large chamber, in each wall there is a door. In the far wall is the door to the armory, in the wall to the left is the door to the guards room, in the wall to your right is the door to the outside world. Various machines rest haphazerdly about the room, some glow with heat others lay dormant. In one corner is a gallows, presumably for prisoners like you. Besides the gallows, with their back to you, stands the excecutioner.",
            [{
                "name": "hallway door",
                "actions": ["open"]
            }, {
                "name": "armory door",
                "actions": ["open"]
            }, {
                "name": "guard's room door",
                "actions": ["open"]
            }, {
                "name": "door to outside",
                "actions": ["open"]
            }, {
                "name": "gallows",
                "actions": ["inspect"]
            }, {
                "name": "executioner",
                "actions": ["inspect", "talk"]
            }, {
                "name": "mysterious spiky machine",
                "actions": ["inspect", "pull lever"]
            }], player, starttime)

    def start_room(self):
        utils.print_line_of_char("#")
        utils.print_centered_text(self.name)
        utils.print_line_of_char("#")
        print(f"Gametime elapsed: {dt.now() - self.starttime}")
        print(self.description)
        leave = False
        while leave == False:
            [current_item, current_action, item_index] = self.listItems()
            if current_item == "hallway door":
                if current_action == "open":
                    start = Hallway.Hallway(self.player, self.starttime)
                    start.start_room()
            if current_item == "armory door":
                if current_action == "open":
                    start = Armory.Armory(self.player, self.starttime)
                    start.start_room()
            if current_item == "guard's room door":
                if current_action == "open":
                    if self.player.isInItems("guard's uniform"):
                        start = Guards_Room.Guards_Room(
                            self.player, self.starttime)
                        start.start_room()
                    else:
                        win_lose.end(
                            'Upon seeing a free prisoner entering the guards room, the guard captain orders you be incarcerated in a maximum security cell. YOU HAVE FAILED TO ESCAPE THE DUNGEONS OF MORDOR!',
                            self.starttime)
            if current_item == "door to outside":
                if current_action == "open":
                    if self.player.isInItems("master key"):
                        print("YOU HAVE ESCAPED!")
                        win_lose.end(
                            'You emerge from the dungeons to breath the smoky air on the slopes of mount doom, YOU HAVE ESCAPED THE DUNGEONS OF MORDOR!',
                            self.starttime)
                    else:
                        print(
                            "The door is locked, you didn't think it would be that easy did you..."
                        )
            if current_item == "gallows":
                if current_action == "inspect":
                    print(
                        "Just your ordinary gallows, they look quite well cared for though..."
                    )
            if current_item == "executioner":
                if current_action == "inspect":
                    print(
                        "The excecutioner appears to not have noticed your entrance, they are standing with their back to you, mending a noose from the gallows."
                    )
                if current_action == "talk":
                    if self.player.isInItems("guard's uniform"):
                        print(
                            "Excecutioner: 'Hello there, have you heard of the new security protocol? (Cackles) If you don't know the password you hang! Don't remember? Care to guess? Of course you do!'"
                        )
                        win = hangman.play_game()
                        if win == True:
                            utils.print_centered_text(
                                "*** You got the password ***")
                            self.player.insertItem("password")
                        else:
                            win_lose.end(
                                'You are hanged by the excecutioner, YOU HAVE FAILED TO ESCAPE THE DUNGEONS OF MORDOR!',
                                self.starttime)
                    else:
                        print(
                            "Excecutioner: 'You're an escaped prisoner! GUARDS! GUARDS!'"
                        )
                        win_lose.win(
                            'You are captured by the Guards and taken to a maximum security cell, YOU HAVE FAILED TO ESCAPE THE DUNGEONS OF MORDOR!',
                            self.starttime)
            if current_item == "mysterious spiky machine":
                if current_action == "inspect":
                    print(
                        "Just your average every day spiky machine, for...spiking things?"
                    )
                if current_action == "pull lever":
                    print("Nothing happened...wait...yeah nothing happend...")


from flask import Flask, request, render_template
import paymentwall
app = Flask(__name__)
# Initialize Paymentwall API keys

paymentwall.Paymentwall.configure(
    paymentwall.PublicKey('YOUR_PUBLIC_KEY'),
    paymentwall.PrivateKey('YOUR_PRIVATE_KEY')
)

@app.route('/checkout', methods=['POST', 'GET'])
def checkout():
    if request.method == 'POST':
        product_id = 'your_product_id'  #actual product ID
        amount = 50.0  #$
        #paymentwall widget
        widget = paymentwall.Widget(
            product_id,
            'user_email@example.com',  #user's email
            {
                'amount': amount,
                'currency_code': 'USD',
                'description': 'Product Description',
                'custom': 'Custom Parameter'  # Optional custom parameter
            }
        )
        return render_template('checkout.html', widget=widget.get_html_code())
    return 'Invalid request'

@app.route('/payment_success', methods=['POST'])
def payment_success():
    widget = paymentwall.Widget(request.form['widget'])
    if widget.verify_signature(request.form):
        transaction_id = request.form['id']
        return 'Payment Success! Transaction ID: {}'.format(transaction_id)
    else:
        return 'Payment Verification Failed'

if __name__ == '__main__':
    app.run()


from util import read_input
lines = read_input()

calories = []
sum_c = 0
for l in lines:
    l = l.strip()
    if l:
        sum_c += int(l)
    else:
        calories.append(sum_c)
        sum_c = 0

calories.sort(reverse=True)
print(calories[0], sum(calories[:3]))


"""
The LabelFrame widget, like the Frame widget, is a spatial container—a rectangular
area that can contain other widgets. However, unlike the Frame widget, the LabelFrame
widget allows you to display a label as part of the border around the area.
https://anzeljg.github.io/rin2/book2/2405/docs/tkinter/labelframe.html"""

import tkinter as tk

root = tk.Tk()
root.geometry('360x360')
root.title("Labeled Frames")

# Creating the Labeled Frame
frame_1 = tk.LabelFrame(root, text='Buttons')
frame_1.grid(row=0, column=0, padx=5, pady=5)

# Creating the widgets to be placed in the frame
button_1 = tk.Button(frame_1, text='Press')
button_1.grid(row=0, column=0)

button_2 = tk.Button(frame_1, text='Press')
button_2.grid(row=0, column=1, padx=20)

root.mainloop()


""" 373. Find K Pairs with Smallest Sums """

"""
Complexities.
Time: O(k log(m + n))
Space: O(m + n)
where k is as in the problem statement, and m and n are the lengths of the two
input arrays.
"""

"""
Idea.
We arrange the index tuples in a grid:
  (0,0) (0,1) ⋯ ⋯ (0,n)
  (1,0) (1,1) ⋯ ⋯ (1,n)
  ⋮       ⋮   ⋱     ⋮
  ⋮       ⋮     ⋱   ⋮
  (m,0) (m,1) ⋯ ⋯ (m,n)
The associated sums  nums1[i] + nums2[j]  are increasing in each row and in
each column. We start with the top-left entry, (0, 0), giving us the sum
nums1[0] + nums2[0]. The possible fields for the next choice are (0, 1) and
(1, 0). As the algorithm continues, the chosen entries form a connected,
convex-like area in the top-left of the grid. The possible choices for the
next field are the fields bordering this area:

  * ? . . . .   * ? . . . .   * * ? . . .   * * ? . . .   * * * ? . .
  ? . . . . .   * ? . . . .   * ? . . . .   * ? . . . .   * ? ? . . .
  . . . . . .   ? . . . . .   ? . . . . .   * ? . . . .   * ? . . . .
  . . . . . .   . . . . . .   . . . . . .   ? . . . . .   ? . . . . .

   * * * ? . .   * * * ? . .   * * * ? . .   * * * * ? .   * * * * ? .
   * * ? . . .   * * ? . . .   * * ? . . .   * * ? ? . .   * * ? ? . .
   * ? . . . .   * ? . . . .   * * ? . . .   * * ? . . .   * * ? . . .
   ? . . . . .   * ? . . . .   * ? . . . .   * ? . . . .   * * ? . . .

We keep track of the possible next field in a priority queue, implemented via a
binary heap. To make sure that this heap doesn’t contain duplicate entries, we
also keep track of a list l such that l[i] is the right-most column index j for
which (i, j) has been in the heap so far. If we have no fields from the row-th
row in the heap, then the length of l is smaller or equal to row. In the above
example, the heap and auxiliary list l look as follows:

  heap: (0,1) (1,0)    heap: (0,1) (1,1) (2,0)    heap: (0,2) (1,1) (2,0)
  l: 1 0               l: 1 1 0                   l: 2 1 0

  heap: (0,2) (1,1) (2,1) (3,0)    heap: (0,3) (1,1) (1,2) (2,1) (3,0)
  l: 2 1 1 0                       l: 3 2 1 0

  heap: (0,3) (1,2) (2,1) (3,0)    heap: (0,3) (1,2) (2,1) (3,1)
  l: 3 2 1 0                       l: 3 2 1 1

  heap: (0,3) (1,2) (2,2) (3,1)    heap: (0,4) (1,2) (1,3) (2,2) (3,1)
  l: 3 2 2 1                       l: 4 3 2 1

  heap: (0,4) (1,2) (1,3) (2,2) (3,2)
  l: 4 3 2 2
"""

import heapq

class PriorityQueue:
    def __init__(self) -> None:
        self._entries: list[tuple[int, int, int]] = []  # the heap
        self._maxColIndex: list[int] = []  # the list l

    def updateEntry(self, row: int, column: int):
        if row >= len(self._maxColIndex):
            self._maxColIndex.append(0)
            return True
        if self._maxColIndex[row] < column:
            self._maxColIndex[row] += 1
            return True
        return False

    def push(self, entry):
        (_, row, column) = entry
        if self.updateEntry(row, column):
            heapq.heappush(self._entries, entry)

    def pop(self):
        return heapq.heappop(self._entries)

    @property
    def size(self):
        return len(self._entries)

class Solution:
    def kSmallestPairs(
        self, nums1: list[int], nums2: list[int], k: int
    ) -> list[tuple[int, int]]:
        result: list[tuple[int, int]] = []
        smallest = PriorityQueue()
        smallest.push((nums1[0] + nums2[0], 0, 0))
        while k > 0 and smallest.size > 0:
            (_, i, j) = smallest.pop()
            result.append((nums1[i], nums2[j]))
            k -= 1
            if i + 1 < len(nums1):
                smallest.push((nums1[i + 1] + nums2[j], i + 1, j))
            if j + 1 < len(nums2):
                smallest.push((nums1[i] + nums2[j + 1], i, j + 1))
        return result


"""
CCC '08 J5/S5 - Nukit
Find this problem at:
https://dmoj.ca/problem/ccc08s5
"""

rules = [[2, 1, 0, 2], [1, 1, 1, 1], [0, 0, 2, 1], [0, 3, 0, 0], [1, 0, 0, 1]]
memoize = {}

def get_new_moves(cur):
    new_moves = []
    for rule in rules:
        new = cur[::]
        for i in range(4):
            new[i] -= rule[i]
            if new[i] < 0:
                break
        else:
            new_moves.append(new)
    return new_moves

def a_moves(cur):
    key = 'a' + ''.join(map(str, cur))
    if key not in memoize:
        new_moves = get_new_moves(cur)
        # All moves player A can needs to lead to a win for player B
        memoize[key] = not new_moves or all(
            b_moves(move) for move in new_moves)
    return memoize[key]

def b_moves(cur):
    key = 'b' + ''.join(map(str, cur))
    if key not in memoize:
        new_moves = get_new_moves(cur)
        # Player B only needs to have one move that wins
        memoize[key] = new_moves and any(
            a_moves(move) for move in new_moves)
    return memoize[key]

for _ in range(int(input())):
    memoize = {}
    # Check wether player B will win
    if a_moves(list(map(int, input().split()))):
        print("Roland")
    else:
        print("Patrick")


import os
from sqlalchemy import create_engine
from sqlalchemy.orm import scoped_session, sessionmaker
from tornado.web import (
    RequestHandler,
    Application,
    url as unnamed_url)

import logging
from logging.handlers import SysLogHandler, SMTPHandler
from uuid import uuid4
from tornado.options import options
from logging import getLogger
from pystil.db import metadata, Visit
from threading import Thread
from queue import Queue

MESSAGE_QUEUE = Queue()

log = getLogger("pystil")

class Tracking(Thread):
    daemon = True

    def __init__(self, db, log, *args, **kwargs):
        super(Tracking, self).__init__(*args, **kwargs)
        self.log = log
        self.db = db

    def run(self):
        from pystil.websocket import broadcast
        from pystil.utils import visit_to_table_line
        while True:
            try:
                self.log.debug('Blocking for messages')
                message = MESSAGE_QUEUE.get(True)
                self.log.debug('Message got %r' % message)
                try:
                    visit_or_uuid, opening = message.process(self.db)

                    if opening:
                        visit = Visit(**visit_or_uuid)
                        broadcast(
                            'VISIT|' + visit.host + '|' +
                            visit_to_table_line(visit))
                    else:
                        visit_or_uuid and broadcast('EXIT|%s' % visit_or_uuid)
                except:
                    self.log.exception('Error processing visit')
            except:
                self.log.exception('Exception in loop')

class Pystil(Application):
    def listen(self, *args, **kwargs):
        super(Pystil, self).listen(*args, **kwargs)
        db_url = 'postgresql+psycopg2://%s:%s@%s:%d/%s' % (
            options.db_user,
            options.db_password,
            options.db_host,
            options.db_port,
            options.db_name)

        self.db_engine = create_engine(db_url, echo=False)
        metadata.reflect(bind=self.db_engine, schema='agg')
        self.db_metadata = metadata
        self.db = scoped_session(sessionmaker(bind=self.db_engine))
        Tracking(self.db_engine.connect(), self.log).start()
        if not options.debug:
            handler = SysLogHandler(
                address='/dev/log', facility=SysLogHandler.LOG_LOCAL1)
            handler.setLevel(logging.INFO)
            handler.setFormatter(
                logging.Formatter(
                    'PYSTIL: %(name)s: %(levelname)s %(message)s'))

            smtp_handler = SMTPHandler(
                'smtp.keleos.fr',
                'no-reply@pystil.org',
                'pystil-errors@kozea.fr',
                'Pystil Exception')
            smtp_handler.setLevel(logging.ERROR)

            log.addHandler(smtp_handler)
            for logger in (
                    'tornado.access',
                    'tornado.application',
                    'tornado.general',
                    'sqlalchemy'):
                getLogger(logger).addHandler(handler)
                getLogger(logger).addHandler(smtp_handler)
        else:
            self.log.setLevel(logging.DEBUG)
            try:
                from wdb.ext import wdb_tornado, add_w_builtin
            except ImportError:
                pass
            else:
                wdb_tornado(self, start_disabled=True)
                add_w_builtin()

            #getLogger('sqlalchemy').setLevel(logging.DEBUG)

    @property
    def log(self):
        return log

pystil = Pystil(
    debug=options.debug,
    protocol=options.protocol,
    cookie_secret=options.secret,
    static_path=os.path.join(os.path.dirname(__file__), "static"),
    template_path=os.path.join(os.path.dirname(__file__), "templates")
)

class Hdr(RequestHandler):
    @property
    def db(self):
        return self.application.db

    @property
    def log(self):
        return log

    def prepare(self):
        if not self.get_secure_cookie('_pystil_site'):
            self.log.info('Setting secure cookie')
            self.set_secure_cookie('_pystil_site', 'local|' + str(uuid4()))

    def on_finish(self):
        self.db.rollback()

class url(object):
    def __init__(self, url):
        self.url = url

    def __call__(self, cls):
        pystil.add_handlers(
            r'.*$',
            (unnamed_url(self.url, cls, name=cls.__name__),)
        )
        return cls