// File: medvedevgroup[P]varmatch/src/wholegenome.cpp
// Function: WholeGenome::ReadWholeGenomeVariant(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, bool)
int WholeGenome::ReadWholeGenomeVariant(string filename, bool flag){
    int total_num = 0;
    int long_num = 0;
    double QUAL_LOWER_BOUND = 0.1;

	ifstream vcf_file;
	vcf_file.open(filename.c_str());
	if (!vcf_file.good()) {
		cout << "[VarMatch] Error: can not open vcf file" << endl;
		return -1;
	}

    vector<float> quality_list;

	int genotype_index = -1;
	char genotype_separator = '/';
	//int genome_sequence_length = genome_sequence.length();
	while (!vcf_file.eof()) { // alternative way is vcf_file != NULL
		string line;
		getline(vcf_file, line, '\n');
		// check ineligible lines
		//dout << line << endl;
		if ((int)line.length() <= 1) continue;
		//if (line.find_first_not_of(' ') == std::string::npos) continue;

		if (line[0] == '#') {
			continue;
		}
		auto columns = split(line, '\t');
		if (columns.size() < 10) {
			if(match_mode_indicator != 1){
                cout << "[VarMatch] Warning: not enough information in VCF file for genotype matching." << endl;
                cout << "[VarMatch] \tAutomatically turn off genotype matching module " << filename << endl;
                match_mode_indicator = 1;
                //continue;
            }
            if(columns.size() < 6){
                cout << "[VarMatch] Warning: not enough information in VCF file for variant matching." << endl;
                cout << "[VarMatch] skip current variant: " << line << endl;
                continue;
            }
		}
		string chr_name = columns[0];
		auto pos = atoi(columns[1].c_str()) - 1; // 0-based coordinate

		auto ref = columns[3];
		auto alt_line = columns[4];
		//double quality = stod(columns[5]);

		double quality = 1.0;
		if(columns[5] != ".") quality = stod(columns[5]);

        if(flag){
            quality_list.push_back(quality);
        }

		ToUpper(ref);
		ToUpper(alt_line);

		bool is_heterozygous_variant = false;
		bool is_multi_alternatives = false;
        bool is_zero_one_var = false;
        
        vector<string> genotype_columns;
		
        if (match_mode_indicator != 1) { // match mode indicator is -1 or 0
			if (genotype_index < 0) {
                // change genotype index
                auto formats = split(columns[8], ':');
                for (int i = 0; i < formats.size(); i++) {
                    if (formats[i] == "GT") {
                        genotype_index = i;
                        break;
                    }
                }
                // if GT not found
                if(genotype_index < 0){
                    if(match_mode_indicator != 1 && match_mode_indicator != 1){
                        cout << "[VarMatch] Warning: VCF entry does not contain genotype information." << endl;
                        cout << "[VarMatch] \tAutomatically turn off genotype matching mode. " << endl;
                        match_mode_indicator = 1;
                    }
                }
			}

            
            if(match_mode_indicator != 1){

    			auto additionals = split(columns[9], ':');
                genotype_columns = split(additionals[genotype_index], genotype_separator);

                if(genotype_columns.size() != 2){
                    
                    if(genotype_separator == '/'){
                        genotype_separator = '|';
                    }else{
                        genotype_separator = '/';
                    }
                    genotype_columns = split(additionals[genotype_index], genotype_separator);
                }

    			// normalize format of genotype: sorted, separated by |
    			if (genotype_columns.size() != 2) {
    				cout << "[VarMatch] Warning: Unrecognized Genotype: " << additionals[genotype_index] << endl;
                    cout << "[VarMatch] \tAutomatically turn off genotype matching mode." << endl;
                    match_mode_indicator = 1;
    			}
    			else {
    				if (genotype_columns[0] != genotype_columns[1]) {
    					is_heterozygous_variant = true;
    				}
                    if (genotype_columns[1] == "0" && genotype_columns[0] == "0") {
                        //cout << "Skip Variants when both genotype is refernce allele: " << line << endl;   
                        continue;
                    }
                    if(genotype_columns[0] == "0" || genotype_columns[1] == "0"){
                        is_zero_one_var = true;
                    }
    			}
            }
		}

		vector<string> alt_list;
		if (alt_line.find(",") != std::string::npos) {
			alt_list = split(alt_line, ',');
			is_multi_alternatives = true;
		}
		else {
			alt_list.push_back(alt_line);
		}

        if(alt_list.size() > 2){
            if(match_mode_indicator != 1){
            vector<string> temp_alt_list = alt_list;
            alt_list.clear();
            for(int i = 0; i < 2; i++){
                int alt_indicator = stoi(genotype_columns[i]);
                if(alt_indicator == 0) continue;
                alt_list.push_back(temp_alt_list[alt_indicator-1]);
            }
            }else{
                vector<string> temp_alt_list = alt_list;
                alt_list.clear();
                alt_list.push_back(temp_alt_list[0]);
                alt_list.push_back(temp_alt_list[1]);
            }
        }

        int snp_ins = max(0, (int)alt_list[0].length() - (int)ref.length());
        int snp_del = max(0, (int)ref.length() - (int)alt_list[0].length());
        if(is_multi_alternatives){
            snp_ins = max(snp_ins, (int)alt_list[1].length() - (int)ref.length());
            snp_del = max(snp_del, (int)ref.length() - (int)alt_list[1].length());
        }

        if(snp_ins > VAR_LEN || snp_del > VAR_LEN){
            //dout << "[VarMatch] skip large INDEL with length > " << VAR_LEN << "| "<< line <<endl;
            long_num ++;
            continue;
        }

		DiploidVariant dv(pos, ref, alt_list, is_heterozygous_variant, is_multi_alternatives, snp_del, snp_ins, flag, quality, is_zero_one_var);
		//if (normalization) {
			//NormalizeDiploidVariant(dv);
		//}
        if(chrid_by_chrname.find(chr_name) != chrid_by_chrname.end()){
            int chr_id = chrid_by_chrname[chr_name];
            if(flag == false){
                ref_variant_by_chrid[chr_id]->push_back(dv);
                //baseline_variant_strings.push_back(line);
            }else{
                que_variant_by_chrid[chr_id]->push_back(dv);
                query_variant_strings.push_back(line);
            }
        }else{
            //cout << "[VarMatch] skip current variant as no corresponding reference genome sequence found." << endl;
            cout << "[VarMatch] Warning: variant skipped, no reference genome sequence found for chromosome name: " << chr_name << "." << endl;
            continue;
            int chr_id = chrname_dict[chr_name];
            if(flag == false){
                ref_variant_by_chrid[chr_id]->push_back(dv);
                //baseline_variant_strings.push_back(line);
            }else{
                que_variant_by_chrid[chr_id]->push_back(dv);
                query_variant_strings.push_back(line);
            }
        }

        total_num++;
	}
	vcf_file.close();

    if(flag){
        sort(quality_list.begin(), quality_list.end());
        auto qual_lower_it = lower_bound(quality_list.begin(), quality_list.end(), QUAL_LOWER_BOUND);
        int qual_lower_index = qual_lower_it - quality_list.begin();
        int rest_size = quality_list.size() - qual_lower_index;

        vector<float> temp_percentage_list;
        temp_percentage_list.push_back(0.0);
        threshold_list.push_back(0.0);
        
        for(int i = 1; i < per_list.size(); i++){
            int additional_index = (int)(rest_size * per_list[i]);
            int real_index = qual_lower_index + additional_index;
            if(real_index >= quality_list.size()) real_index = quality_list.size() - 1;
            double quality = quality_list[real_index];
            threshold_list.push_back(quality);

            auto quality_lowit = lower_bound(quality_list.begin(), quality_list.end(), quality);
            int quality_low_index = quality_lowit - quality_list.begin();
            // following program will retain variants >= quality threshold
            
            int quality_size = quality_low_index + 1; // counting number, +/- 1 does not matter
            if(quality_size > quality_list.size()) quality_size = quality_list.size();
            double percentage = (double)quality_size/ quality_list.size();
            temp_percentage_list.push_back(percentage);
        }
        threshold_num = threshold_list.size();
        // revice percentage
        per_list = temp_percentage_list;
    }
    //cout << flag << "," << total_num << "," << long_num << endl;
	return total_num;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x750, %rsp            # imm = 0x750
movq %rsi, -0x598(%rbp)
movb %dl, %al
movq %rdi, -0x10(%rbp)
movq %rsi, -0x18(%rbp)
andb $0x1, %al
movb %al, -0x19(%rbp)
movq -0x10(%rbp), %rax
movq %rax, -0x5a0(%rbp)
movl $0x0, -0x20(%rbp)
movl $0x0, -0x24(%rbp)
movabsq $0x3fb999999999999a, %rax # imm = 0x3FB999999999999A
movq %rax, -0x30(%rbp)
leaq -0x238(%rbp), %rdi
movq %rdi, -0x590(%rbp)
callq 0x64f0
movq -0x598(%rbp), %rdi
callq 0x61a0
movq -0x590(%rbp), %rdi
movq %rax, %rsi
movl $0x8, %edx
callq 0x62d0
jmp 0x1c03d
movq -0x238(%rbp), %rax
movq -0x18(%rax), %rax
leaq -0x238(%rbp,%rax), %rdi
callq 0x6700
movb %al, -0x5a1(%rbp)
jmp 0x1c05d
movb -0x5a1(%rbp), %al
testb $0x1, %al
jne 0x1c0c7
jmp 0x1c069
movq 0x57f48(%rip), %rdi     # 0x73fb8
leaq 0x392b9(%rip), %rsi     # 0x55330
callq 0x6420
movq %rax, -0x5b0(%rbp)
jmp 0x1c085
movq -0x5b0(%rbp), %rdi
movq 0x57eed(%rip), %rsi     # 0x73f80
callq 0x6480
jmp 0x1c09a
movl $0xffffffff, -0x4(%rbp) # imm = 0xFFFFFFFF
movl $0x1, -0x248(%rbp)
jmp 0x1d64c
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x240(%rbp)
movl %eax, -0x244(%rbp)
jmp 0x1d664
leaq -0x260(%rbp), %rdi
callq 0x322b0
movl $0xffffffff, -0x264(%rbp) # imm = 0xFFFFFFFF
movb $0x2f, -0x265(%rbp)
movq -0x238(%rbp), %rax
movq -0x18(%rax), %rax
leaq -0x238(%rbp,%rax), %rdi
callq 0x67a0
movb %al, -0x5b1(%rbp)
jmp 0x1c104
movb -0x5b1(%rbp), %al
xorb $-0x1, %al
testb $0x1, %al
jne 0x1c115
jmp 0x1d1e7
leaq -0x288(%rbp), %rdi
movq %rdi, -0x5c0(%rbp)
callq 0x65e0
movq -0x5c0(%rbp), %rsi
leaq -0x238(%rbp), %rdi
movl $0xa, %edx
callq 0x67c0
jmp 0x1c142
leaq -0x288(%rbp), %rdi
callq 0x6630
cmpl $0x1, %eax
jg 0x1c190
movl $0x2, -0x248(%rbp)
jmp 0x1d16c
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x240(%rbp)
movl %eax, -0x244(%rbp)
jmp 0x1d63e
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x240(%rbp)
movl %eax, -0x244(%rbp)
jmp 0x1d1d6
xorl %eax, %eax
movl %eax, %esi
leaq -0x288(%rbp), %rdi
callq 0x6810
movq %rax, -0x5c8(%rbp)
jmp 0x1c1a9
movq -0x5c8(%rbp), %rax
movsbl (%rax), %eax
cmpl $0x23, %eax
jne 0x1c1c7
movl $0x2, -0x248(%rbp)
jmp 0x1d16c
leaq -0x2a0(%rbp), %rdi
leaq -0x288(%rbp), %rsi
movl $0x9, %edx
callq 0x53e70
jmp 0x1c1e1
leaq -0x2a0(%rbp), %rdi
callq 0xbf00
cmpq $0xa, %rax
jae 0x1c358
movq -0x5a0(%rbp), %rax
cmpl $0x1, 0x1e4(%rax)
je 0x1c2b3
movq 0x57da6(%rip), %rdi     # 0x73fb8
leaq 0x3913f(%rip), %rsi     # 0x55358
callq 0x6420
movq %rax, -0x5d0(%rbp)
jmp 0x1c227
movq -0x5d0(%rbp), %rdi
movq 0x57d4b(%rip), %rsi     # 0x73f80
callq 0x6480
jmp 0x1c23c
movq 0x57d75(%rip), %rdi     # 0x73fb8
leaq 0x3915c(%rip), %rsi     # 0x553a6
callq 0x6420
movq %rax, -0x5d8(%rbp)
jmp 0x1c258
movq -0x598(%rbp), %rsi
movq -0x5d8(%rbp), %rdi
callq 0x63e0
movq %rax, -0x5e0(%rbp)
jmp 0x1c274
movq -0x5e0(%rbp), %rdi
movq 0x57cfe(%rip), %rsi     # 0x73f80
callq 0x6480
jmp 0x1c289
movq -0x5a0(%rbp), %rax
movl $0x1, 0x1e4(%rax)
jmp 0x1c2b3
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x240(%rbp)
movl %eax, -0x244(%rbp)
jmp 0x1d1ca
leaq -0x2a0(%rbp), %rdi
callq 0xbf00
cmpq $0x6, %rax
jae 0x1c356
movq 0x57ce8(%rip), %rdi     # 0x73fb8
leaq 0x3910c(%rip), %rsi     # 0x553e3
callq 0x6420
movq %rax, -0x5e8(%rbp)
jmp 0x1c2e5
movq -0x5e8(%rbp), %rdi
movq 0x57c8d(%rip), %rsi     # 0x73f80
callq 0x6480
jmp 0x1c2fa
movq 0x57cb7(%rip), %rdi     # 0x73fb8
leaq 0x39128(%rip), %rsi     # 0x55430
callq 0x6420
movq %rax, -0x5f0(%rbp)
jmp 0x1c316
movq -0x5f0(%rbp), %rdi
leaq -0x288(%rbp), %rsi
callq 0x63e0
movq %rax, -0x5f8(%rbp)
jmp 0x1c332
movq -0x5f8(%rbp), %rdi
movq 0x57c40(%rip), %rsi     # 0x73f80
callq 0x6480
jmp 0x1c347
movl $0x2, -0x248(%rbp)
jmp 0x1d160
jmp 0x1c358
xorl %eax, %eax
movl %eax, %esi
leaq -0x2a0(%rbp), %rdi
callq 0x9080
movq %rax, %rsi
leaq -0x2c0(%rbp), %rdi
callq 0x61b0
jmp 0x1c379
leaq -0x2a0(%rbp), %rdi
movq %rdi, -0x600(%rbp)
movl $0x1, %esi
callq 0x9080
movq %rax, %rdi
callq 0x61a0
movq %rax, %rdi
callq 0x6660
movq -0x600(%rbp), %rdi
decl %eax
movl %eax, -0x2c4(%rbp)
movl $0x3, %esi
callq 0x9080
movq %rax, %rsi
leaq -0x2e8(%rbp), %rdi
callq 0x61b0
jmp 0x1c3cb
leaq -0x2a0(%rbp), %rdi
movl $0x4, %esi
callq 0x9080
movq %rax, %rsi
leaq -0x308(%rbp), %rdi
callq 0x61b0
jmp 0x1c3ed
movabsq $0x3ff0000000000000, %rax # imm = 0x3FF0000000000000
movq %rax, -0x310(%rbp)
leaq -0x2a0(%rbp), %rdi
movl $0x5, %esi
callq 0x9080
movq %rax, %rdi
leaq 0x39619(%rip), %rsi     # 0x55a32
callq 0x17c70
movb %al, -0x601(%rbp)
jmp 0x1c426
movb -0x601(%rbp), %al
testb $0x1, %al
jne 0x1c432
jmp 0x1c4b0
leaq -0x2a0(%rbp), %rdi
movl $0x5, %esi
callq 0x9080
movq %rax, %rdi
xorl %eax, %eax
movl %eax, %esi
callq 0x32850
movsd %xmm0, -0x610(%rbp)
jmp 0x1c459
movsd -0x610(%rbp), %xmm0
movsd %xmm0, -0x310(%rbp)
jmp 0x1c4b0
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x240(%rbp)
movl %eax, -0x244(%rbp)
jmp 0x1d1be
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x240(%rbp)
movl %eax, -0x244(%rbp)
jmp 0x1d1b2
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x240(%rbp)
movl %eax, -0x244(%rbp)
jmp 0x1d1a6
testb $0x1, -0x19(%rbp)
je 0x1c4e1
movsd -0x310(%rbp), %xmm0
cvtsd2ss %xmm0, %xmm0
movss %xmm0, -0x314(%rbp)
leaq -0x260(%rbp), %rdi
leaq -0x314(%rbp), %rsi
callq 0x32890
jmp 0x1c4df
jmp 0x1c4e1
movq -0x5a0(%rbp), %rdi
leaq -0x2e8(%rbp), %rsi
callq 0x328c0
jmp 0x1c4f6
movq -0x5a0(%rbp), %rdi
leaq -0x308(%rbp), %rsi
callq 0x328c0
jmp 0x1c50b
movb $0x0, -0x315(%rbp)
movb $0x0, -0x316(%rbp)
movb $0x0, -0x317(%rbp)
leaq -0x330(%rbp), %rdi
callq 0x12d30
movq -0x5a0(%rbp), %rax
cmpl $0x1, 0x1e4(%rax)
je 0x1ca1f
cmpl $0x0, -0x264(%rbp)
jge 0x1c6f1
leaq -0x2a0(%rbp), %rdi
movl $0x8, %esi
callq 0x9080
movq %rax, %rsi
leaq -0x348(%rbp), %rdi
movl $0x3a, %edx
callq 0x53e70
jmp 0x1c574
movl $0x0, -0x34c(%rbp)
movslq -0x34c(%rbp), %rax
movq %rax, -0x618(%rbp)
leaq -0x348(%rbp), %rdi
callq 0xbf00
movq %rax, %rcx
movq -0x618(%rbp), %rax
cmpq %rcx, %rax
jae 0x1c63f
movslq -0x34c(%rbp), %rsi
leaq -0x348(%rbp), %rdi
callq 0x9080
movq %rax, %rdi
leaq 0x38e8a(%rip), %rsi     # 0x55452
callq 0x125e0
movb %al, -0x619(%rbp)
jmp 0x1c5d5
movb -0x619(%rbp), %al
testb $0x1, %al
jne 0x1c5e1
jmp 0x1c629
movl -0x34c(%rbp), %eax
movl %eax, -0x264(%rbp)
jmp 0x1c63f
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x240(%rbp)
movl %eax, -0x244(%rbp)
jmp 0x1d19a
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x240(%rbp)
movl %eax, -0x244(%rbp)
leaq -0x348(%rbp), %rdi
callq 0x13370
jmp 0x1d19a
jmp 0x1c62b
movl -0x34c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x34c(%rbp)
jmp 0x1c57e
cmpl $0x0, -0x264(%rbp)
jge 0x1c6e5
movq -0x5a0(%rbp), %rax
cmpl $0x1, 0x1e4(%rax)
je 0x1c6e3
movq -0x5a0(%rbp), %rax
cmpl $0x1, 0x1e4(%rax)
je 0x1c6e3
movq 0x57941(%rip), %rdi     # 0x73fb8
leaq 0x38dd7(%rip), %rsi     # 0x55455
callq 0x6420
movq %rax, -0x628(%rbp)
jmp 0x1c68c
movq -0x628(%rbp), %rdi
movq 0x578e6(%rip), %rsi     # 0x73f80
callq 0x6480
jmp 0x1c6a1
movq 0x57910(%rip), %rdi     # 0x73fb8
leaq 0x38deb(%rip), %rsi     # 0x5549a
callq 0x6420
movq %rax, -0x630(%rbp)
jmp 0x1c6bd
movq -0x630(%rbp), %rdi
movq 0x578b5(%rip), %rsi     # 0x73f80
callq 0x6480
jmp 0x1c6d2
movq -0x5a0(%rbp), %rax
movl $0x1, 0x1e4(%rax)
jmp 0x1c6e5
leaq -0x348(%rbp), %rdi
callq 0x13370
movq -0x5a0(%rbp), %rax
cmpl $0x1, 0x1e4(%rax)
je 0x1ca1d
leaq -0x2a0(%rbp), %rdi
movl $0x9, %esi
callq 0x9080
movq %rax, %rsi
leaq -0x368(%rbp), %rdi
movl $0x3a, %edx
callq 0x53e70
jmp 0x1c72c
movslq -0x264(%rbp), %rsi
leaq -0x368(%rbp), %rdi
callq 0x9080
movq %rax, %rsi
movsbl -0x265(%rbp), %edx
leaq -0x380(%rbp), %rdi
callq 0x53e70
jmp 0x1c757
leaq -0x330(%rbp), %rdi
leaq -0x380(%rbp), %rsi
callq 0x32920
leaq -0x380(%rbp), %rdi
callq 0x13370
leaq -0x330(%rbp), %rdi
callq 0xbf00
cmpq $0x2, %rax
je 0x1c815
movsbl -0x265(%rbp), %eax
cmpl $0x2f, %eax
jne 0x1c7c4
movb $0x7c, -0x265(%rbp)
jmp 0x1c7cb
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x240(%rbp)
movl %eax, -0x244(%rbp)
leaq -0x368(%rbp), %rdi
callq 0x13370
jmp 0x1d19a
movb $0x2f, -0x265(%rbp)
movslq -0x264(%rbp), %rsi
leaq -0x368(%rbp), %rdi
callq 0x9080
movq %rax, %rsi
movsbl -0x265(%rbp), %edx
leaq -0x398(%rbp), %rdi
callq 0x53e70
jmp 0x1c7f6
leaq -0x330(%rbp), %rdi
leaq -0x398(%rbp), %rsi
callq 0x32920
leaq -0x398(%rbp), %rdi
callq 0x13370
leaq -0x330(%rbp), %rdi
callq 0xbf00
cmpq $0x2, %rax
je 0x1c8ce
movq 0x57786(%rip), %rdi     # 0x73fb8
leaq 0x38c9d(%rip), %rsi     # 0x554d6
callq 0x6420
movq %rax, -0x638(%rbp)
jmp 0x1c847
movslq -0x264(%rbp), %rsi
leaq -0x368(%rbp), %rdi
callq 0x9080
movq -0x638(%rbp), %rdi
movq %rax, %rsi
callq 0x63e0
movq %rax, -0x640(%rbp)
jmp 0x1c872
movq -0x640(%rbp), %rdi
movq 0x57700(%rip), %rsi     # 0x73f80
callq 0x6480
jmp 0x1c887
movq 0x5772a(%rip), %rdi     # 0x73fb8
leaq 0x38c6d(%rip), %rsi     # 0x55502
callq 0x6420
movq %rax, -0x648(%rbp)
jmp 0x1c8a3
movq -0x648(%rbp), %rdi
movq 0x576cf(%rip), %rsi     # 0x73f80
callq 0x6480
jmp 0x1c8b8
movq -0x5a0(%rbp), %rax
movl $0x1, 0x1e4(%rax)
jmp 0x1c9f5
leaq -0x330(%rbp), %rdi
xorl %eax, %eax
movl %eax, %esi
callq 0x9080
movq %rax, -0x650(%rbp)
leaq -0x330(%rbp), %rdi
movl $0x1, %esi
callq 0x9080
movq -0x650(%rbp), %rdi
movq %rax, %rsi
callq 0x125b0
testb $0x1, %al
jne 0x1c90b
jmp 0x1c912
movb $0x1, -0x315(%rbp)
leaq -0x330(%rbp), %rdi
movl $0x1, %esi
callq 0x9080
movq %rax, %rdi
leaq 0x38f00(%rip), %rsi     # 0x5582d
callq 0x125e0
movb %al, -0x651(%rbp)
jmp 0x1c93a
movb -0x651(%rbp), %al
testb $0x1, %al
jne 0x1c946
jmp 0x1c985
xorl %eax, %eax
movl %eax, %esi
leaq -0x330(%rbp), %rdi
callq 0x9080
movq %rax, %rdi
leaq 0x38ecd(%rip), %rsi     # 0x5582d
callq 0x125e0
movb %al, -0x652(%rbp)
jmp 0x1c96d
movb -0x652(%rbp), %al
testb $0x1, %al
jne 0x1c979
jmp 0x1c985
movl $0x2, -0x248(%rbp)
jmp 0x1c9ff
xorl %eax, %eax
movl %eax, %esi
leaq -0x330(%rbp), %rdi
callq 0x9080
movq %rax, %rdi
leaq 0x38e8e(%rip), %rsi     # 0x5582d
callq 0x125e0
movb %al, -0x653(%rbp)
jmp 0x1c9ac
movb -0x653(%rbp), %al
testb $0x1, %al
jne 0x1c9ec
jmp 0x1c9b8
leaq -0x330(%rbp), %rdi
movl $0x1, %esi
callq 0x9080
movq %rax, %rdi
leaq 0x38e5a(%rip), %rsi     # 0x5582d
callq 0x125e0
movb %al, -0x654(%rbp)
jmp 0x1c9e0
movb -0x654(%rbp), %al
testb $0x1, %al
jne 0x1c9ec
jmp 0x1c9f3
movb $0x1, -0x317(%rbp)
jmp 0x1c9f5
movl $0x0, -0x248(%rbp)
leaq -0x368(%rbp), %rdi
callq 0x13370
movl -0x248(%rbp), %eax
testl %eax, %eax
jne 0x1d130
jmp 0x1ca1b
jmp 0x1ca1d
jmp 0x1ca1f
leaq -0x3b0(%rbp), %rdi
callq 0x12d30
leaq -0x308(%rbp), %rdi
leaq 0x38b04(%rip), %rsi     # 0x5553d
xorl %eax, %eax
movl %eax, %edx
callq 0x6800
cmpq $-0x1, %rax
je 0x1caa1
leaq -0x3c8(%rbp), %rdi
leaq -0x308(%rbp), %rsi
movl $0x2c, %edx
callq 0x53e70
jmp 0x1ca62
leaq -0x3b0(%rbp), %rdi
leaq -0x3c8(%rbp), %rsi
callq 0x32920
leaq -0x3c8(%rbp), %rdi
callq 0x13370
movb $0x1, -0x316(%rbp)
jmp 0x1cab8
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x240(%rbp)
movl %eax, -0x244(%rbp)
jmp 0x1d18e
leaq -0x3b0(%rbp), %rdi
leaq -0x308(%rbp), %rsi
callq 0x17750
jmp 0x1cab6
jmp 0x1cab8
leaq -0x3b0(%rbp), %rdi
callq 0xbf00
cmpq $0x2, %rax
jbe 0x1cc6d
movq -0x5a0(%rbp), %rax
cmpl $0x1, 0x1e4(%rax)
je 0x1cbcf
leaq -0x3e0(%rbp), %rdi
leaq -0x3b0(%rbp), %rsi
callq 0x32950
jmp 0x1caf7
leaq -0x3b0(%rbp), %rdi
callq 0x17a60
movl $0x0, -0x3e4(%rbp)
cmpl $0x2, -0x3e4(%rbp)
jge 0x1cbbe
movslq -0x3e4(%rbp), %rsi
leaq -0x330(%rbp), %rdi
callq 0x9080
movq %rax, %rdi
xorl %eax, %eax
movl %eax, %esi
movl $0xa, %edx
callq 0x32a40
movl %eax, -0x658(%rbp)
jmp 0x1cb46
movl -0x658(%rbp), %eax
movl %eax, -0x3e8(%rbp)
cmpl $0x0, -0x3e8(%rbp)
jne 0x1cb80
jmp 0x1cbaa
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x240(%rbp)
movl %eax, -0x244(%rbp)
leaq -0x3e0(%rbp), %rdi
callq 0x13370
jmp 0x1d18e
movl -0x3e8(%rbp), %eax
decl %eax
movslq %eax, %rsi
leaq -0x3e0(%rbp), %rdi
callq 0x9080
movq %rax, %rsi
leaq -0x3b0(%rbp), %rdi
callq 0x17750
jmp 0x1cba8
jmp 0x1cbaa
movl -0x3e4(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x3e4(%rbp)
jmp 0x1cb0d
leaq -0x3e0(%rbp), %rdi
callq 0x13370
jmp 0x1cc6b
leaq -0x400(%rbp), %rdi
leaq -0x3b0(%rbp), %rsi
callq 0x32950
jmp 0x1cbe4
leaq -0x3b0(%rbp), %rdi
movq %rdi, -0x660(%rbp)
callq 0x17a60
xorl %eax, %eax
movl %eax, %esi
leaq -0x400(%rbp), %rdi
callq 0x9080
movq -0x660(%rbp), %rdi
movq %rax, %rsi
callq 0x17750
jmp 0x1cc18
leaq -0x400(%rbp), %rdi
movl $0x1, %esi
callq 0x9080
movq %rax, %rsi
leaq -0x3b0(%rbp), %rdi
callq 0x17750
jmp 0x1cc3a
leaq -0x400(%rbp), %rdi
callq 0x13370
jmp 0x1cc6b
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x240(%rbp)
movl %eax, -0x244(%rbp)
leaq -0x400(%rbp), %rdi
callq 0x13370
jmp 0x1d18e
jmp 0x1cc6d
movl $0x0, -0x408(%rbp)
xorl %eax, %eax
movl %eax, %esi
leaq -0x3b0(%rbp), %rdi
callq 0x9080
movq %rax, %rdi
callq 0x6630
movl %eax, -0x66c(%rbp)
leaq -0x2e8(%rbp), %rdi
callq 0x6630
movq %rax, %rcx
movl -0x66c(%rbp), %eax
subl %ecx, %eax
movl %eax, -0x40c(%rbp)
leaq -0x408(%rbp), %rdi
leaq -0x40c(%rbp), %rsi
callq 0x32a80
movq %rax, -0x668(%rbp)
jmp 0x1ccce
movq -0x668(%rbp), %rax
movl (%rax), %eax
movl %eax, -0x404(%rbp)
movl $0x0, -0x414(%rbp)
leaq -0x2e8(%rbp), %rdi
callq 0x6630
movl %eax, -0x67c(%rbp)
xorl %eax, %eax
movl %eax, %esi
leaq -0x3b0(%rbp), %rdi
callq 0x9080
movq %rax, %rdi
callq 0x6630
movq %rax, %rcx
movl -0x67c(%rbp), %eax
subl %ecx, %eax
movl %eax, -0x418(%rbp)
leaq -0x414(%rbp), %rdi
leaq -0x418(%rbp), %rsi
callq 0x32a80
movq %rax, -0x678(%rbp)
jmp 0x1cd3e
movq -0x678(%rbp), %rax
movl (%rax), %eax
movl %eax, -0x410(%rbp)
testb $0x1, -0x316(%rbp)
je 0x1ce28
leaq -0x3b0(%rbp), %rdi
movl $0x1, %esi
callq 0x9080
movq %rax, %rdi
callq 0x6630
movl %eax, -0x68c(%rbp)
leaq -0x2e8(%rbp), %rdi
callq 0x6630
movq %rax, %rcx
movl -0x68c(%rbp), %eax
subl %ecx, %eax
movl %eax, -0x41c(%rbp)
leaq -0x404(%rbp), %rdi
leaq -0x41c(%rbp), %rsi
callq 0x32a80
movq %rax, -0x688(%rbp)
jmp 0x1cdb2
movq -0x688(%rbp), %rax
movl (%rax), %eax
movl %eax, -0x404(%rbp)
leaq -0x2e8(%rbp), %rdi
callq 0x6630
movl %eax, -0x69c(%rbp)
leaq -0x3b0(%rbp), %rdi
movl $0x1, %esi
callq 0x9080
movq %rax, %rdi
callq 0x6630
movq %rax, %rcx
movl -0x69c(%rbp), %eax
subl %ecx, %eax
movl %eax, -0x420(%rbp)
leaq -0x410(%rbp), %rdi
leaq -0x420(%rbp), %rsi
callq 0x32a80
movq %rax, -0x698(%rbp)
jmp 0x1ce19
movq -0x698(%rbp), %rax
movl (%rax), %eax
movl %eax, -0x410(%rbp)
cmpl $0x64, -0x404(%rbp)
jg 0x1ce3a
cmpl $0x64, -0x410(%rbp)
jle 0x1ce52
movl -0x24(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x24(%rbp)
movl $0x2, -0x248(%rbp)
jmp 0x1d124
movl -0x2c4(%rbp), %eax
movl %eax, -0x6a0(%rbp)
leaq -0x498(%rbp), %rdi
leaq -0x2e8(%rbp), %rsi
callq 0x61b0
jmp 0x1ce73
leaq -0x4b0(%rbp), %rdi
leaq -0x3b0(%rbp), %rsi
callq 0x32950
jmp 0x1ce88
movl -0x6a0(%rbp), %esi
movl -0x410(%rbp), %ecx
movl -0x404(%rbp), %edx
movsd -0x310(%rbp), %xmm0
movzbl -0x316(%rbp), %r9d
movzbl -0x315(%rbp), %r8d
movzbl -0x19(%rbp), %edi
movzbl -0x317(%rbp), %r10d
andl $0x1, %r10d
movq %rsp, %rax
movl %r10d, 0x18(%rax)
andl $0x1, %edi
movl %edi, 0x10(%rax)
movl %edx, 0x8(%rax)
movl %ecx, (%rax)
andl $0x1, %r8d
andl $0x1, %r9d
leaq -0x478(%rbp), %rdi
leaq -0x498(%rbp), %rdx
leaq -0x4b0(%rbp), %rcx
callq 0x32ac0
jmp 0x1cef8
leaq -0x4b0(%rbp), %rdi
callq 0x13370
leaq -0x498(%rbp), %rdi
callq 0x6828
movq -0x5a0(%rbp), %rdi
addq $0x88, %rdi
leaq -0x2c0(%rbp), %rsi
callq 0x32710
movq %rax, -0x6a8(%rbp)
jmp 0x1cf33
movq -0x5a0(%rbp), %rdi
movq -0x6a8(%rbp), %rax
movq %rax, -0x4b8(%rbp)
addq $0x88, %rdi
callq 0x32740
movq %rax, -0x4c0(%rbp)
leaq -0x4b8(%rbp), %rdi
leaq -0x4c0(%rbp), %rsi
callq 0x32bc0
testb $0x1, %al
jne 0x1cf77
jmp 0x1d090
movq -0x5a0(%rbp), %rdi
addq $0x88, %rdi
leaq -0x2c0(%rbp), %rsi
callq 0x322f0
movq %rax, -0x6b0(%rbp)
jmp 0x1cf9a
movq -0x6b0(%rbp), %rax
movl (%rax), %eax
movl %eax, -0x4c4(%rbp)
movb -0x19(%rbp), %al
andb $0x1, %al
movzbl %al, %eax
cmpl $0x0, %eax
jne 0x1d04c
movq -0x5a0(%rbp), %rax
movq 0x148(%rax), %rax
movslq -0x4c4(%rbp), %rcx
movq (%rax,%rcx,8), %rdi
leaq -0x478(%rbp), %rsi
callq 0x32bf0
jmp 0x1cfe1
jmp 0x1d08e
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x240(%rbp)
movl %eax, -0x244(%rbp)
jmp 0x1d018
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x240(%rbp)
movl %eax, -0x244(%rbp)
leaq -0x4b0(%rbp), %rdi
callq 0x13370
leaq -0x498(%rbp), %rdi
callq 0x6828
jmp 0x1d18e
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x240(%rbp)
movl %eax, -0x244(%rbp)
leaq -0x478(%rbp), %rdi
callq 0x32c60
jmp 0x1d18e
movq -0x5a0(%rbp), %rax
movq 0x150(%rax), %rax
movslq -0x4c4(%rbp), %rcx
movq (%rax,%rcx,8), %rdi
leaq -0x478(%rbp), %rsi
callq 0x32bf0
jmp 0x1d073
movq -0x5a0(%rbp), %rdi
addq $0x68, %rdi
leaq -0x288(%rbp), %rsi
callq 0x17750
jmp 0x1d08c
jmp 0x1d08e
jmp 0x1d105
movq 0x56f21(%rip), %rdi     # 0x73fb8
leaq 0x384a1(%rip), %rsi     # 0x5553f
callq 0x6420
movq %rax, -0x6b8(%rbp)
jmp 0x1d0ac
movq -0x6b8(%rbp), %rdi
leaq -0x2c0(%rbp), %rsi
callq 0x63e0
movq %rax, -0x6c0(%rbp)
jmp 0x1d0c8
movq -0x6c0(%rbp), %rdi
leaq 0x3895c(%rip), %rsi     # 0x55a32
callq 0x6420
movq %rax, -0x6c8(%rbp)
jmp 0x1d0e4
movq -0x6c8(%rbp), %rdi
movq 0x56e8e(%rip), %rsi     # 0x73f80
callq 0x6480
jmp 0x1d0f9
movl $0x2, -0x248(%rbp)
jmp 0x1d118
movl -0x20(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x20(%rbp)
movl $0x0, -0x248(%rbp)
leaq -0x478(%rbp), %rdi
callq 0x32c60
leaq -0x3b0(%rbp), %rdi
callq 0x13370
leaq -0x330(%rbp), %rdi
callq 0x13370
leaq -0x308(%rbp), %rdi
callq 0x6828
leaq -0x2e8(%rbp), %rdi
callq 0x6828
leaq -0x2c0(%rbp), %rdi
callq 0x6828
leaq -0x2a0(%rbp), %rdi
callq 0x13370
leaq -0x288(%rbp), %rdi
callq 0x6828
movl -0x248(%rbp), %eax
testl %eax, %eax
je 0x1d189
jmp 0x1d184
jmp 0x1c0e4
jmp 0x1c0e4
leaq -0x3b0(%rbp), %rdi
callq 0x13370
leaq -0x330(%rbp), %rdi
callq 0x13370
leaq -0x308(%rbp), %rdi
callq 0x6828
leaq -0x2e8(%rbp), %rdi
callq 0x6828
leaq -0x2c0(%rbp), %rdi
callq 0x6828
leaq -0x2a0(%rbp), %rdi
callq 0x13370
leaq -0x288(%rbp), %rdi
callq 0x6828
jmp 0x1d63e
leaq -0x238(%rbp), %rdi
callq 0x60e0
jmp 0x1d1f5
testb $0x1, -0x19(%rbp)
je 0x1d620
leaq -0x260(%rbp), %rdi
movq %rdi, -0x6d0(%rbp)
callq 0x32cd0
movq -0x6d0(%rbp), %rdi
movq %rax, -0x4d0(%rbp)
callq 0x32d00
movq %rax, -0x4d8(%rbp)
movq -0x4d0(%rbp), %rdi
movq -0x4d8(%rbp), %rsi
callq 0x32c90
jmp 0x1d241
leaq -0x260(%rbp), %rdi
movq %rdi, -0x6e0(%rbp)
callq 0x32cd0
movq -0x6e0(%rbp), %rdi
movq %rax, -0x4e8(%rbp)
callq 0x32d00
movq %rax, -0x4f0(%rbp)
movq -0x4e8(%rbp), %rdi
movq -0x4f0(%rbp), %rsi
leaq -0x30(%rbp), %rdx
callq 0x32d30
movq %rax, -0x6d8(%rbp)
jmp 0x1d28e
movq -0x6d8(%rbp), %rax
movq %rax, -0x4e0(%rbp)
leaq -0x260(%rbp), %rdi
movq %rdi, -0x6f0(%rbp)
callq 0x32cd0
movq %rax, -0x500(%rbp)
leaq -0x4e0(%rbp), %rdi
leaq -0x500(%rbp), %rsi
callq 0x32d80
movq -0x6f0(%rbp), %rdi
movl %eax, -0x4f4(%rbp)
callq 0x32dc0
movl -0x4f4(%rbp), %ecx
subl %ecx, %eax
movl %eax, -0x504(%rbp)
leaq -0x520(%rbp), %rdi
movq %rdi, -0x6e8(%rbp)
callq 0x322b0
movq -0x6e8(%rbp), %rdi
movl $0x0, -0x524(%rbp)
leaq -0x524(%rbp), %rsi
callq 0x32890
jmp 0x1d31b
movq -0x5a0(%rbp), %rdi
addq $0x250, %rdi            # imm = 0x250
movq $0x0, -0x530(%rbp)
leaq -0x530(%rbp), %rsi
callq 0x32de0
jmp 0x1d342
movl $0x1, -0x534(%rbp)
movq -0x5a0(%rbp), %rdi
movslq -0x534(%rbp), %rax
movq %rax, -0x6f8(%rbp)
addq $0x270, %rdi            # imm = 0x270
callq 0x32dc0
movq %rax, %rcx
movq -0x6f8(%rbp), %rax
cmpq %rcx, %rax
jae 0x1d5df
movq -0x5a0(%rbp), %rdi
cvtsi2ssl -0x504(%rbp), %xmm0
movss %xmm0, -0x704(%rbp)
addq $0x270, %rdi            # imm = 0x270
movslq -0x534(%rbp), %rsi
callq 0x32e10
movss -0x704(%rbp), %xmm0
mulss (%rax), %xmm0
cvttss2si %xmm0, %eax
movl %eax, -0x538(%rbp)
movl -0x4f4(%rbp), %eax
addl -0x538(%rbp), %eax
movl %eax, -0x53c(%rbp)
movslq -0x53c(%rbp), %rax
movq %rax, -0x700(%rbp)
leaq -0x260(%rbp), %rdi
callq 0x32dc0
movq %rax, %rcx
movq -0x700(%rbp), %rax
cmpq %rcx, %rax
jb 0x1d436
leaq -0x260(%rbp), %rdi
callq 0x32dc0
subq $0x1, %rax
movl %eax, -0x53c(%rbp)
jmp 0x1d436
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x240(%rbp)
movl %eax, -0x244(%rbp)
leaq -0x520(%rbp), %rdi
callq 0x32500
jmp 0x1d63e
movslq -0x53c(%rbp), %rsi
leaq -0x260(%rbp), %rdi
callq 0x32e10
movq -0x5a0(%rbp), %rdi
movss (%rax), %xmm0
cvtss2sd %xmm0, %xmm0
movsd %xmm0, -0x548(%rbp)
addq $0x250, %rdi            # imm = 0x250
leaq -0x548(%rbp), %rsi
callq 0x32e30
jmp 0x1d475
leaq -0x260(%rbp), %rdi
movq %rdi, -0x718(%rbp)
callq 0x32cd0
movq -0x718(%rbp), %rdi
movq %rax, -0x558(%rbp)
callq 0x32d00
movq %rax, -0x560(%rbp)
movq -0x558(%rbp), %rdi
movq -0x560(%rbp), %rsi
leaq -0x548(%rbp), %rdx
callq 0x32d30
movq %rax, -0x710(%rbp)
jmp 0x1d4c5
movq -0x710(%rbp), %rax
movq %rax, -0x550(%rbp)
leaq -0x260(%rbp), %rdi
callq 0x32cd0
movq %rax, -0x570(%rbp)
leaq -0x550(%rbp), %rdi
leaq -0x570(%rbp), %rsi
callq 0x32d80
movl %eax, -0x564(%rbp)
movl -0x564(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x574(%rbp)
movslq -0x574(%rbp), %rax
movq %rax, -0x720(%rbp)
leaq -0x260(%rbp), %rdi
callq 0x32dc0
movq %rax, %rcx
movq -0x720(%rbp), %rax
cmpq %rcx, %rax
jbe 0x1d549
leaq -0x260(%rbp), %rdi
callq 0x32dc0
movl %eax, -0x574(%rbp)
cvtsi2sdl -0x574(%rbp), %xmm0
movsd %xmm0, -0x728(%rbp)
leaq -0x260(%rbp), %rdi
callq 0x32dc0
movsd -0x728(%rbp), %xmm0
movq %rax, %xmm1
movaps 0x37d17(%rip), %xmm2    # 0x55290
punpckldq %xmm2, %xmm1    # xmm1 = xmm1[0],xmm2[0],xmm1[1],xmm2[1]
movapd 0x37d1b(%rip), %xmm2    # 0x552a0
subpd %xmm2, %xmm1
movaps %xmm1, %xmm2
unpckhpd %xmm1, %xmm1            # xmm1 = xmm1[1,1]
addsd %xmm2, %xmm1
divsd %xmm1, %xmm0
movsd %xmm0, -0x580(%rbp)
movsd -0x580(%rbp), %xmm0
cvtsd2ss %xmm0, %xmm0
movss %xmm0, -0x584(%rbp)
leaq -0x520(%rbp), %rdi
leaq -0x584(%rbp), %rsi
callq 0x32890
jmp 0x1d5c9
jmp 0x1d5cb
movl -0x534(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x534(%rbp)
jmp 0x1d34c
movq -0x5a0(%rbp), %rdi
addq $0x250, %rdi            # imm = 0x250
callq 0x32ea0
movq -0x5a0(%rbp), %rdi
movl %eax, 0x268(%rdi)
addq $0x270, %rdi            # imm = 0x270
leaq -0x520(%rbp), %rsi
callq 0x32ec0
jmp 0x1d614
leaq -0x520(%rbp), %rdi
callq 0x32500
movl -0x20(%rbp), %eax
movl %eax, -0x4(%rbp)
movl $0x1, -0x248(%rbp)
leaq -0x260(%rbp), %rdi
callq 0x32500
jmp 0x1d64c
leaq -0x260(%rbp), %rdi
callq 0x32500
jmp 0x1d664
leaq -0x238(%rbp), %rdi
callq 0x6120
movl -0x4(%rbp), %eax
addq $0x750, %rsp            # imm = 0x750
popq %rbp
retq
leaq -0x238(%rbp), %rdi
callq 0x6120
movq -0x240(%rbp), %rdi
callq 0x6750
nopl (%rax)