// File: /workspace/github_cpp_makefile_star2_O3/brc7[P]DiversitySampling/targets/samplerace.cpp
// Function: main
int main(int argc, char **argv){

    if (argc < 4){
        std::clog<<"Usage: "<<std::endl; 
        std::clog<<"samplerace <tau> <format> <input> <output>"; 
        std::clog<<" [--range race_range] [--reps race_reps] [--hashes n_minhashes] [-k kmer_size]"<<std::endl; 
        std::clog<<"Positional arguments: "<<std::endl; 
        std::clog<<"tau: floating point RACE sampling threshold. Roughly determines how many samples you will store. You may specify this in scientific notation (i.e. 10e-6)"<<std::endl; 
        std::clog<<"format: Either PE, SE, or I for paired-end, single-end, and interleaved paired reads"<<std::endl; 
        std::clog<<"input: path to input data file (.fastq or .fasta extension). For PE format, specify two files."<<std::endl; 
        std::clog<<"output: path to output sample file (same extension as input). For PE format, specify two files."<<std::endl; 
        
        std::clog<<"Optional arguments: "<<std::endl; 
        std::clog<<"[--range race_range]: (Optional, default 10000) Hash range for each ACE (B)"<<std::endl;
        std::clog<<"[--reps race_reps]: (Optional, default 10) Number of ACE repetitions (R)"<<std::endl;
        std::clog<<"[--hashes n_minhashes]: (Optional, default 1) Number of MinHashes for each ACE (n)"<<std::endl;
        std::clog<<"[--k kmer_size]: (Optional, default 16) Size of each MinHash k-mer (k)"<<std::endl;

        std::clog<<std::endl<<"Example usage:"<<std::endl; 
        std::clog<<"samplerace 15.0 PE data/input-1.fastq data/input-2.fastq data/output-1.fastq data/output-2.fastq --range 100 --reps 50 --hashes 3 --k 5"<<std::endl; 
        std::clog<<"samplerace 10e-6 SE data/input.fastq data/output.fastq --range 100 --reps 5 --hashes 1 --k 33"<<std::endl; 
        std::clog<<"samplerace 0.1 SE data/input.fasta data/output.fasta --range 100000 --k 20"<<std::endl; 
        return -1; 
    }


    // POSITIONAL ARGUMENTS
    double tau = std::stod(argv[1]);
    int format; // ENUM: 1 = unpaired, 2 = interleaved, 3 = paired
    if (std::strcmp("SE",argv[2]) == 0){
        format = 1;
    } else if (std::strcmp("I",argv[2]) == 0){
        format = 2; 
    } else if (std::strcmp("PE",argv[2]) == 0){
        format = 3; 
        if (argc < 7){
            std::cerr<<"For paired-end reads, please specify the input and output files as:"<<std::endl; 
            std::cerr<<"input1.fastq input2.fastq output1.fastq output2.fastq"<<std::endl; 
            return -1; 
        }
    } else {
        std::cerr<<"Invalid format, please specify either SE, PE, or I"<<std::endl; 
        return -1;
    }

    // open the correct file streams given the format
    std::ifstream datastream1;
    std::ofstream samplestream1;
    std::ifstream datastream2;
    std::ofstream samplestream2;

    if (format != 3){
        datastream1.open(argv[3]);
        samplestream1.open(argv[4]);
    } else {
        datastream1.open(argv[3]);
        datastream2.open(argv[4]);
        samplestream1.open(argv[5]);
        samplestream2.open(argv[6]);
    }

    // determine file extension
    std::string filename(argv[3]); 
    std::string file_extension = "";
    size_t idx = filename.rfind('.',filename.length()); 
    if (file_extension == "fq"){
        file_extension = "fastq"; 
    }
    if (idx != std::string::npos){
        file_extension = filename.substr(idx+1, filename.length() - idx); 
    } else {
        std::cerr<<"Input file does not appear to have any file extension."<<std::endl; 
        return -1; 
    }
    if (file_extension != "fasta" && file_extension != "fastq"){
        std::cerr<<"Unknown file extension: "<<file_extension<<std::endl; 
        std::cerr<<"Please specify either a file with the .fasta or .fastq extension."<<std::endl; 
        return -1; 
    }

    // OPTIONAL ARGUMENTS
    int race_range = 10000;
    int race_repetitions = 10;
    int hash_power = 1;
    int kmer_k = 16;

    for (int i = 0; i < argc; ++i){
        if (std::strcmp("--range",argv[i]) == 0){
            if ((i+1) < argc){
                race_range = std::stoi(argv[i+1]);
            } else {
                std::cerr<<"Invalid argument for optional parameter --range"<<std::endl; 
                return -1;
            }
        }
        if (std::strcmp("--reps",argv[i]) == 0){
            if ((i+1) < argc){
                race_repetitions = std::stoi(argv[i+1]);
            } else {
                std::cerr<<"Invalid argument for optional parameter --reps"<<std::endl; 
                return -1;
            }
        }
        if (std::strcmp("--hashes",argv[i]) == 0){
            if ((i+1) < argc){
                hash_power = std::stoi(argv[i+1]);
            } else {
                std::cerr<<"Invalid argument for optional parameter --hashes"<<std::endl; 
                return -1;
            }
        }
        if (std::strcmp("--k",argv[i]) == 0){
            if ((i+1) < argc){
                kmer_k = std::stoi(argv[i+1]);
            } else {
                std::cerr<<"Invalid argument for optional parameter --k"<<std::endl; 
                return -1;
            }
        }
    }

    // Check if arguments are valid
    if (tau <= 0){ std::cerr<<"Invalid value for parameter <tau>"<<std::endl; return -1; }
    if (race_range <= 0){ std::cerr<<"Invalid value for optional parameter --range"<<std::endl; return -1; }
    if (race_repetitions <= 0){ std::cerr<<"Invalid value for optional parameter --reps"<<std::endl; return -1; }
    if (hash_power <= 0){ std::cerr<<"Invalid value for optional parameter --hashes"<<std::endl; return -1; }
    if (kmer_k <= 0){ std::cerr<<"Invalid value for optional parameter --k"<<std::endl; return -1; }

    // done parsing information. Begin RACE algorithm: 

    // buffer for sequences and fasta/fastq chunks
    std::string sequence;
    std::string chunk1;
    std::string chunk2;

    // set up the hash function that will be used to hash input sequences
    SequenceMinHash hash = SequenceMinHash(race_repetitions*hash_power);
    int* raw_hashes = new int[race_repetitions*hash_power]; 
    int* rehashes = new int[race_repetitions];

    RACE sketch = RACE(race_repetitions,race_range); 

    do{
        bool success = false; 
        int c = datastream1.peek(); 
        if (c == EOF) {
            if (datastream1.eof()){
                continue; 
            }
        }

        switch(format){
            case 1: // 1 = unpaired
            success = SequenceFeaturesSE(datastream1, sequence, chunk1, file_extension);
            break; 
            case 2: // 2 = interleaved
            success = SequenceFeaturesI(datastream1, sequence, chunk1, file_extension); 
            break; 
            case 3: // 3 = paired
            success = SequenceFeaturesPE(datastream1, datastream2, sequence, chunk1, chunk2, file_extension);
            break; 
        }
        if (!success) continue;

        hash.getHash(kmer_k, sequence, raw_hashes); 
        // now that we have the sequence and label
        // feed the sequence into the RACE structure
        // first rehash so that the arrays can fit into RACE
        rehash(raw_hashes, rehashes, race_repetitions, hash_power);
        // then simultaneously query and add 
        double KDE = sketch.query_and_add(rehashes); 
        // note: KDE is on a scale from [0,N] not the normalized interval [0,1]
        if (KDE < tau){
            // then keep this sample
            
            switch(format){
                case 1: // 1 = unpaired
                samplestream1 << chunk1; 
                break; 
                case 2: // 2 = interleaved
                samplestream1 << chunk1; 
                break; 
                case 3: // 3 = paired
                samplestream1 << chunk1; 
                samplestream2 << chunk2; 
                break; 
            }
        }
    }
    while(datastream1);
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x978, %rsp            # imm = 0x978
cmpl $0x3, %edi
jg 0x39ad
movq 0x49cf(%rip), %rbx      # 0x7fb8
leaq 0x1bf0(%rip), %rsi      # 0x51e0
movl $0x7, %edx
movq %rbx, %rdi
callq 0x21c0
movq (%rbx), %rax
movq -0x18(%rax), %rdi
addq %rbx, %rdi
movl $0xa, %esi
callq 0x2180
movsbl %al, %esi
movq %rbx, %rdi
callq 0x2040
movq %rax, %rdi
callq 0x2120
leaq 0x1bbd(%rip), %rsi      # 0x51e8
movl $0x2a, %edx
movq %rbx, %rdi
callq 0x21c0
leaq 0x1bd4(%rip), %rsi      # 0x5213
movl $0x4e, %edx
movq %rbx, %rdi
callq 0x21c0
movq (%rbx), %rax
movq -0x18(%rax), %rdi
addq %rbx, %rdi
movl $0xa, %esi
callq 0x2180
movsbl %al, %esi
movq %rbx, %rdi
callq 0x2040
movq %rax, %rdi
callq 0x2120
leaq 0x1be8(%rip), %rsi      # 0x5262
movl $0x16, %edx
movq %rbx, %rdi
callq 0x21c0
movq (%rbx), %rax
movq -0x18(%rax), %rdi
addq %rbx, %rdi
movl $0xa, %esi
callq 0x2180
movsbl %al, %esi
movq %rbx, %rdi
callq 0x2040
movq %rax, %rdi
callq 0x2120
leaq 0x1bc4(%rip), %rsi      # 0x5279
movl $0x99, %edx
movq %rbx, %rdi
callq 0x21c0
movq (%rbx), %rax
movq -0x18(%rax), %rdi
addq %rbx, %rdi
movl $0xa, %esi
callq 0x2180
movsbl %al, %esi
movq %rbx, %rdi
callq 0x2040
movq %rax, %rdi
callq 0x2120
leaq 0x1c23(%rip), %rsi      # 0x5313
movl $0x54, %edx
movq %rbx, %rdi
callq 0x21c0
movq (%rbx), %rax
movq -0x18(%rax), %rdi
addq %rbx, %rdi
movl $0xa, %esi
callq 0x2180
movsbl %al, %esi
movq %rbx, %rdi
callq 0x2040
movq %rax, %rdi
callq 0x2120
leaq 0x1c3d(%rip), %rsi      # 0x5368
movl $0x5e, %edx
movq %rbx, %rdi
callq 0x21c0
movq (%rbx), %rax
movq -0x18(%rax), %rdi
addq %rbx, %rdi
movl $0xa, %esi
callq 0x2180
movsbl %al, %esi
movq %rbx, %rdi
callq 0x2040
movq %rax, %rdi
callq 0x2120
leaq 0x1c61(%rip), %rsi      # 0x53c7
movl $0x5f, %edx
movq %rbx, %rdi
callq 0x21c0
movq (%rbx), %rax
movq -0x18(%rax), %rdi
addq %rbx, %rdi
movl $0xa, %esi
callq 0x2180
movsbl %al, %esi
movq %rbx, %rdi
callq 0x2040
movq %rax, %rdi
callq 0x2120
leaq 0x1c86(%rip), %rsi      # 0x5427
movl $0x14, %edx
movq %rbx, %rdi
callq 0x21c0
movq (%rbx), %rax
movq -0x18(%rax), %rdi
addq %rbx, %rdi
movl $0xa, %esi
callq 0x2180
movsbl %al, %esi
movq %rbx, %rdi
callq 0x2040
movq %rax, %rdi
callq 0x2120
leaq 0x1c60(%rip), %rsi      # 0x543c
movl $0x4b, %edx
movq %rbx, %rdi
callq 0x21c0
movq (%rbx), %rax
movq -0x18(%rax), %rdi
addq %rbx, %rdi
movl $0xa, %esi
callq 0x2180
movsbl %al, %esi
movq %rbx, %rdi
callq 0x2040
movq %rax, %rdi
callq 0x2120
leaq 0x1c71(%rip), %rsi      # 0x5488
movl $0x48, %edx
movq %rbx, %rdi
callq 0x21c0
movq (%rbx), %rax
movq -0x18(%rax), %rdi
addq %rbx, %rdi
movl $0xa, %esi
callq 0x2180
movsbl %al, %esi
movq %rbx, %rdi
callq 0x2040
movq %rax, %rdi
callq 0x2120
leaq 0x1c7f(%rip), %rsi      # 0x54d1
movl $0x52, %edx
movq %rbx, %rdi
callq 0x21c0
movq (%rbx), %rax
movq -0x18(%rax), %rdi
addq %rbx, %rdi
movl $0xa, %esi
callq 0x2180
movsbl %al, %esi
movq %rbx, %rdi
callq 0x2040
movq %rax, %rdi
callq 0x2120
leaq 0x1c97(%rip), %rsi      # 0x5524
movl $0x46, %edx
movq %rbx, %rdi
callq 0x21c0
movq (%rbx), %rax
movq -0x18(%rax), %rdi
addq %rbx, %rdi
movl $0xa, %esi
callq 0x2180
movsbl %al, %esi
movq %rbx, %rdi
callq 0x2040
movq %rax, %rdi
callq 0x2120
movq (%rbx), %rax
movq -0x18(%rax), %rdi
addq %rbx, %rdi
movl $0xa, %esi
callq 0x2180
movsbl %al, %esi
movq %rbx, %rdi
callq 0x2040
movq %rax, %rdi
callq 0x2120
movq %rax, %r14
leaq 0x1c79(%rip), %rsi      # 0x556b
movl $0xe, %edx
movq %rax, %rdi
callq 0x21c0
movq (%r14), %rax
movq -0x18(%rax), %rdi
addq %r14, %rdi
movl $0xa, %esi
callq 0x2180
movsbl %al, %esi
movq %r14, %rdi
callq 0x2040
movq %rax, %rdi
callq 0x2120
leaq 0x1c4d(%rip), %rsi      # 0x557a
movl $0x87, %edx
movq %rbx, %rdi
callq 0x21c0
movq (%rbx), %rax
movq -0x18(%rax), %rdi
addq %rbx, %rdi
movl $0xa, %esi
callq 0x2180
movsbl %al, %esi
movq %rbx, %rdi
callq 0x2040
movq %rax, %rdi
callq 0x2120
leaq 0x1c9a(%rip), %rsi      # 0x5602
movl $0x5d, %edx
movq %rbx, %rdi
callq 0x21c0
movq (%rbx), %rax
movq -0x18(%rax), %rdi
addq %rbx, %rdi
movl $0xa, %esi
callq 0x2180
movsbl %al, %esi
movq %rbx, %rdi
callq 0x2040
movq %rax, %rdi
callq 0x2120
leaq 0x1cbd(%rip), %rsi      # 0x5660
movl $0x4a, %edx
jmp 0x3b5c
movq %rsi, %r15
movl %edi, %ebx
movq 0x8(%rsi), %rsi
leaq 0x168(%rsp), %rdi
leaq 0x370(%rsp), %rdx
callq 0x48e4
movq 0x168(%rsp), %r12
callq 0x2050
movq %rax, %r14
movl (%rax), %ebp
movl $0x0, (%rax)
leaq 0x770(%rsp), %r13
movq %r12, %rdi
movq %r13, %rsi
callq 0x2140
movsd %xmm0, 0xc0(%rsp)
cmpq %r12, (%r13)
je 0x46a6
movl (%r14), %eax
testl %eax, %eax
je 0x3a21
cmpl $0x22, %eax
jne 0x3a24
leaq 0x1f5f(%rip), %rdi      # 0x597b
callq 0x2240
movl %ebp, (%r14)
leaq 0x178(%rsp), %rax
movq -0x10(%rax), %rdi
cmpq %rax, %rdi
je 0x3a45
movq 0x178(%rsp), %rsi
incq %rsi
callq 0x2190
movq 0x10(%r15), %rcx
movzbl (%rcx), %eax
movl %eax, %edx
subl $0x53, %edx
jne 0x3a60
movzbl 0x1(%rcx), %edx
subl $0x45, %edx
jne 0x3a60
movzbl 0x2(%rcx), %edx
negl %edx
movb $0x1, %r13b
testl %edx, %edx
je 0x3a86
cmpl $0x49, %eax
jne 0x3b2d
cmpb $0x0, 0x1(%rcx)
jne 0x3b49
movl $0x2, 0x2c(%rsp)
jmp 0x3a8e
movl $0x1, 0x2c(%rsp)
xorl %ebp, %ebp
leaq 0x168(%rsp), %rdi
callq 0x21b0
leaq 0x370(%rsp), %r12
movq %r12, %rdi
callq 0x2280
leaq 0x770(%rsp), %rdi
callq 0x21b0
leaq 0x570(%rsp), %rdi
callq 0x2280
movl %r13d, 0x98(%rsp)
movq 0x18(%r15), %rsi
testb %bpl, %bpl
je 0x3b95
leaq 0x168(%rsp), %rdi
movl $0x8, %edx
callq 0x2100
movq 0x20(%r15), %rsi
leaq 0x770(%rsp), %rdi
movl $0x8, %edx
callq 0x2100
movq 0x28(%r15), %rsi
leaq 0x370(%rsp), %rdi
movl $0x10, %edx
callq 0x2060
leaq 0x570(%rsp), %r12
movl $0x30, %r13d
jmp 0x3bad
subl $0x50, %eax
jne 0x3b3f
movzbl 0x1(%rcx), %eax
subl $0x45, %eax
jne 0x3b3f
movzbl 0x2(%rcx), %eax
negl %eax
testl %eax, %eax
je 0x4430
movq 0x44a0(%rip), %rbx      # 0x7ff0
leaq 0x1bce(%rip), %rsi      # 0x5725
movl $0x32, %edx
movq %rbx, %rdi
callq 0x21c0
movq (%rbx), %rax
movq -0x18(%rax), %rdi
addq %rbx, %rdi
movl $0xa, %esi
callq 0x2180
movsbl %al, %esi
movq %rbx, %rdi
callq 0x2040
movq %rax, %rdi
callq 0x2120
movl $0xffffffff, %ebx       # imm = 0xFFFFFFFF
jmp 0x467a
movl $0x20, %r13d
leaq 0x168(%rsp), %rdi
movl $0x8, %edx
callq 0x2100
movq (%r15,%r13), %rsi
movq %r12, %rdi
movl $0x10, %edx
callq 0x2060
movq 0x18(%r15), %rsi
leaq 0x128(%rsp), %rdi
leaq 0x30(%rsp), %rdx
callq 0x48e4
leaq 0x40(%rsp), %rax
movq %rax, -0x10(%rax)
leaq 0x14d3(%rip), %rdx      # 0x50b7
leaq 0x30(%rsp), %rdi
movq %rdx, %rsi
callq 0x4922
leaq 0x128(%rsp), %rdi
movq 0x8(%rdi), %rdx
movl $0x2e, %esi
callq 0x22e0
movq %rax, %r12
leaq 0x1b47(%rip), %rsi      # 0x5758
leaq 0x30(%rsp), %rdi
callq 0x2080
testl %eax, %eax
jne 0x3c3c
leaq 0x30(%rsp), %rdi
movq 0x8(%rdi), %rdx
leaq 0x1af0(%rip), %rcx      # 0x571f
movl $0x5, %r8d
xorl %esi, %esi
callq 0x2270
cmpq $-0x1, %r12
je 0x43e0
leaq 0x128(%rsp), %rsi
movq 0x8(%rsi), %rcx
subq %r12, %rcx
incq %r12
leaq 0x8(%rsp), %rdi
movq %r12, %rdx
callq 0x21a0
leaq 0x30(%rsp), %rdi
leaq 0x8(%rsp), %r12
movq %r12, %rsi
callq 0x21e0
movq (%r12), %rdi
leaq 0x18(%rsp), %rax
cmpq %rax, %rdi
je 0x3c92
movq 0x18(%rsp), %rsi
incq %rsi
callq 0x2190
leaq 0x136b(%rip), %rsi      # 0x5004
leaq 0x30(%rsp), %rdi
callq 0x2080
testl %eax, %eax
je 0x3d25
leaq 0x1a71(%rip), %rsi      # 0x571f
leaq 0x30(%rsp), %rdi
callq 0x2080
testl %eax, %eax
je 0x3d25
movq 0x432d(%rip), %rdi      # 0x7ff0
leaq 0x1ac8(%rip), %rsi      # 0x5792
movl $0x18, %edx
callq 0x21c0
movq 0x30(%rsp), %rsi
movq 0x38(%rsp), %rdx
movq 0x430b(%rip), %rdi      # 0x7ff0
callq 0x21c0
movq %rax, %rbx
movq (%rax), %rax
movq -0x18(%rax), %rdi
addq %rbx, %rdi
movl $0xa, %esi
callq 0x2180
movsbl %al, %esi
movq %rbx, %rdi
callq 0x2040
movq %rax, %rdi
callq 0x2120
movl $0x41, %edx
leaq 0x1a8b(%rip), %rsi      # 0x57ab
jmp 0x43ec
movl %ebx, %ebp
movq %rbp, %rax
negq %rax
movq %rax, 0x90(%rsp)
movl $0x2710, %eax           # imm = 0x2710
movq %rax, 0x80(%rsp)
movl $0xa, %eax
movq %rax, 0x70(%rsp)
movl $0x1, %eax
movq %rax, 0x88(%rsp)
movl $0x10, %eax
movq %rax, 0x78(%rsp)
movl $0x1, %r12d
movq -0x8(%r15,%r12,8), %rbx
leaq 0x1b7b(%rip), %rdi      # 0x58f0
movq %rbx, %rsi
callq 0x2220
testl %eax, %eax
jne 0x3e26
cmpq %rbp, %r12
jae 0x44eb
movq (%r15,%r12,8), %rsi
leaq 0x8(%rsp), %rdi
leaq 0xa0(%rsp), %rdx
callq 0x48e4
movq 0x8(%rsp), %rbx
movl (%r14), %r13d
movl $0x0, (%r14)
movq %rbx, %rdi
leaq 0x50(%rsp), %rsi
movl $0xa, %edx
callq 0x2230
cmpq %rbx, 0x50(%rsp)
je 0x468e
leaq -0x80000000(%rax), %rcx
movabsq $-0x100000000, %rdx     # imm = 0xFFFFFFFF00000000
cmpq %rdx, %rcx
jb 0x469a
movl (%r14), %ecx
cmpl $0x22, %ecx
je 0x469a
movq %rax, 0x80(%rsp)
testl %ecx, %ecx
jne 0x3e05
movl %r13d, (%r14)
movq 0x8(%rsp), %rdi
leaq 0x18(%rsp), %rax
cmpq %rax, %rdi
je 0x3e21
movq 0x18(%rsp), %rsi
incq %rsi
callq 0x2190
movq -0x8(%r15,%r12,8), %rbx
leaq 0x1af0(%rip), %rdi      # 0x591d
movq %rbx, %rsi
callq 0x2220
testl %eax, %eax
jne 0x3edb
cmpq %rbp, %r12
jae 0x44f9
movq (%r15,%r12,8), %rsi
leaq 0x8(%rsp), %rdi
leaq 0xa0(%rsp), %rdx
callq 0x48e4
movq 0x8(%rsp), %rbx
movl (%r14), %r13d
movl $0x0, (%r14)
movq %rbx, %rdi
leaq 0x50(%rsp), %rsi
movl $0xa, %edx
callq 0x2230
cmpq %rbx, 0x50(%rsp)
je 0x46be
leaq -0x80000000(%rax), %rcx
movabsq $-0x100000000, %rdx     # imm = 0xFFFFFFFF00000000
cmpq %rdx, %rcx
jb 0x46b2
movl (%r14), %ecx
cmpl $0x22, %ecx
je 0x46b2
movq %rax, 0x70(%rsp)
testl %ecx, %ecx
jne 0x3eba
movl %r13d, (%r14)
movq 0x8(%rsp), %rdi
leaq 0x18(%rsp), %rax
cmpq %rax, %rdi
je 0x3ed6
movq 0x18(%rsp), %rsi
incq %rsi
callq 0x2190
movq -0x8(%r15,%r12,8), %rbx
leaq 0x1a67(%rip), %rdi      # 0x5949
movq %rbx, %rsi
callq 0x2220
testl %eax, %eax
jne 0x3f93
cmpq %rbp, %r12
jae 0x4507
movq (%r15,%r12,8), %rsi
leaq 0x8(%rsp), %rdi
leaq 0xa0(%rsp), %rdx
callq 0x48e4
movq 0x8(%rsp), %rbx
movl (%r14), %r13d
movl $0x0, (%r14)
movq %rbx, %rdi
leaq 0x50(%rsp), %rsi
movl $0xa, %edx
callq 0x2230
cmpq %rbx, 0x50(%rsp)
je 0x46d6
leaq -0x80000000(%rax), %rcx
movabsq $-0x100000000, %rdx     # imm = 0xFFFFFFFF00000000
cmpq %rdx, %rcx
jb 0x46ca
movl (%r14), %ecx
cmpl $0x22, %ecx
je 0x46ca
movq %rax, 0x88(%rsp)
testl %ecx, %ecx
jne 0x3f72
movl %r13d, (%r14)
movq 0x8(%rsp), %rdi
leaq 0x18(%rsp), %rax
cmpq %rax, %rdi
je 0x3f8e
movq 0x18(%rsp), %rsi
incq %rsi
callq 0x2190
movq -0x8(%r15,%r12,8), %rbx
leaq 0x19dd(%rip), %rdi      # 0x5977
movq %rbx, %rsi
callq 0x2220
testl %eax, %eax
jne 0x4043
cmpq %rbp, %r12
jae 0x4515
movq (%r15,%r12,8), %rsi
leaq 0x8(%rsp), %rdi
leaq 0xa0(%rsp), %rdx
callq 0x48e4
movq 0x8(%rsp), %rbx
movl (%r14), %r13d
movl $0x0, (%r14)
movq %rbx, %rdi
leaq 0x50(%rsp), %rsi
movl $0xa, %edx
callq 0x2230
cmpq %rbx, 0x50(%rsp)
je 0x46e2
leaq -0x80000000(%rax), %rcx
movabsq $-0x100000000, %rdx     # imm = 0xFFFFFFFF00000000
cmpq %rdx, %rcx
jb 0x46ee
movl (%r14), %ecx
cmpl $0x22, %ecx
je 0x46ee
movq %rax, 0x78(%rsp)
testl %ecx, %ecx
jne 0x4027
movl %r13d, (%r14)
movq 0x8(%rsp), %rdi
leaq 0x18(%rsp), %rax
cmpq %rax, %rdi
je 0x4043
movq 0x18(%rsp), %rsi
incq %rsi
callq 0x2190
movq 0x90(%rsp), %rax
addq %r12, %rax
incq %rax
incq %r12
cmpq $0x1, %rax
jne 0x3d69
xorpd %xmm0, %xmm0
ucomisd 0xc0(%rsp), %xmm0
jae 0x449b
cmpl $0x0, 0x80(%rsp)
jle 0x4562
movq 0x70(%rsp), %rcx
testl %ecx, %ecx
jle 0x4570
movq 0x88(%rsp), %rdx
testl %edx, %edx
jle 0x457e
cmpl $0x0, 0x78(%rsp)
jle 0x458c
leaq 0x18(%rsp), %rax
movq %rax, 0x8(%rsp)
xorl %eax, %eax
movq %rax, 0x10(%rsp)
movb %al, 0x18(%rsp)
leaq 0x60(%rsp), %rsi
movq %rsi, -0x10(%rsi)
movq %rax, -0x8(%rsi)
movb %al, (%rsi)
leaq 0xb0(%rsp), %rsi
movq %rsi, -0x10(%rsi)
movq %rax, -0x8(%rsi)
movb %al, (%rsi)
movl %edx, %ebx
imull %ecx, %ebx
leaq 0x9c(%rsp), %rdi
movl %ebx, %esi
callq 0x24bc
movl %ebx, %edi
shlq $0x2, %rdi
callq 0x2030
movq %rax, %r14
movl 0x70(%rsp), %ebx
leaq (,%rbx,4), %rdi
callq 0x2030
movq %rax, %r15
movl 0x80(%rsp), %edx
leaq 0x148(%rsp), %rdi
movq %rbx, %rsi
callq 0x2f98
leaq 0xf8(%rsp), %rbx
leaq 0x118(%rsp), %rbp
movl 0x78(%rsp), %eax
movq %rax, 0x90(%rsp)
leaq 0x168(%rsp), %r13
movq %r13, %rdi
callq 0x20b0
cmpl $-0x1, %eax
jne 0x4175
movq 0x168(%rsp), %rax
movq -0x18(%rax), %rax
testb $0x2, 0x188(%rsp,%rax)
jne 0x4355
movl 0x2c(%rsp), %eax
cmpl $0x3, %eax
je 0x41e4
cmpl $0x2, %eax
jne 0x425a
movq %rbx, 0xe8(%rsp)
movq 0x30(%rsp), %rsi
movq 0x38(%rsp), %rdx
addq %rsi, %rdx
leaq 0xe8(%rsp), %rdi
callq 0x2e32
movq %r13, %rdi
leaq 0x8(%rsp), %rsi
leaq 0x50(%rsp), %rdx
leaq 0xe8(%rsp), %rcx
callq 0x2cbe
movl %eax, %r12d
movq 0xe8(%rsp), %rdi
cmpq %rbx, %rdi
je 0x42b6
movq 0xf8(%rsp), %rsi
jmp 0x42ae
leaq 0xd8(%rsp), %rax
movq %rax, 0xc8(%rsp)
movq 0x30(%rsp), %rsi
movq 0x38(%rsp), %rdx
addq %rsi, %rdx
leaq 0xc8(%rsp), %rdi
callq 0x2e32
movq %r13, %rdi
leaq 0x770(%rsp), %rsi
leaq 0x8(%rsp), %rdx
leaq 0x50(%rsp), %rcx
leaq 0xa0(%rsp), %r8
leaq 0xc8(%rsp), %r9
callq 0x2b35
movl %eax, %r12d
movq 0xc8(%rsp), %rdi
leaq 0xd8(%rsp), %rax
cmpq %rax, %rdi
je 0x42b6
movq 0xd8(%rsp), %rsi
jmp 0x42ae
movq %rbp, 0x108(%rsp)
movq 0x30(%rsp), %rsi
movq 0x38(%rsp), %rdx
addq %rsi, %rdx
leaq 0x108(%rsp), %rdi
callq 0x2e32
movq %r13, %rdi
leaq 0x8(%rsp), %rsi
leaq 0x50(%rsp), %rdx
leaq 0x108(%rsp), %rcx
callq 0x2aa7
movl %eax, %r12d
movq 0x108(%rsp), %rdi
cmpq %rbp, %rdi
je 0x42b6
movq 0x118(%rsp), %rsi
incq %rsi
callq 0x2190
testb %r12b, %r12b
je 0x4355
leaq 0x9c(%rsp), %rdi
movq 0x90(%rsp), %rsi
leaq 0x8(%rsp), %rdx
movq %r14, %rcx
callq 0x24c0
movq %r14, %rdi
movq %r15, %rsi
movq 0x70(%rsp), %rdx
movq 0x88(%rsp), %rcx
callq 0x2f40
leaq 0x148(%rsp), %rdi
movq %r15, %rsi
callq 0x302e
movsd 0xc0(%rsp), %xmm1
ucomisd %xmm0, %xmm1
jbe 0x4355
leaq 0x370(%rsp), %rdi
leaq 0x50(%rsp), %rax
cmpb $0x0, 0x98(%rsp)
jne 0x4349
movq 0x50(%rsp), %rsi
movq 0x58(%rsp), %rdx
callq 0x21c0
leaq 0x570(%rsp), %rdi
leaq 0xa0(%rsp), %rax
movq (%rax), %rsi
movq 0x8(%rax), %rdx
callq 0x21c0
movq 0x168(%rsp), %rax
movq -0x18(%rax), %rax
testb $0x5, 0x188(%rsp,%rax)
je 0x414e
leaq 0x148(%rsp), %rdi
callq 0x2fec
movq 0xa0(%rsp), %rdi
leaq 0xb0(%rsp), %rax
cmpq %rax, %rdi
je 0x43a1
movq 0xb0(%rsp), %rsi
incq %rsi
callq 0x2190
movq 0x50(%rsp), %rdi
leaq 0x60(%rsp), %rax
cmpq %rax, %rdi
je 0x43bd
movq 0x60(%rsp), %rsi
incq %rsi
callq 0x2190
movq 0x8(%rsp), %rdi
leaq 0x18(%rsp), %rax
cmpq %rax, %rdi
je 0x43d9
movq 0x18(%rsp), %rsi
incq %rsi
callq 0x2190
xorl %ebx, %ebx
jmp 0x45b5
movl $0x36, %edx
leaq 0x136f(%rip), %rsi      # 0x575b
movq 0x3bfd(%rip), %rbx      # 0x7ff0
movq %rbx, %rdi
callq 0x21c0
movq (%rbx), %rax
addq -0x18(%rax), %rbx
movq %rbx, %rdi
movl $0xa, %esi
callq 0x2180
movsbl %al, %esi
movq 0x3bd7(%rip), %rdi      # 0x7ff0
callq 0x2040
movl $0xffffffff, %ebx       # imm = 0xFFFFFFFF
movq %rax, %rdi
callq 0x2120
jmp 0x45b5
cmpl $0x6, %ebx
ja 0x4488
movq 0x3bb4(%rip), %rbx      # 0x7ff0
leaq 0x1268(%rip), %rsi      # 0x56ab
movl $0x43, %edx
movq %rbx, %rdi
callq 0x21c0
movq (%rbx), %rax
movq -0x18(%rax), %rdi
addq %rbx, %rdi
movl $0xa, %esi
callq 0x2180
movsbl %al, %esi
movq %rbx, %rdi
callq 0x2040
movq %rax, %rdi
callq 0x2120
leaq 0x1271(%rip), %rsi      # 0x56ef
movl $0x35, %edx
jmp 0x3b5c
movl $0x3, 0x2c(%rsp)
movb $0x1, %bpl
xorl %r13d, %r13d
jmp 0x3a90
movq 0x3b4e(%rip), %rbx      # 0x7ff0
leaq 0x1400(%rip), %rsi      # 0x58a9
movl $0x21, %edx
movq %rbx, %rdi
callq 0x21c0
movq (%rbx), %rax
addq -0x18(%rax), %rbx
movq %rbx, %rdi
movl $0xa, %esi
callq 0x2180
movsbl %al, %esi
movq 0x3b1c(%rip), %rdi      # 0x7ff0
callq 0x2040
movl $0xffffffff, %ebx       # imm = 0xFFFFFFFF
movq %rax, %rdi
callq 0x2120
jmp 0x45b5
movl $0x2f, %edx
leaq 0x12f6(%rip), %rsi      # 0x57ed
jmp 0x4521
movl $0x2e, %edx
leaq 0x1318(%rip), %rsi      # 0x581d
jmp 0x4521
movl $0x30, %edx
leaq 0x1339(%rip), %rsi      # 0x584c
jmp 0x4521
movl $0x2b, %edx
leaq 0x135c(%rip), %rsi      # 0x587d
movq 0x3ac8(%rip), %rbx      # 0x7ff0
movq %rbx, %rdi
callq 0x21c0
movq (%rbx), %rax
addq -0x18(%rax), %rbx
movq %rbx, %rdi
movl $0xa, %esi
callq 0x2180
movsbl %al, %esi
movq 0x3aa2(%rip), %rdi      # 0x7ff0
callq 0x2040
movl $0xffffffff, %ebx       # imm = 0xFFFFFFFF
movq %rax, %rdi
callq 0x2120
jmp 0x45b5
movl $0x2c, %edx
leaq 0x135d(%rip), %rsi      # 0x58cb
jmp 0x4598
movl $0x2b, %edx
leaq 0x137c(%rip), %rsi      # 0x58f8
jmp 0x4598
movl $0x2d, %edx
leaq 0x139a(%rip), %rsi      # 0x5924
jmp 0x4598
movl $0x28, %edx
leaq 0x13ba(%rip), %rsi      # 0x5952
movq 0x3a51(%rip), %rdi      # 0x7ff0
callq 0x21c0
movl $0xffffffff, %ebx       # imm = 0xFFFFFFFF
movq 0x3a40(%rip), %rdi      # 0x7ff0
callq 0x20d0
movq 0x30(%rsp), %rdi
leaq 0x40(%rsp), %rax
cmpq %rax, %rdi
je 0x45d1
movq 0x40(%rsp), %rsi
incq %rsi
callq 0x2190
leaq 0x138(%rsp), %rax
movq -0x10(%rax), %rdi
cmpq %rax, %rdi
je 0x45f2
movq 0x138(%rsp), %rsi
incq %rsi
callq 0x2190
movq 0x39d7(%rip), %rax      # 0x7fd0
movq (%rax), %r14
movq 0x18(%rax), %r15
leaq 0x578(%rsp), %rdi
movq %r14, -0x8(%rdi)
movq -0x18(%r14), %rax
movq %r15, 0x570(%rsp,%rax)
callq 0x2160
movl $0xf8, %r12d
leaq 0x570(%rsp), %rdi
addq %r12, %rdi
callq 0x20a0
leaq 0x770(%rsp), %rdi
callq 0x2070
leaq 0x378(%rsp), %rdi
movq %r14, -0x8(%rdi)
movq -0x18(%r14), %rax
movq %r15, 0x370(%rsp,%rax)
callq 0x2160
leaq 0x370(%rsp), %rdi
addq %r12, %rdi
callq 0x20a0
leaq 0x168(%rsp), %rdi
callq 0x2070
movl %ebx, %eax
addq $0x978, %rsp            # imm = 0x978
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
leaq 0x12eb(%rip), %rdi      # 0x5980
callq 0x20f0
leaq 0x12df(%rip), %rdi      # 0x5980
callq 0x2240
leaq 0x12ce(%rip), %rdi      # 0x597b
callq 0x20f0
leaq 0x12c7(%rip), %rdi      # 0x5980
callq 0x2240
leaq 0x12bb(%rip), %rdi      # 0x5980
callq 0x20f0
leaq 0x12af(%rip), %rdi      # 0x5980
callq 0x2240
leaq 0x12a3(%rip), %rdi      # 0x5980
callq 0x20f0
leaq 0x1297(%rip), %rdi      # 0x5980
callq 0x20f0
leaq 0x128b(%rip), %rdi      # 0x5980
callq 0x2240
jmp 0x4700
jmp 0x4700
jmp 0x4700
movq %rax, %r15
jmp 0x4784
movq %rax, %r15
movq 0xc8(%rsp), %rdi
leaq 0xd8(%rsp), %rax
cmpq %rax, %rdi
je 0x4777
movq 0xd8(%rsp), %rsi
jmp 0x4759
movq %rax, %r15
movq 0xe8(%rsp), %rdi
cmpq %rbx, %rdi
je 0x4777
movq 0xf8(%rsp), %rsi
jmp 0x4759
movq %rax, %r15
movq 0x108(%rsp), %rdi
cmpq %rbp, %rdi
je 0x4777
movq 0x118(%rsp), %rsi
incq %rsi
callq 0x2190
jmp 0x4777
jmp 0x4774
jmp 0x4868
jmp 0x4868
jmp 0x4868
movq %rax, %r15
leaq 0x148(%rsp), %rdi
callq 0x2fec
movq 0xa0(%rsp), %rdi
leaq 0xb0(%rsp), %rax
cmpq %rax, %rdi
je 0x47a9
movq 0xb0(%rsp), %rsi
incq %rsi
callq 0x2190
movq 0x50(%rsp), %rdi
leaq 0x60(%rsp), %rax
cmpq %rax, %rdi
je 0x484a
movq 0x60(%rsp), %rsi
incq %rsi
callq 0x2190
jmp 0x484a
movq %rax, %r15
jmp 0x4887
jmp 0x4833
movq %rax, %r15
jmp 0x48b5
movq %rax, %r15
jmp 0x48c2
movq %rax, %r15
jmp 0x48cf
jmp 0x4868
jmp 0x4868
jmp 0x4868
movq %rax, %r15
jmp 0x48dc
jmp 0x4868
movq %rax, %r15
cmpl $0x0, (%r14)
jne 0x4809
movl %ebp, (%r14)
leaq 0x178(%rsp), %rax
movq -0x10(%rax), %rdi
cmpq %rax, %rdi
je 0x48dc
movq 0x178(%rsp), %rsi
incq %rsi
callq 0x2190
jmp 0x48dc
movq %rax, %r15
jmp 0x48a8
jmp 0x483e
jmp 0x483e
jmp 0x483e
movq %rax, %r15
cmpl $0x0, (%r14)
jne 0x484a
movl %r13d, (%r14)
movq 0x8(%rsp), %rdi
leaq 0x18(%rsp), %rax
cmpq %rax, %rdi
je 0x486b
movq 0x18(%rsp), %rsi
incq %rsi
callq 0x2190
jmp 0x486b
movq %rax, %r15
movq 0x30(%rsp), %rdi
leaq 0x40(%rsp), %rax
cmpq %rax, %rdi
je 0x4887
movq 0x40(%rsp), %rsi
incq %rsi
callq 0x2190
leaq 0x138(%rsp), %rax
movq -0x10(%rax), %rdi
cmpq %rax, %rdi
je 0x48a8
movq 0x138(%rsp), %rsi
incq %rsi
callq 0x2190
leaq 0x570(%rsp), %rdi
callq 0x2250
leaq 0x770(%rsp), %rdi
callq 0x2070
leaq 0x370(%rsp), %rdi
callq 0x2250
leaq 0x168(%rsp), %rdi
callq 0x2070
movq %r15, %rdi
callq 0x22a0