// File: Computer-Kids-Club[P]screenshare-pro-backend/server.cpp
// Function: main
int main(int argc, char *argv[]) {
    int opt = TRUE;
    int master_socket, addrlen, new_socket,
        max_clients = 30, activity, i, valread, sd;
    int max_sd;
    struct sockaddr_in address;

    bool doPrintSocketFrame = false;
    bool doPrintSocketFrameStats = false;

    // yes
    for (int i = 0; i < argc; i++) {
        if (argv[i][0] == '-') {
            if (strcmp(argv[i], "-pf") == 0) {
                doPrintSocketFrame = true;
            } else if (strcmp(argv[i], "-pfs") == 0) {
                doPrintSocketFrameStats = true;
            }
        }
    }

    unsigned long long totalFramesRecieved = 1;
    unsigned long long totalFramesSent = 1;
    unsigned long long lastFrameLength = 0;
    unsigned long long totalFrameLength = 0;

    std::unordered_map<std::string, int> urlToSocketDesc;
    std::unordered_map<int, std::vector<Client>> socketDescToClients;
    std::unordered_map<int, int> clientSocketDescToStreamerSocketDesc;
    std::unordered_map<int, Client> clients;

    char buffer[BUFFER_SIZE + 1];       //data buffer of 1K
    char send_buffer[BUFFER_SIZE + 1];  //data buffer of 1K

    //set of socket descriptors
    fd_set readfds;

    //create a master socket
    if ((master_socket = socket(AF_INET, SOCK_STREAM, 0)) == 0) {
        perror("socket failed");
        exit(EXIT_FAILURE);
    }

    //set master socket to allow multiple connections ,
    //this is just a good habit, it will work without this
    if (setsockopt(master_socket, SOL_SOCKET, SO_REUSEADDR, (char *)&opt,
                   sizeof(opt)) < 0) {
        perror("setsockopt");
        exit(EXIT_FAILURE);
    }

    //type of socket created
    address.sin_family = AF_INET;
    address.sin_addr.s_addr = INADDR_ANY;
    address.sin_port = htons(PORT);

    //bind the socket to localhost port 4004
    if (0 > bind(master_socket, (struct sockaddr *)&address, sizeof(address))) {
        perror("bind failed");
        exit(EXIT_FAILURE);
    }
    printf(COLOR_RESET "Listener on port %d \n", PORT);

    //try to specify maximum of 3 pending connections for the master socket
    if (listen(master_socket, 3) < 0) {
        perror("listen");
        exit(EXIT_FAILURE);
    }

    //accept the incoming connection
    addrlen = sizeof(address);
    puts("Waiting for connections ...");

    while (TRUE) {
        //clear the socket set
        FD_ZERO(&readfds);

        //add master socket to set
        FD_SET(master_socket, &readfds);
        max_sd = master_socket;

        //add child sockets to set
        for (auto &clientFromClients : clients) {
            Client client = clientFromClients.second;
            //socket descriptor
            sd = client.socket_descriptor;

            //if valid socket descriptor then add to read list
            if (sd > 0)
                FD_SET(sd, &readfds);

            //highest file descriptor number, need it for the select function
            if (sd > max_sd)
                max_sd = sd;

            if (client.last_ping != -1) {
                if (client.last_ping != -1) {
                }
            }
        }

        //wait for an activity on one of the sockets , timeout is NULL ,
        //so wait indefinitely
        activity = select(max_sd + 1, &readfds, NULL, NULL, NULL);

        if ((activity < 0) && (errno != EINTR)) {
            printf("select error");
        }

        //If something happened on the master socket ,
        //then its an incoming connection
        if (FD_ISSET(master_socket, &readfds)) {
            if (0 > (new_socket = accept(master_socket, (struct sockaddr *)&address, (socklen_t *)&addrlen))) {
                perror("accept");
                exit(EXIT_FAILURE);
            }

            //inform user of socket number - used in send and receive commands
            printf(GREEN("New connection , socket fd is %d , ip is : %s , port : %d  \n"), new_socket, inet_ntoa(address.sin_addr), ntohs(address.sin_port));

            //puts("Welcome message sent successfully");

            clients[new_socket] = {new_socket, 0, "", -1};
            // clients.push_back({new_socket, 0});
            //printf("Adding to list of sockets as %d\n", i);
        }

        //else its some IO operation on some other socket
        // for (auto socketClientPair = clients.begin(); socketClientPair != clients.end(); ++socketClientPair) { //&socketClientPair : clients)
        auto it = clients.begin();
        while (it != clients.end()) {
            if (doPrintSocketFrameStats) {
                printf(COLOR_RESET "Total frames recieved: %llu\n", totalFramesRecieved);
                printf(COLOR_RESET "Total frames sent: %llu\n", totalFramesSent);
                printf(COLOR_RESET "Last frame length: %llu\n", lastFrameLength);
                printf(COLOR_RESET "Average frame length: %llu\n\n", totalFrameLength / totalFramesRecieved);
            }

            Client client = it->second;
            auto previous_it = it;
            ++it;
            //socket descriptor
            sd = client.socket_descriptor;
            if (FD_ISSET(sd, &readfds)) {
                //Check if it was for closing , and also read the
                //incoming message
                memset(buffer, 0, sizeof(buffer));

                int read_size = BUFFER_SIZE;

                if (client.startedWS == 1) {
                    read_size = 10;
                }
                if ((valread = read(sd, buffer, read_size)) == 0) {
                    //Somebody disconnected , get his details and print
                    getpeername(sd, (struct sockaddr *)&address, (socklen_t *)&addrlen);
                    printf(MAGENTA("Host disconnected , ip %s , port %d \n"), inet_ntoa(address.sin_addr), ntohs(address.sin_port));

                    //Close the socket and mark as 0 in list for reuse
                    close(sd);
                    //socketDescToClients[sd].erase(std::remove(socketDescToClients[sd].begin(), socketDescToClients[sd].end(), clients[sd]), socketDescToClients[sd].end());
                    it = clients.erase(previous_it);
                    continue;
                } else {
                    //set the string terminating NULL byte on the end
                    //of the data read
                    buffer[valread] = '\0';

                    if (client.startedWS == 1) {
                        unsigned int fin = (unsigned int)(buffer[0] & 0b10000000) == 0b10000000;
                        unsigned int opcode = (unsigned int)(buffer[0] & 0b00001111);
                        if (opcode > 2) {
                            //printf(BACK_YELLOW(RED("Something is very wrong: 1.") "\n=============================================================\n"));
                            //continue;
                        } else if (fin == 0 || opcode == 0) {
                            //printf(BACK_YELLOW(RED("Something is very wrong: 2.") "\n=============================================================\n"));
                            continue;
                        }
                        unsigned long payload_length = (unsigned int)(buffer[1] & 0b01111111);
                        unsigned int bit_offset = 2;
                        if (payload_length == 126) {
                            bit_offset += 2;
                            payload_length = (unsigned int)(buffer[2] & 0b11111111);
                            payload_length = payload_length << 8;
                            payload_length += (unsigned int)(buffer[3] & 0b11111111);
                        } else if (payload_length == 127) {
                            bit_offset += 8;
                            payload_length = (unsigned int)(buffer[2] & 0b11111111);
                            for (int shift_i = 0; shift_i < 7; shift_i++) {
                                payload_length = payload_length << 8;
                                payload_length += (unsigned int)(buffer[3 + shift_i] & 0b11111111);
                            }
                        }
                        if (doPrintSocketFrame) {
                            printf(BACK_YELLOW("================= Recieved websocket Frame ==================") ".");
                            printf("\n" BACK_YELLOW(" ") " Fin: %x ", fin);
                            printf(("Opcode: %x "), opcode);
                            printf(("Is masked: %d "), (unsigned int)((buffer[1] & 0b10000000) == 0b10000000));
                            printf(("Payload length: %lu"), payload_length);
                            printf(("\n" BACK_YELLOW(" ") " Mask: %x %x %x %x "),
                                   (unsigned int)(buffer[bit_offset + 0] & 0b11111111),
                                   (unsigned int)(buffer[bit_offset + 1] & 0b11111111),
                                   (unsigned int)(buffer[bit_offset + 2] & 0b11111111),
                                   (unsigned int)(buffer[bit_offset + 3] & 0b11111111));
                        }

                        bit_offset += 4;

                        totalFramesRecieved++;

                        int totalread = valread;
                        if (payload_length + bit_offset + 1 > BUFFER_SIZE) {
                            while (totalread < payload_length + bit_offset && (valread = read(sd, buffer, payload_length + bit_offset - totalread)) != 0) {
                                totalread += valread;
                            }
                            lastFrameLength = totalread;
                            totalFrameLength += totalread;
                            printf(BACK_YELLOW(RED("Dropped frame.")) " (Frame size is greater than %d bytes)\n", BUFFER_SIZE);
                            continue;
                        };
                        while (totalread < payload_length + bit_offset) {
                            valread = read(sd, buffer + totalread, payload_length + bit_offset - totalread);
                            totalread += valread;
                        }
                        lastFrameLength = totalread;
                        totalFrameLength += totalread;
                        buffer[totalread] = '\0';
                        if (doPrintSocketFrame) {
                            printf(("Total read length: %d\n"), totalread);
                            printf(BACK_YELLOW("=============================================================\n"));
                        }

                        //printf("Unmasked payload: \n>");
                        for (int payload_i = 0; payload_i < payload_length; payload_i++) {
                            buffer[bit_offset + payload_i] = buffer[bit_offset + payload_i] ^ buffer[bit_offset - 4 + payload_i % 4];
                            //printf("%c", buffer[bit_offset + payload_i]);
                        }

                        if (payload_length > 7 && buffer[bit_offset + 2] == 'h' && buffer[bit_offset + 3] == 'r' && buffer[bit_offset + 4] == 'e' && buffer[bit_offset + 5] == 'f') {
                            std::string url = std::string(buffer + bit_offset + 9, buffer + bit_offset - 2 + payload_length);
                            printf("%s\n", url.c_str());
                            if (url.compare(baseUrl) == 0) {
                                std::string stream_url = url + std::to_string(sd);
                                urlToSocketDesc[stream_url] = sd;
                                socketDescToClients[sd] = std::vector<Client>();

                                int send_len = generate_ws_frame(send_buffer, "{\"url\":\"" + stream_url + "\",\"streamer\":" + std::to_string(sd) + "}");

                                if (send(sd, send_buffer, send_len, 0) != send_len) {
                                    perror("send");
                                }

                                continue;
                            } else {
                                previous_it->second.url = url;
                                clientSocketDescToStreamerSocketDesc[sd] = urlToSocketDesc[url];
                                socketDescToClients[urlToSocketDesc[url]].push_back(previous_it->second);

                                int send_len = generate_ws_frame(send_buffer, "{\"watcher\":" + std::to_string(sd) + ",\"streamer\":" + std::to_string(urlToSocketDesc[url]) + "}");

                                if (send(sd, send_buffer, send_len, 0) != send_len) {
                                    perror("send");
                                }
                            }
                            continue;
                        }

                        if (opcode != 1 && opcode != 2) {
                            continue;
                        }

                        //printf("Bit offset: %d\n", bit_offset);

                        for (int payload_i = 0; payload_i < payload_length; payload_i++) {
                            buffer[bit_offset - 4 + payload_i] = buffer[bit_offset + payload_i];
                        }

                        buffer[0] = buffer[0] & 0b10001111;
                        buffer[1] = buffer[1] & 0b01111111;

                        opcode = (unsigned int)(buffer[0] & 0b00001111);

                        buffer[bit_offset - 4 + payload_length] = '\0';
                        buffer[bit_offset - 3 + payload_length] = '\0';
                        buffer[bit_offset - 2 + payload_length] = '\0';
                        buffer[bit_offset - 1 + payload_length] = '\0';

                        int target_sd_bit_offset = bit_offset - 4;
                        if (buffer[target_sd_bit_offset] == 't' && buffer[target_sd_bit_offset + 1] == 'o') {
                            int target_sd = 0;
                            target_sd_bit_offset += 2;
                            while (buffer[target_sd_bit_offset] != '{') {
                                target_sd = target_sd * 10 + buffer[target_sd_bit_offset++] - '0';
                            }
                            if (send(target_sd, buffer, bit_offset - 4 + payload_length, 0) != bit_offset - 4 + payload_length) {
                                perror("send");
                            } else {
                                totalFramesSent++;
                            }
                        } else if (clientSocketDescToStreamerSocketDesc[sd] && clientSocketDescToStreamerSocketDesc[sd] != sd) {
                            if (send(clientSocketDescToStreamerSocketDesc[sd], buffer, bit_offset - 4 + payload_length, 0) != bit_offset - 4 + payload_length) {
                                perror("send");
                            } else {
                                totalFramesSent++;
                            }
                        } else {
                            for (auto clientForSocket = socketDescToClients[sd].begin(); clientForSocket != socketDescToClients[sd].end();) {
                                if (send(clientForSocket->socket_descriptor, buffer, bit_offset - 4 + payload_length, 0) != bit_offset - 4 + payload_length) {
                                    perror("send");
                                    clientForSocket = socketDescToClients[sd].erase(clientForSocket);
                                } else {
                                    totalFramesSent++;
                                    clientForSocket++;
                                }
                            }
                        }

                        continue;
                    }

                    std::unordered_map<std::string, std::string> headerMap = parse_header(buffer, buffer + valread);

                    if (headerMap.count("Sec-WebSocket-Key") == 1) {
                        printf(GREEN("Recieved ws request\n"));
                        printf(CYAN("%s\n"), buffer);

                        char sha1_handshake[40];
                        size_t handshake_sz;

                        memset(sha1_handshake, 0, sizeof(sha1_handshake));
                        if (ws_compute_handshake(headerMap["Sec-WebSocket-Key"].c_str(), sha1_handshake, &handshake_sz) != 0) {
                            /* failed to compute handshake. */
                            printf("failed to compute handshake\n");
                            continue;
                        }

                        //printf("%s\n", sha1_handshake);

                        std::string strWSResponse = "HTTP/1.1 101 Switching Protocols\r\nUpgrade: WebSocket\r\nConnection: Upgrade\r\n";
                        strWSResponse += "Sec-WebSocket-Accept: ";
                        strWSResponse += sha1_handshake;
                        strWSResponse += "\r\n";
                        const char *strWSResponseMsg = strWSResponse.c_str();

                        //send websocket response
                        if (send(sd, strWSResponseMsg, strlen(strWSResponseMsg), 0) != strlen(strWSResponseMsg)) {
                            perror("send");
                        }

                        previous_it->second.startedWS = 1;

                    } else {
                        printf(GREEN("Recieved http request\n"));
                        printf(RED("%s\n"), buffer);
                    }

                    /*for (auto x : headerMap)
                    {
                        //cout << x.first << " " << x.second << endl;
                        printf(">%s< -> >%s<\n", x.first.c_str(), x.second.c_str());
                    }*/
                    //send(sd, buffer, strlen(buffer), 0);
                }
            }
        }
    }

    return 0;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x207d0, %rsp          # imm = 0x207D0
movl $0x0, -0x4(%rbp)
movl %edi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movl $0x1, -0x14(%rbp)
movl $0x1e, -0x24(%rbp)
movb $0x0, -0x49(%rbp)
movb $0x0, -0x4a(%rbp)
movl $0x0, -0x50(%rbp)
movl -0x50(%rbp), %eax
cmpl -0x8(%rbp), %eax
jge 0x3857
movq -0x10(%rbp), %rax
movslq -0x50(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movsbl (%rax), %eax
cmpl $0x2d, %eax
jne 0x384a
movq -0x10(%rbp), %rax
movslq -0x50(%rbp), %rcx
movq (%rax,%rcx,8), %rdi
leaq 0xd7f3(%rip), %rsi      # 0x11008
callq 0x3430
cmpl $0x0, %eax
jne 0x3825
movb $0x1, -0x49(%rbp)
jmp 0x3848
movq -0x10(%rbp), %rax
movslq -0x50(%rbp), %rcx
movq (%rax,%rcx,8), %rdi
leaq 0xd7d4(%rip), %rsi      # 0x1100c
callq 0x3430
cmpl $0x0, %eax
jne 0x3846
movb $0x1, -0x4a(%rbp)
jmp 0x3848
jmp 0x384a
jmp 0x384c
movl -0x50(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x50(%rbp)
jmp 0x37e6
movq $0x1, -0x58(%rbp)
movq $0x1, -0x60(%rbp)
movq $0x0, -0x68(%rbp)
movq $0x0, -0x70(%rbp)
leaq -0xa8(%rbp), %rdi
callq 0x5520
leaq -0xe0(%rbp), %rdi
callq 0x5540
leaq -0x118(%rbp), %rdi
callq 0x5560
leaq -0x150(%rbp), %rdi
callq 0x5580
movl $0x2, %edi
movl $0x1, %esi
xorl %edx, %edx
callq 0x30c0
movl %eax, -0x18(%rbp)
cmpl $0x0, %eax
jne 0x38ef
leaq 0xd74a(%rip), %rdi      # 0x11011
callq 0x32c0
jmp 0x38ce
movl $0x1, %edi
callq 0x33b0
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x201d8(%rbp)
movl %eax, -0x201dc(%rbp)
jmp 0x54e1
movl -0x18(%rbp), %edi
movl $0x1, %esi
movl $0x2, %edx
leaq -0x14(%rbp), %rcx
movl $0x4, %r8d
callq 0x3520
cmpl $0x0, %eax
jge 0x3928
leaq 0xd708(%rip), %rdi      # 0x1101f
callq 0x32c0
jmp 0x391e
movl $0x1, %edi
callq 0x33b0
movw $0x2, -0x48(%rbp)
movl $0x0, -0x44(%rbp)
movl $0xfa4, %edi            # imm = 0xFA4
callq 0x3070
movw %ax, -0x46(%rbp)
movl -0x18(%rbp), %edi
leaq -0x48(%rbp), %rsi
movl $0x10, %edx
callq 0x3090
movl %eax, %ecx
xorl %eax, %eax
cmpl %ecx, %eax
jle 0x3974
leaq 0xd6c7(%rip), %rdi      # 0x1102a
callq 0x32c0
jmp 0x396a
movl $0x1, %edi
callq 0x33b0
leaq 0xd6bb(%rip), %rdi      # 0x11036
xorl %eax, %eax
movl $0xfa4, %esi            # imm = 0xFA4
callq 0x3060
jmp 0x3989
movl -0x18(%rbp), %edi
movl $0x3, %esi
callq 0x3380
cmpl $0x0, %eax
jge 0x39b3
leaq 0xd6ae(%rip), %rdi      # 0x11050
callq 0x32c0
jmp 0x39a9
movl $0x1, %edi
callq 0x33b0
movl $0x10, -0x1c(%rbp)
leaq 0xd696(%rip), %rdi      # 0x11057
callq 0x3490
jmp 0x39c8
jmp 0x39ca
jmp 0x39cc
jmp 0x39ce
leaq -0x201d0(%rbp), %rax
movq %rax, -0x201e8(%rbp)
movl $0x0, -0x201e0(%rbp)
movl -0x201e0(%rbp), %eax
cmpq $0x10, %rax
jae 0x3a18
movq -0x201e8(%rbp), %rax
movl -0x201e0(%rbp), %ecx
movq $0x0, (%rax,%rcx,8)
movl -0x201e0(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x201e0(%rbp)
jmp 0x39e6
jmp 0x3a1a
jmp 0x3a1c
movl -0x18(%rbp), %eax
movl $0x40, %ecx
cltd
idivl %ecx
movl %edx, %eax
movl %eax, %ecx
movl $0x1, %eax
shlq %cl, %rax
movq %rax, %rcx
movl -0x18(%rbp), %eax
movl $0x40, %esi
cltd
idivl %esi
cltq
orq -0x201d0(%rbp,%rax,8), %rcx
movq %rcx, -0x201d0(%rbp,%rax,8)
movl -0x18(%rbp), %eax
movl %eax, -0x38(%rbp)
leaq -0x150(%rbp), %rax
movq %rax, -0x201f0(%rbp)
movq -0x201f0(%rbp), %rdi
callq 0x55a0
movq %rax, -0x201f8(%rbp)
movq -0x201f0(%rbp), %rdi
callq 0x55d0
movq %rax, -0x20200(%rbp)
leaq -0x201f8(%rbp), %rdi
leaq -0x20200(%rbp), %rsi
callq 0x5600
testb $0x1, %al
jne 0x3aa9
jmp 0x3b5c
leaq -0x201f8(%rbp), %rdi
callq 0x5630
movq %rax, -0x20208(%rbp)
movq -0x20208(%rbp), %rsi
addq $0x8, %rsi
leaq -0x20238(%rbp), %rdi
callq 0x5660
jmp 0x3ad5
movl -0x20238(%rbp), %eax
movl %eax, -0x34(%rbp)
cmpl $0x0, -0x34(%rbp)
jle 0x3b1b
movl -0x34(%rbp), %eax
movl $0x40, %ecx
cltd
idivl %ecx
movl %edx, %eax
movl %eax, %ecx
movl $0x1, %eax
shlq %cl, %rax
movq %rax, %rcx
movl -0x34(%rbp), %eax
movl $0x40, %esi
cltd
idivl %esi
cltq
orq -0x201d0(%rbp,%rax,8), %rcx
movq %rcx, -0x201d0(%rbp,%rax,8)
movl -0x34(%rbp), %eax
cmpl -0x38(%rbp), %eax
jle 0x3b29
movl -0x34(%rbp), %eax
movl %eax, -0x38(%rbp)
cmpl $-0x1, -0x20210(%rbp)
je 0x3b3f
cmpl $-0x1, -0x20210(%rbp)
je 0x3b3d
jmp 0x3b3d
jmp 0x3b3f
leaq -0x20238(%rbp), %rdi
callq 0x56b0
leaq -0x201f8(%rbp), %rdi
callq 0x56d0
jmp 0x3a8d
movl -0x38(%rbp), %edi
incl %edi
xorl %eax, %eax
movl %eax, %r8d
leaq -0x201d0(%rbp), %rsi
movq %r8, %rdx
movq %r8, %rcx
callq 0x32f0
movl %eax, -0x20614(%rbp)
jmp 0x3b80
movl -0x20614(%rbp), %eax
movl %eax, -0x28(%rbp)
cmpl $0x0, -0x28(%rbp)
jge 0x3bab
callq 0x3050
cmpl $0x4, (%rax)
je 0x3bab
leaq 0xd4d3(%rip), %rdi      # 0x11073
xorl %eax, %eax
callq 0x3060
jmp 0x3ba9
jmp 0x3bab
movl -0x18(%rbp), %eax
movl $0x40, %ecx
cltd
idivl %ecx
cltq
movq -0x201d0(%rbp,%rax,8), %rax
movq %rax, -0x20620(%rbp)
movl -0x18(%rbp), %eax
movl $0x40, %ecx
cltd
idivl %ecx
movq -0x20620(%rbp), %rax
movl %edx, %ecx
movl $0x1, %edx
shlq %cl, %rdx
movq %rdx, %rcx
andq %rcx, %rax
cmpq $0x0, %rax
je 0x3d62
movl -0x18(%rbp), %edi
leaq -0x48(%rbp), %rsi
leaq -0x1c(%rbp), %rdx
callq 0x3120
movl %eax, -0x20624(%rbp)
jmp 0x3c0b
movl -0x20624(%rbp), %ecx
movl %ecx, -0x20(%rbp)
xorl %eax, %eax
cmpl %ecx, %eax
jle 0x3c32
leaq 0xd45f(%rip), %rdi      # 0x11080
callq 0x32c0
jmp 0x3c28
movl $0x1, %edi
callq 0x33b0
movl -0x20(%rbp), %eax
movl %eax, -0x20634(%rbp)
movl -0x44(%rbp), %eax
movl %eax, -0x2023c(%rbp)
movl -0x2023c(%rbp), %edi
callq 0x31a0
movq %rax, -0x20630(%rbp)
movzwl -0x46(%rbp), %edi
callq 0x3540
movl -0x20634(%rbp), %esi
movq -0x20630(%rbp), %rdx
movzwl %ax, %ecx
leaq 0xd411(%rip), %rdi      # 0x11087
xorl %eax, %eax
callq 0x3060
jmp 0x3c7f
movl -0x20(%rbp), %eax
movl %eax, -0x20270(%rbp)
movl $0x0, -0x2026c(%rbp)
leaq -0x20268(%rbp), %rax
movq %rax, -0x20648(%rbp)
leaq -0x20271(%rbp), %rdi
movq %rdi, -0x20640(%rbp)
callq 0x3510
movq -0x20648(%rbp), %rdi
movq -0x20640(%rbp), %rdx
leaq 0xd480(%rip), %rsi      # 0x11148
callq 0x5700
jmp 0x3ccf
movl $0xffffffff, -0x20248(%rbp) # imm = 0xFFFFFFFF
leaq -0x150(%rbp), %rdi
leaq -0x20(%rbp), %rsi
callq 0x57b0
movq %rax, -0x20650(%rbp)
jmp 0x3cf2
movq -0x20650(%rbp), %rdi
leaq -0x20270(%rbp), %rsi
callq 0x57e0
leaq -0x20270(%rbp), %rdi
callq 0x56b0
leaq -0x20271(%rbp), %rdi
callq 0x3340
jmp 0x3d62
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x201d8(%rbp)
movl %eax, -0x201dc(%rbp)
jmp 0x3d51
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x201d8(%rbp)
movl %eax, -0x201dc(%rbp)
leaq -0x20270(%rbp), %rdi
callq 0x56b0
leaq -0x20271(%rbp), %rdi
callq 0x3340
jmp 0x54e1
leaq -0x150(%rbp), %rdi
callq 0x55a0
movq %rax, -0x20280(%rbp)
leaq -0x150(%rbp), %rdi
callq 0x55d0
movq %rax, -0x20288(%rbp)
leaq -0x20280(%rbp), %rdi
leaq -0x20288(%rbp), %rsi
callq 0x5600
testb $0x1, %al
jne 0x3da4
jmp 0x54dc
testb $0x1, -0x4a(%rbp)
je 0x3e12
movq -0x58(%rbp), %rsi
leaq 0xd318(%rip), %rdi      # 0x110cd
xorl %eax, %eax
callq 0x3060
jmp 0x3dbe
movq -0x60(%rbp), %rsi
leaq 0xd325(%rip), %rdi      # 0x110ee
xorl %eax, %eax
callq 0x3060
jmp 0x3dd2
movq -0x68(%rbp), %rsi
leaq 0xd32e(%rip), %rdi      # 0x1110b
xorl %eax, %eax
callq 0x3060
jmp 0x3de6
movq -0x70(%rbp), %rax
movq -0x58(%rbp), %rcx
xorl %edx, %edx
movl %edx, -0x20654(%rbp)
divq %rcx
movq %rax, %rsi
movl -0x20654(%rbp), %eax
leaq 0xd31f(%rip), %rdi      # 0x11128
callq 0x3060
jmp 0x3e10
jmp 0x3e12
leaq -0x20280(%rbp), %rdi
callq 0x5830
movq %rax, %rsi
addq $0x8, %rsi
leaq -0x202b8(%rbp), %rdi
callq 0x5660
jmp 0x3e33
movq -0x20280(%rbp), %rax
movq %rax, -0x202c0(%rbp)
leaq -0x20280(%rbp), %rdi
callq 0x56d0
movl -0x202b8(%rbp), %eax
movl %eax, -0x34(%rbp)
movl -0x34(%rbp), %eax
movl $0x40, %ecx
cltd
idivl %ecx
cltq
movq -0x201d0(%rbp,%rax,8), %rax
movq %rax, -0x20660(%rbp)
movl -0x34(%rbp), %eax
movl $0x40, %ecx
cltd
idivl %ecx
movq -0x20660(%rbp), %rax
movl %edx, %ecx
movl $0x1, %edx
shlq %cl, %rdx
movq %rdx, %rcx
andq %rcx, %rax
cmpq $0x0, %rax
je 0x54a2
leaq -0x10150(%rbp), %rdi
xorl %esi, %esi
movl $0x10000, %edx          # imm = 0x10000
callq 0x3200
movl $0xffff, -0x202c4(%rbp) # imm = 0xFFFF
cmpl $0x1, -0x202b4(%rbp)
jne 0x3ece
movl $0xa, -0x202c4(%rbp)
movl -0x34(%rbp), %edi
movslq -0x202c4(%rbp), %rdx
leaq -0x10150(%rbp), %rsi
callq 0x3440
movq %rax, -0x20668(%rbp)
jmp 0x3eed
movq -0x20668(%rbp), %rax
movl %eax, -0x30(%rbp)
cmpl $0x0, %eax
jne 0x3fc4
movl -0x34(%rbp), %edi
leaq -0x48(%rbp), %rsi
leaq -0x1c(%rbp), %rdx
callq 0x3280
movl -0x44(%rbp), %eax
movl %eax, -0x202c8(%rbp)
movl -0x202c8(%rbp), %edi
callq 0x31a0
movq %rax, -0x20670(%rbp)
movzwl -0x46(%rbp), %edi
callq 0x3540
movq -0x20670(%rbp), %rsi
movzwl %ax, %edx
leaq 0xd204(%rip), %rdi      # 0x11149
xorl %eax, %eax
callq 0x3060
jmp 0x3f4e
movl -0x34(%rbp), %edi
callq 0x3580
jmp 0x3f58
movq -0x202c0(%rbp), %rax
movq %rax, -0x202d8(%rbp)
movq -0x202d8(%rbp), %rsi
leaq -0x150(%rbp), %rdi
callq 0x5860
movq %rax, -0x20678(%rbp)
jmp 0x3f82
movq -0x20678(%rbp), %rax
movq %rax, -0x202d0(%rbp)
movq -0x202d0(%rbp), %rax
movq %rax, -0x20280(%rbp)
movl $0xe, -0x202dc(%rbp)
jmp 0x54ac
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x201d8(%rbp)
movl %eax, -0x201dc(%rbp)
jmp 0x54ce
movslq -0x30(%rbp), %rax
movb $0x0, -0x10150(%rbp,%rax)
cmpl $0x1, -0x202b4(%rbp)
jne 0x50bd
movsbl -0x10150(%rbp), %eax
andl $0x80, %eax
cmpl $0x80, %eax
sete %al
andb $0x1, %al
movzbl %al, %eax
movl %eax, -0x202e0(%rbp)
movsbl -0x10150(%rbp), %eax
andl $0xf, %eax
movl %eax, -0x202e4(%rbp)
cmpl $0x2, -0x202e4(%rbp)
jbe 0x4017
jmp 0x403a
cmpl $0x0, -0x202e0(%rbp)
je 0x4029
cmpl $0x0, -0x202e4(%rbp)
jne 0x4038
movl $0xe, -0x202dc(%rbp)
jmp 0x54ac
jmp 0x403a
movsbl -0x1014f(%rbp), %eax
andl $0x7f, %eax
movl %eax, %eax
movq %rax, -0x202f0(%rbp)
movl $0x2, -0x202f4(%rbp)
cmpq $0x7e, -0x202f0(%rbp)
jne 0x40b8
movl -0x202f4(%rbp), %eax
addl $0x2, %eax
movl %eax, -0x202f4(%rbp)
movsbl -0x1014e(%rbp), %eax
andl $0xff, %eax
movl %eax, %eax
movq %rax, -0x202f0(%rbp)
movq -0x202f0(%rbp), %rax
shlq $0x8, %rax
movq %rax, -0x202f0(%rbp)
movsbl -0x1014d(%rbp), %eax
andl $0xff, %eax
movl %eax, %eax
addq -0x202f0(%rbp), %rax
movq %rax, -0x202f0(%rbp)
jmp 0x414c
cmpq $0x7f, -0x202f0(%rbp)
jne 0x414a
movl -0x202f4(%rbp), %eax
addl $0x8, %eax
movl %eax, -0x202f4(%rbp)
movsbl -0x1014e(%rbp), %eax
andl $0xff, %eax
movl %eax, %eax
movq %rax, -0x202f0(%rbp)
movl $0x0, -0x202f8(%rbp)
cmpl $0x7, -0x202f8(%rbp)
jge 0x4148
movq -0x202f0(%rbp), %rax
shlq $0x8, %rax
movq %rax, -0x202f0(%rbp)
movl -0x202f8(%rbp), %eax
addl $0x3, %eax
cltq
movsbl -0x10150(%rbp,%rax), %eax
andl $0xff, %eax
movl %eax, %eax
addq -0x202f0(%rbp), %rax
movq %rax, -0x202f0(%rbp)
movl -0x202f8(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x202f8(%rbp)
jmp 0x40f4
jmp 0x414a
jmp 0x414c
testb $0x1, -0x49(%rbp)
je 0x420e
leaq 0xd01b(%rip), %rdi      # 0x11178
xorl %eax, %eax
callq 0x3060
jmp 0x4166
movl -0x202e0(%rbp), %esi
leaq 0xd056(%rip), %rdi      # 0x111c9
xorl %eax, %eax
callq 0x3060
jmp 0x417c
movl -0x202e4(%rbp), %esi
leaq 0xd05e(%rip), %rdi      # 0x111e7
xorl %eax, %eax
callq 0x3060
jmp 0x4192
movb -0x1014f(%rbp), %al
shrb $0x7, %al
movzbl %al, %esi
leaq 0xd04e(%rip), %rdi      # 0x111f3
xorl %eax, %eax
callq 0x3060
jmp 0x41ae
movq -0x202f0(%rbp), %rsi
leaq 0xd046(%rip), %rdi      # 0x11202
xorl %eax, %eax
callq 0x3060
jmp 0x41c5
movl -0x202f4(%rbp), %eax
movl %eax, %ecx
movl %ecx, %eax
movzbl -0x10150(%rbp,%rcx), %esi
movl %eax, %ecx
incl %ecx
movzbl -0x10150(%rbp,%rcx), %edx
movl %eax, %ecx
addl $0x2, %ecx
movzbl -0x10150(%rbp,%rcx), %ecx
addl $0x3, %eax
movzbl -0x10150(%rbp,%rax), %r8d
leaq 0xd013(%rip), %rdi      # 0x11216
xorl %eax, %eax
callq 0x3060
jmp 0x420c
jmp 0x420e
movl -0x202f4(%rbp), %eax
addl $0x4, %eax
movl %eax, -0x202f4(%rbp)
movq -0x58(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x58(%rbp)
movl -0x30(%rbp), %eax
movl %eax, -0x202fc(%rbp)
movq -0x202f0(%rbp), %rax
movl -0x202f4(%rbp), %ecx
addq %rcx, %rax
addq $0x1, %rax
cmpq $0xffff, %rax           # imm = 0xFFFF
jbe 0x4321
jmp 0x4254
movslq -0x202fc(%rbp), %rcx
movq -0x202f0(%rbp), %rdx
movl -0x202f4(%rbp), %eax
addq %rax, %rdx
xorl %eax, %eax
cmpq %rdx, %rcx
movb %al, -0x20679(%rbp)
jae 0x42c0
movl -0x34(%rbp), %edi
movq -0x202f0(%rbp), %rdx
movl -0x202f4(%rbp), %eax
addq %rax, %rdx
movslq -0x202fc(%rbp), %rax
subq %rax, %rdx
leaq -0x10150(%rbp), %rsi
callq 0x3440
movq %rax, -0x20688(%rbp)
jmp 0x42aa
movq -0x20688(%rbp), %rax
movl %eax, -0x30(%rbp)
cmpl $0x0, %eax
setne %al
movb %al, -0x20679(%rbp)
movb -0x20679(%rbp), %al
testb $0x1, %al
jne 0x42cc
jmp 0x42e0
movl -0x30(%rbp), %eax
addl -0x202fc(%rbp), %eax
movl %eax, -0x202fc(%rbp)
jmp 0x4254
movslq -0x202fc(%rbp), %rax
movq %rax, -0x68(%rbp)
movslq -0x202fc(%rbp), %rcx
movq -0x70(%rbp), %rax
addq %rcx, %rax
movq %rax, -0x70(%rbp)
leaq 0xcf3a(%rip), %rdi      # 0x1123e
xorl %eax, %eax
movl $0xffff, %esi           # imm = 0xFFFF
callq 0x3060
jmp 0x4312
movl $0xe, -0x202dc(%rbp)
jmp 0x54ac
jmp 0x4323
movslq -0x202fc(%rbp), %rax
movq -0x202f0(%rbp), %rcx
movl -0x202f4(%rbp), %edx
addq %rdx, %rcx
cmpq %rcx, %rax
jae 0x438d
movl -0x34(%rbp), %edi
movslq -0x202fc(%rbp), %rax
leaq -0x10150(%rbp,%rax), %rsi
movq -0x202f0(%rbp), %rdx
movl -0x202f4(%rbp), %ecx
addq %rcx, %rdx
subq %rax, %rdx
callq 0x3440
movq %rax, -0x20690(%rbp)
jmp 0x4372
movq -0x20690(%rbp), %rax
movl %eax, -0x30(%rbp)
movl -0x30(%rbp), %eax
addl -0x202fc(%rbp), %eax
movl %eax, -0x202fc(%rbp)
jmp 0x4323
movslq -0x202fc(%rbp), %rax
movq %rax, -0x68(%rbp)
movslq -0x202fc(%rbp), %rax
addq -0x70(%rbp), %rax
movq %rax, -0x70(%rbp)
movslq -0x202fc(%rbp), %rax
movb $0x0, -0x10150(%rbp,%rax)
testb $0x1, -0x49(%rbp)
je 0x43e4
movl -0x202fc(%rbp), %esi
leaq 0xcec6(%rip), %rdi      # 0x1128f
xorl %eax, %eax
callq 0x3060
jmp 0x43d2
leaq 0xcecd(%rip), %rdi      # 0x112a6
xorl %eax, %eax
callq 0x3060
jmp 0x43e2
jmp 0x43e4
movl $0x0, -0x20300(%rbp)
movslq -0x20300(%rbp), %rax
cmpq -0x202f0(%rbp), %rax
jae 0x446d
movl -0x202f4(%rbp), %eax
addl -0x20300(%rbp), %eax
movl %eax, %eax
movsbl -0x10150(%rbp,%rax), %eax
movl %eax, -0x20694(%rbp)
movl -0x202f4(%rbp), %ecx
subl $0x4, %ecx
movl -0x20300(%rbp), %eax
movl $0x4, %esi
cltd
idivl %esi
movl -0x20694(%rbp), %eax
addl %edx, %ecx
movl %ecx, %ecx
movsbl -0x10150(%rbp,%rcx), %ecx
xorl %ecx, %eax
movb %al, %cl
movl -0x202f4(%rbp), %eax
addl -0x20300(%rbp), %eax
movl %eax, %eax
movb %cl, -0x10150(%rbp,%rax)
movl -0x20300(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x20300(%rbp)
jmp 0x43ee
cmpq $0x7, -0x202f0(%rbp)
jbe 0x4c3f
movl -0x202f4(%rbp), %eax
addl $0x2, %eax
movl %eax, %eax
movsbl -0x10150(%rbp,%rax), %eax
cmpl $0x68, %eax
jne 0x4c3f
movl -0x202f4(%rbp), %eax
addl $0x3, %eax
movl %eax, %eax
movsbl -0x10150(%rbp,%rax), %eax
cmpl $0x72, %eax
jne 0x4c3f
movl -0x202f4(%rbp), %eax
addl $0x4, %eax
movl %eax, %eax
movsbl -0x10150(%rbp,%rax), %eax
cmpl $0x65, %eax
jne 0x4c3f
movl -0x202f4(%rbp), %eax
addl $0x5, %eax
movl %eax, %eax
movsbl -0x10150(%rbp,%rax), %eax
cmpl $0x66, %eax
jne 0x4c3f
movl -0x202f4(%rbp), %eax
leaq -0x10150(%rbp,%rax), %rcx
leaq -0x10147(%rbp,%rax), %rax
movq %rax, -0x206b0(%rbp)
movq -0x202f0(%rbp), %rax
leaq -0x2(%rax,%rcx), %rax
movq %rax, -0x206a8(%rbp)
leaq -0x20321(%rbp), %rdi
movq %rdi, -0x206a0(%rbp)
callq 0x3510
movq -0x206b0(%rbp), %rsi
movq -0x206a8(%rbp), %rdx
movq -0x206a0(%rbp), %rcx
leaq -0x20320(%rbp), %rdi
callq 0x58a0
jmp 0x4551
leaq -0x20321(%rbp), %rdi
callq 0x3340
leaq -0x20320(%rbp), %rdi
callq 0x3160
movq %rax, %rsi
leaq 0xcd84(%rip), %rdi      # 0x112f7
xorl %eax, %eax
callq 0x3060
jmp 0x457c
leaq -0x20320(%rbp), %rdi
leaq 0xcd71(%rip), %rsi      # 0x112fb
callq 0x3100
cmpl $0x0, %eax
jne 0x4905
movl -0x34(%rbp), %esi
leaq -0x20368(%rbp), %rdi
callq 0x5960
jmp 0x45a9
leaq -0x20348(%rbp), %rdi
leaq -0x20320(%rbp), %rsi
leaq -0x20368(%rbp), %rdx
callq 0x5910
jmp 0x45c5
leaq -0x20368(%rbp), %rdi
callq 0x3230
movl -0x34(%rbp), %eax
movl %eax, -0x206bc(%rbp)
leaq -0xa8(%rbp), %rdi
leaq -0x20348(%rbp), %rsi
callq 0x5a80
movq %rax, -0x206b8(%rbp)
jmp 0x45f6
movq -0x206b8(%rbp), %rax
movl -0x206bc(%rbp), %ecx
movl %ecx, (%rax)
xorps %xmm0, %xmm0
movaps %xmm0, -0x20380(%rbp)
movq $0x0, -0x20370(%rbp)
leaq -0x20380(%rbp), %rdi
callq 0x5ab0
leaq -0xe0(%rbp), %rdi
leaq -0x34(%rbp), %rsi
callq 0x5ad0
movq %rax, -0x206c8(%rbp)
jmp 0x463f
movq -0x206c8(%rbp), %rdi
leaq -0x20380(%rbp), %rsi
movq %rsi, -0x206d8(%rbp)
callq 0x5b00
movq -0x206d8(%rbp), %rdi
callq 0x5b30
leaq -0x20150(%rbp), %rax
movq %rax, -0x206d0(%rbp)
leaq 0xcc9a(%rip), %rsi      # 0x11314
leaq -0x20408(%rbp), %rdi
leaq -0x20348(%rbp), %rdx
callq 0x5cb0
jmp 0x468f
leaq 0xcc87(%rip), %rdx      # 0x1131d
leaq -0x203e8(%rbp), %rdi
leaq -0x20408(%rbp), %rsi
callq 0x5b90
jmp 0x46ab
movl -0x34(%rbp), %esi
leaq -0x20428(%rbp), %rdi
callq 0x5960
jmp 0x46bc
leaq -0x203c8(%rbp), %rdi
leaq -0x203e8(%rbp), %rsi
leaq -0x20428(%rbp), %rdx
callq 0x5be0
jmp 0x46d8
leaq 0xcc4c(%rip), %rdx      # 0x1132b
leaq -0x203a8(%rbp), %rdi
leaq -0x203c8(%rbp), %rsi
callq 0x5b90
jmp 0x46f4
movq -0x206d0(%rbp), %rdi
leaq -0x203a8(%rbp), %rsi
callq 0x10ba0
movl %eax, -0x206dc(%rbp)
jmp 0x470f
leaq -0x203a8(%rbp), %rdi
callq 0x3230
leaq -0x203c8(%rbp), %rdi
callq 0x3230
leaq -0x20428(%rbp), %rdi
callq 0x3230
leaq -0x203e8(%rbp), %rdi
callq 0x3230
leaq -0x20408(%rbp), %rdi
callq 0x3230
movl -0x206dc(%rbp), %eax
movl %eax, -0x20384(%rbp)
movl -0x34(%rbp), %edi
movslq -0x20384(%rbp), %rdx
leaq -0x20150(%rbp), %rsi
xorl %ecx, %ecx
callq 0x31d0
movq %rax, -0x206e8(%rbp)
jmp 0x4778
movq -0x206e8(%rbp), %rax
movslq -0x20384(%rbp), %rcx
cmpq %rcx, %rax
je 0x48d9
leaq 0xcb97(%rip), %rdi      # 0x1132d
callq 0x32c0
jmp 0x479d
jmp 0x48d9
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x201d8(%rbp)
movl %eax, -0x201dc(%rbp)
leaq -0x20321(%rbp), %rdi
callq 0x3340
jmp 0x54ce
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x201d8(%rbp)
movl %eax, -0x201dc(%rbp)
jmp 0x4c2e
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x201d8(%rbp)
movl %eax, -0x201dc(%rbp)
leaq -0x20368(%rbp), %rdi
callq 0x3230
jmp 0x4c2e
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x201d8(%rbp)
movl %eax, -0x201dc(%rbp)
jmp 0x48f4
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x201d8(%rbp)
movl %eax, -0x201dc(%rbp)
leaq -0x20380(%rbp), %rdi
callq 0x5b30
jmp 0x48f4
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x201d8(%rbp)
movl %eax, -0x201dc(%rbp)
jmp 0x48cb
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x201d8(%rbp)
movl %eax, -0x201dc(%rbp)
jmp 0x48bf
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x201d8(%rbp)
movl %eax, -0x201dc(%rbp)
jmp 0x48b3
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x201d8(%rbp)
movl %eax, -0x201dc(%rbp)
jmp 0x48a7
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x201d8(%rbp)
movl %eax, -0x201dc(%rbp)
leaq -0x203a8(%rbp), %rdi
callq 0x3230
leaq -0x203c8(%rbp), %rdi
callq 0x3230
leaq -0x20428(%rbp), %rdi
callq 0x3230
leaq -0x203e8(%rbp), %rdi
callq 0x3230
leaq -0x20408(%rbp), %rdi
callq 0x3230
jmp 0x48f4
movl $0xe, -0x202dc(%rbp)
leaq -0x20348(%rbp), %rdi
callq 0x3230
jmp 0x4c1d
leaq -0x20348(%rbp), %rdi
callq 0x3230
jmp 0x4c2e
leaq -0x202c0(%rbp), %rdi
callq 0x5830
movq %rax, %rdi
addq $0x10, %rdi
leaq -0x20320(%rbp), %rsi
callq 0x3040
jmp 0x4926
leaq -0xa8(%rbp), %rdi
leaq -0x20320(%rbp), %rsi
callq 0x5a80
movq %rax, -0x206f0(%rbp)
jmp 0x4942
movq -0x206f0(%rbp), %rax
movl (%rax), %eax
movl %eax, -0x206fc(%rbp)
leaq -0x118(%rbp), %rdi
leaq -0x34(%rbp), %rsi
callq 0x5dc0
movq %rax, -0x206f8(%rbp)
jmp 0x496a
movq -0x206f8(%rbp), %rax
movl -0x206fc(%rbp), %ecx
movl %ecx, (%rax)
leaq -0xa8(%rbp), %rdi
leaq -0x20320(%rbp), %rsi
callq 0x5a80
movq %rax, -0x20708(%rbp)
jmp 0x4995
movq -0x20708(%rbp), %rsi
leaq -0xe0(%rbp), %rdi
callq 0x5ad0
movq %rax, -0x20710(%rbp)
jmp 0x49b1
leaq -0x202c0(%rbp), %rdi
callq 0x5830
movq -0x20710(%rbp), %rdi
movq %rax, %rsi
addq $0x8, %rsi
callq 0x5df0
jmp 0x49d2
leaq -0x20150(%rbp), %rax
movq %rax, -0x20718(%rbp)
movl -0x34(%rbp), %esi
leaq -0x204d0(%rbp), %rdi
callq 0x5960
jmp 0x49f1
leaq 0xc93a(%rip), %rsi      # 0x11332
leaq -0x204b0(%rbp), %rdi
leaq -0x204d0(%rbp), %rdx
callq 0x5e60
jmp 0x4a0d
leaq 0xc90a(%rip), %rdx      # 0x1131e
leaq -0x20490(%rbp), %rdi
leaq -0x204b0(%rbp), %rsi
callq 0x5b90
jmp 0x4a29
leaq -0xa8(%rbp), %rdi
leaq -0x20320(%rbp), %rsi
callq 0x5a80
movq %rax, -0x20720(%rbp)
jmp 0x4a45
movq -0x20720(%rbp), %rax
movl (%rax), %esi
leaq -0x204f0(%rbp), %rdi
callq 0x5960
jmp 0x4a5c
leaq -0x20470(%rbp), %rdi
leaq -0x20490(%rbp), %rsi
leaq -0x204f0(%rbp), %rdx
callq 0x5be0
jmp 0x4a78
leaq 0xc8ac(%rip), %rdx      # 0x1132b
leaq -0x20450(%rbp), %rdi
leaq -0x20470(%rbp), %rsi
callq 0x5b90
jmp 0x4a94
movq -0x20718(%rbp), %rdi
leaq -0x20450(%rbp), %rsi
callq 0x10ba0
movl %eax, -0x20724(%rbp)
jmp 0x4aaf
leaq -0x20450(%rbp), %rdi
callq 0x3230
leaq -0x20470(%rbp), %rdi
callq 0x3230
leaq -0x204f0(%rbp), %rdi
callq 0x3230
leaq -0x20490(%rbp), %rdi
callq 0x3230
leaq -0x204b0(%rbp), %rdi
callq 0x3230
leaq -0x204d0(%rbp), %rdi
callq 0x3230
movl -0x20724(%rbp), %eax
movl %eax, -0x2042c(%rbp)
movl -0x34(%rbp), %edi
movslq -0x2042c(%rbp), %rdx
leaq -0x20150(%rbp), %rsi
xorl %ecx, %ecx
callq 0x31d0
movq %rax, -0x20730(%rbp)
jmp 0x4b24
movq -0x20730(%rbp), %rax
movslq -0x2042c(%rbp), %rcx
cmpq %rcx, %rax
je 0x4c11
leaq 0xc7eb(%rip), %rdi      # 0x1132d
callq 0x32c0
jmp 0x4b49
jmp 0x4c11
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x201d8(%rbp)
movl %eax, -0x201dc(%rbp)
jmp 0x4c03
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x201d8(%rbp)
movl %eax, -0x201dc(%rbp)
jmp 0x4bf7
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x201d8(%rbp)
movl %eax, -0x201dc(%rbp)
jmp 0x4beb
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x201d8(%rbp)
movl %eax, -0x201dc(%rbp)
jmp 0x4bdf
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x201d8(%rbp)
movl %eax, -0x201dc(%rbp)
jmp 0x4bd3
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x201d8(%rbp)
movl %eax, -0x201dc(%rbp)
leaq -0x20450(%rbp), %rdi
callq 0x3230
leaq -0x20470(%rbp), %rdi
callq 0x3230
leaq -0x204f0(%rbp), %rdi
callq 0x3230
leaq -0x20490(%rbp), %rdi
callq 0x3230
leaq -0x204b0(%rbp), %rdi
callq 0x3230
leaq -0x204d0(%rbp), %rdi
callq 0x3230
jmp 0x4c2e
jmp 0x4c13
movl $0xe, -0x202dc(%rbp)
leaq -0x20320(%rbp), %rdi
callq 0x3230
jmp 0x54ac
leaq -0x20320(%rbp), %rdi
callq 0x3230
jmp 0x54ce
cmpl $0x1, -0x202e4(%rbp)
je 0x4c60
cmpl $0x2, -0x202e4(%rbp)
je 0x4c60
movl $0xe, -0x202dc(%rbp)
jmp 0x54ac
movl $0x0, -0x204f4(%rbp)
movslq -0x204f4(%rbp), %rax
cmpq -0x202f0(%rbp), %rax
jae 0x4cb8
movl -0x202f4(%rbp), %eax
addl -0x204f4(%rbp), %eax
movl %eax, %eax
movb -0x10150(%rbp,%rax), %cl
movl -0x202f4(%rbp), %eax
subl $0x4, %eax
addl -0x204f4(%rbp), %eax
movl %eax, %eax
movb %cl, -0x10150(%rbp,%rax)
movl -0x204f4(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x204f4(%rbp)
jmp 0x4c6a
movsbl -0x10150(%rbp), %eax
andl $0x8f, %eax
movb %al, -0x10150(%rbp)
movsbl -0x1014f(%rbp), %eax
andl $0x7f, %eax
movb %al, -0x1014f(%rbp)
movsbl -0x10150(%rbp), %eax
andl $0xf, %eax
movl %eax, -0x202e4(%rbp)
movl -0x202f4(%rbp), %eax
subl $0x4, %eax
movl %eax, %eax
addq -0x202f0(%rbp), %rax
movb $0x0, -0x10150(%rbp,%rax)
movl -0x202f4(%rbp), %eax
subl $0x3, %eax
movl %eax, %eax
addq -0x202f0(%rbp), %rax
movb $0x0, -0x10150(%rbp,%rax)
movl -0x202f4(%rbp), %eax
subl $0x2, %eax
movl %eax, %eax
addq -0x202f0(%rbp), %rax
movb $0x0, -0x10150(%rbp,%rax)
movl -0x202f4(%rbp), %eax
subl $0x1, %eax
movl %eax, %eax
addq -0x202f0(%rbp), %rax
movb $0x0, -0x10150(%rbp,%rax)
movl -0x202f4(%rbp), %eax
subl $0x4, %eax
movl %eax, -0x204f8(%rbp)
movslq -0x204f8(%rbp), %rax
movsbl -0x10150(%rbp,%rax), %eax
cmpl $0x74, %eax
jne 0x4e63
movl -0x204f8(%rbp), %eax
addl $0x1, %eax
cltq
movsbl -0x10150(%rbp,%rax), %eax
cmpl $0x6f, %eax
jne 0x4e63
movl $0x0, -0x204fc(%rbp)
movl -0x204f8(%rbp), %eax
addl $0x2, %eax
movl %eax, -0x204f8(%rbp)
movslq -0x204f8(%rbp), %rax
movsbl -0x10150(%rbp,%rax), %eax
cmpl $0x7b, %eax
je 0x4df2
imull $0xa, -0x204fc(%rbp), %eax
movl -0x204f8(%rbp), %ecx
movl %ecx, %edx
addl $0x1, %edx
movl %edx, -0x204f8(%rbp)
movslq %ecx, %rcx
movsbl -0x10150(%rbp,%rcx), %ecx
addl %ecx, %eax
subl $0x30, %eax
movl %eax, -0x204fc(%rbp)
jmp 0x4dae
movl -0x204fc(%rbp), %edi
movl -0x202f4(%rbp), %eax
addl $-0x4, %eax
movl %eax, %edx
movq -0x202f0(%rbp), %rax
addq %rax, %rdx
leaq -0x10150(%rbp), %rsi
xorl %ecx, %ecx
callq 0x31d0
movq %rax, -0x20738(%rbp)
jmp 0x4e24
movq -0x20738(%rbp), %rax
movl -0x202f4(%rbp), %ecx
subl $0x4, %ecx
movl %ecx, %ecx
addq -0x202f0(%rbp), %rcx
cmpq %rcx, %rax
je 0x4e52
leaq 0xc4e4(%rip), %rdi      # 0x1132d
callq 0x32c0
jmp 0x4e50
jmp 0x4e5e
movq -0x60(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x60(%rbp)
jmp 0x50ae
leaq -0x118(%rbp), %rdi
leaq -0x34(%rbp), %rsi
callq 0x5dc0
movq %rax, -0x20740(%rbp)
jmp 0x4e7c
movq -0x20740(%rbp), %rax
cmpl $0x0, (%rax)
je 0x4f44
leaq -0x118(%rbp), %rdi
leaq -0x34(%rbp), %rsi
callq 0x5dc0
movq %rax, -0x20748(%rbp)
jmp 0x4ea5
movq -0x20748(%rbp), %rax
movl (%rax), %eax
cmpl -0x34(%rbp), %eax
je 0x4f44
leaq -0x118(%rbp), %rdi
leaq -0x34(%rbp), %rsi
callq 0x5dc0
movq %rax, -0x20750(%rbp)
jmp 0x4ed0
movq -0x20750(%rbp), %rax
movl (%rax), %edi
movl -0x202f4(%rbp), %eax
addl $-0x4, %eax
movl %eax, %edx
movq -0x202f0(%rbp), %rax
addq %rax, %rdx
leaq -0x10150(%rbp), %rsi
xorl %ecx, %ecx
callq 0x31d0
movq %rax, -0x20758(%rbp)
jmp 0x4f05
movq -0x20758(%rbp), %rax
movl -0x202f4(%rbp), %ecx
subl $0x4, %ecx
movl %ecx, %ecx
addq -0x202f0(%rbp), %rcx
cmpq %rcx, %rax
je 0x4f33
leaq 0xc403(%rip), %rdi      # 0x1132d
callq 0x32c0
jmp 0x4f31
jmp 0x4f3f
movq -0x60(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x60(%rbp)
jmp 0x50ac
leaq -0xe0(%rbp), %rdi
leaq -0x34(%rbp), %rsi
callq 0x5ad0
movq %rax, -0x20760(%rbp)
jmp 0x4f5d
movq -0x20760(%rbp), %rdi
callq 0x5eb0
movq %rax, -0x20508(%rbp)
leaq -0xe0(%rbp), %rdi
leaq -0x34(%rbp), %rsi
callq 0x5ad0
movq %rax, -0x20768(%rbp)
jmp 0x4f89
movq -0x20768(%rbp), %rdi
callq 0x5f20
movq %rax, -0x20510(%rbp)
leaq -0x20508(%rbp), %rdi
leaq -0x20510(%rbp), %rsi
callq 0x5ee0
testb $0x1, %al
jne 0x4fb8
jmp 0x50aa
leaq -0x20508(%rbp), %rdi
callq 0x5f50
movl (%rax), %edi
movl -0x202f4(%rbp), %eax
addl $-0x4, %eax
movl %eax, %edx
movq -0x202f0(%rbp), %rax
addq %rax, %rdx
leaq -0x10150(%rbp), %rsi
xorl %ecx, %ecx
callq 0x31d0
movq %rax, -0x20770(%rbp)
jmp 0x4ff2
movq -0x20770(%rbp), %rax
movl -0x202f4(%rbp), %ecx
subl $0x4, %ecx
movl %ecx, %ecx
addq -0x202f0(%rbp), %rcx
cmpq %rcx, %rax
je 0x5084
leaq 0xc316(%rip), %rdi      # 0x1132d
callq 0x32c0
jmp 0x501e
leaq -0xe0(%rbp), %rdi
leaq -0x34(%rbp), %rsi
callq 0x5ad0
movq %rax, -0x20778(%rbp)
jmp 0x5037
leaq -0x20520(%rbp), %rdi
leaq -0x20508(%rbp), %rsi
callq 0x5fe0
movq -0x20778(%rbp), %rdi
movq -0x20520(%rbp), %rsi
callq 0x5f70
movq %rax, -0x20780(%rbp)
jmp 0x5066
movq -0x20780(%rbp), %rax
movq %rax, -0x20518(%rbp)
movq -0x20518(%rbp), %rax
movq %rax, -0x20508(%rbp)
jmp 0x50a5
movq -0x60(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x60(%rbp)
leaq -0x20508(%rbp), %rdi
xorl %esi, %esi
callq 0x6020
movq %rax, -0x20528(%rbp)
jmp 0x4f70
jmp 0x50ac
jmp 0x50ae
movl $0xe, -0x202dc(%rbp)
jmp 0x54ac
movslq -0x30(%rbp), %rax
leaq -0x10150(%rbp,%rax), %rdx
leaq -0x20560(%rbp), %rdi
leaq -0x10150(%rbp), %rsi
callq 0xeeb0
jmp 0x50de
leaq -0x20581(%rbp), %rdi
movq %rdi, -0x20788(%rbp)
callq 0x3510
movq -0x20788(%rbp), %rdx
leaq 0xc23f(%rip), %rsi      # 0x1133e
leaq -0x20580(%rbp), %rdi
callq 0x5700
jmp 0x510d
leaq -0x20560(%rbp), %rdi
leaq -0x20580(%rbp), %rsi
callq 0x6060
movq %rax, -0x20790(%rbp)
jmp 0x5129
leaq -0x20580(%rbp), %rdi
callq 0x3230
leaq -0x20581(%rbp), %rdi
callq 0x3340
movq -0x20790(%rbp), %rax
cmpq $0x1, %rax
jne 0x5445
leaq 0xc1f7(%rip), %rdi      # 0x11350
xorl %eax, %eax
callq 0x3060
jmp 0x5162
leaq 0xc205(%rip), %rdi      # 0x1136e
xorl %eax, %eax
leaq -0x10150(%rbp), %rsi
callq 0x3060
jmp 0x5179
xorps %xmm0, %xmm0
movaps %xmm0, -0x205a0(%rbp)
movaps %xmm0, -0x205b0(%rbp)
movq $0x0, -0x20590(%rbp)
leaq -0x205d9(%rbp), %rdi
movq %rdi, -0x20798(%rbp)
callq 0x3510
movq -0x20798(%rbp), %rdx
leaq 0xc188(%rip), %rsi      # 0x1133e
leaq -0x205d8(%rbp), %rdi
callq 0x5700
jmp 0x51c4
leaq -0x20560(%rbp), %rdi
leaq -0x205d8(%rbp), %rsi
callq 0x6090
movq %rax, -0x207a0(%rbp)
jmp 0x51e0
movq -0x207a0(%rbp), %rdi
callq 0x3160
movq %rax, %rdi
leaq -0x205b0(%rbp), %rsi
leaq -0x205b8(%rbp), %rdx
callq 0x109c0
movl %eax, -0x207a4(%rbp)
jmp 0x520a
leaq -0x205d8(%rbp), %rdi
callq 0x3230
leaq -0x205d9(%rbp), %rdi
callq 0x3340
movl -0x207a4(%rbp), %eax
cmpl $0x0, %eax
je 0x52ed
leaq 0xc143(%rip), %rdi      # 0x1137b
xorl %eax, %eax
callq 0x3060
jmp 0x5241
movl $0xe, -0x202dc(%rbp)
jmp 0x5478
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x201d8(%rbp)
movl %eax, -0x201dc(%rbp)
jmp 0x5282
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x201d8(%rbp)
movl %eax, -0x201dc(%rbp)
leaq -0x20580(%rbp), %rdi
callq 0x3230
leaq -0x20581(%rbp), %rdi
callq 0x3340
jmp 0x5492
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x201d8(%rbp)
movl %eax, -0x201dc(%rbp)
jmp 0x5492
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x201d8(%rbp)
movl %eax, -0x201dc(%rbp)
jmp 0x52dc
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x201d8(%rbp)
movl %eax, -0x201dc(%rbp)
leaq -0x205d8(%rbp), %rdi
callq 0x3230
leaq -0x205d9(%rbp), %rdi
callq 0x3340
jmp 0x5492
leaq -0x20601(%rbp), %rdi
movq %rdi, -0x207b0(%rbp)
callq 0x3510
movq -0x207b0(%rbp), %rdx
leaq 0xc08a(%rip), %rsi      # 0x11398
leaq -0x20600(%rbp), %rdi
callq 0x5700
jmp 0x531c
leaq -0x20601(%rbp), %rdi
callq 0x3340
leaq 0xc0b5(%rip), %rsi      # 0x113e4
leaq -0x20600(%rbp), %rdi
callq 0x3300
jmp 0x533d
leaq -0x20600(%rbp), %rdi
leaq -0x205b0(%rbp), %rsi
callq 0x3300
jmp 0x5352
leaq 0xc088(%rip), %rsi      # 0x113e1
leaq -0x20600(%rbp), %rdi
callq 0x3300
jmp 0x5367
leaq -0x20600(%rbp), %rdi
callq 0x3160
movq %rax, -0x20610(%rbp)
movl -0x34(%rbp), %eax
movl %eax, -0x207c4(%rbp)
movq -0x20610(%rbp), %rdi
movq %rdi, -0x207c0(%rbp)
callq 0x3180
movl -0x207c4(%rbp), %edi
movq -0x207c0(%rbp), %rsi
movq %rax, %rdx
xorl %ecx, %ecx
callq 0x31d0
movq %rax, -0x207b8(%rbp)
jmp 0x53b6
movq -0x20610(%rbp), %rdi
callq 0x3180
movq %rax, %rcx
movq -0x207b8(%rbp), %rax
cmpq %rcx, %rax
je 0x5424
leaq 0xbf55(%rip), %rdi      # 0x1132d
callq 0x32c0
jmp 0x53df
jmp 0x5424
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x201d8(%rbp)
movl %eax, -0x201dc(%rbp)
leaq -0x20601(%rbp), %rdi
callq 0x3340
jmp 0x5492
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x201d8(%rbp)
movl %eax, -0x201dc(%rbp)
leaq -0x20600(%rbp), %rdi
callq 0x3230
jmp 0x5492
leaq -0x202c0(%rbp), %rdi
callq 0x5830
movl $0x1, 0xc(%rax)
leaq -0x20600(%rbp), %rdi
callq 0x3230
jmp 0x546e
leaq 0xbfaf(%rip), %rdi      # 0x113fb
xorl %eax, %eax
callq 0x3060
jmp 0x5455
leaq 0xbfbf(%rip), %rdi      # 0x1141b
xorl %eax, %eax
leaq -0x10150(%rbp), %rsi
callq 0x3060
jmp 0x546c
jmp 0x546e
movl $0x0, -0x202dc(%rbp)
leaq -0x20560(%rbp), %rdi
callq 0x60c0
movl -0x202dc(%rbp), %eax
testl %eax, %eax
jne 0x54ac
jmp 0x5490
jmp 0x54a0
leaq -0x20560(%rbp), %rdi
callq 0x60c0
jmp 0x54ce
jmp 0x54a2
movl $0x0, -0x202dc(%rbp)
leaq -0x202b8(%rbp), %rdi
callq 0x56b0
movl -0x202dc(%rbp), %eax
testl %eax, %eax
je 0x54c9
jmp 0x54c4
jmp 0x3d75
jmp 0x3d75
leaq -0x202b8(%rbp), %rdi
callq 0x56b0
jmp 0x54e1
jmp 0x39ca
leaq -0x150(%rbp), %rdi
callq 0x60e0
leaq -0x118(%rbp), %rdi
callq 0x6100
leaq -0xe0(%rbp), %rdi
callq 0x6120
leaq -0xa8(%rbp), %rdi
callq 0x6140
movq -0x201d8(%rbp), %rdi
callq 0x3500
nopl (%rax)