// File: /workspace/github_cpp_makefile_star2_O2/medvedevgroup[P]varmatch/src/wholegenome.cpp
// Function: WholeGenome::ClusteringMatchMultiThread()
void WholeGenome::ClusteringMatchMultiThread() {
	int start = 0;
	int cluster_number = variants_by_cluster.size(); // cluster number
	int cluster_end_boundary = start + cluster_number; // end cluster id, exclusive
	int cluster_step = cluster_number / thread_num; // assign clusters to threads
	if (cluster_step * thread_num < cluster_number) cluster_step++;
	int end = start + cluster_step;
	//initialize vector size
	//complex_match_records = new vector<string>*[thread_num];
	match_records_by_mode_by_thread = new vector<string>**[thread_num];

    //query_matches_by_mode_by_thread = new vector<int> ** [thread_num];

	for(int i = 0; i < thread_num; i++){
        match_records_by_mode_by_thread[i] = new vector<string>*[MATCH_MODE_NUM];
        //max_path_num_by_mode_by_thread.push_back(vector<int>());
        for(int j = 0; j < MATCH_MODE_NUM; j++){
            match_records_by_mode_by_thread[i][j] = new vector<string>;
            //max_path_num_by_mode_by_thread[i].push_back(0);
        }
	}

    baseline_total_match_num = new vector<int>** [thread_num];
    query_total_match_num = new vector<int> ** [thread_num];

    baseline_total_edit_distance = new vector<int>** [thread_num];
    query_total_edit_distance = new vector<int>** [thread_num];

    for(int i = 0; i < thread_num; i++){
        
        baseline_total_match_num[i] = new vector<int>* [ROC_SAMPLE_NUM];
        query_total_match_num[i] = new vector<int>* [ROC_SAMPLE_NUM];

        baseline_total_edit_distance[i] = new vector<int> * [ROC_SAMPLE_NUM];
        query_total_edit_distance[i] = new vector<int>* [ROC_SAMPLE_NUM];

        for(int j = 0; j < ROC_SAMPLE_NUM; j++){
            baseline_total_match_num[i][j] = new vector<int>;
            baseline_total_match_num[i][j]->resize(MATCH_MODE_NUM, 0);
            query_total_match_num[i][j] = new vector<int>;
            query_total_match_num[i][j]->resize(MATCH_MODE_NUM, 0);

            baseline_total_edit_distance[i][j] = new vector<int>;
            baseline_total_edit_distance[i][j]->resize(MATCH_MODE_NUM, 0);
            query_total_edit_distance[i][j] = new vector<int>;
            query_total_edit_distance[i][j]->resize(MATCH_MODE_NUM, 0);
        }
    }

	vector<thread> threads;
	//spawn threads
	unsigned i = 0;
	for (; i < thread_num - 1; i++) {
		threads.push_back(thread(&WholeGenome::ClusteringMatchInThread, this, start, end, i));
		start = end;
		end = start + cluster_step;
	}
	// also you need to do a job in main thread
	// i equals to (thread_num - 1)
	if (i != thread_num - 1) {
		dout << "[Error] thread number not match" << endl;
	}
	if (start >= variants_by_cluster.size()) {
		dout << "[Error] index out of map range" << endl;
	}
	else {
		ClusteringMatchInThread(start, end, i);
	}

	// call join() on each thread in turn before this function?
    std::for_each(threads.begin(), threads.end(), std::mem_fn(&std::thread::join));

    //output all results
    cout << "writing results..." << endl;
    ofstream output_stat_file;
    output_stat_file.open(output_dir + "/" + output_prefix+".stat");

    cout << "=========VarMatch Result Stat.=======" << endl;
    string stat_head_string = "#score_unit\tmatch_mode\tscore_unit\tqual_threshold\tbaseline_match_num\tquery_match_num\tquery_total_num\tbaseline_total_ED\tquery_total_ED";
    cout << stat_head_string << endl;
    output_stat_file << "##Baseline:" << baseline_variant_total_num << endl;
    output_stat_file << "##Query:"<< query_variant_total_num << endl;
    output_stat_file << stat_head_string << endl;

    int score_unit;
    int match_mode;
    int score_scheme;

    for(int x = 0; x < score_unit_list.size(); x++){
        score_unit = score_unit_list[x];
        for(int y = 0; y < match_mode_list.size(); y++){
            match_mode = match_mode_list[y];
            for(int z = 0; z < score_scheme_list.size(); z++){
                score_scheme = score_scheme_list[z];
                int mode_index = GetIndexFromMatchScore(score_unit, match_mode, score_scheme);
                int total_ref_complex = 0;
                int total_que_complex = 0;

                string threshold_string = "";
                string baseline_match_num_string = "";
                string query_match_num_string = "";
                string query_total_num_string = "";

                string baseline_edit_distance_string = "";
                string query_edit_distance_string = "";

                for(int t = 0; t < threshold_num; t++){
                    
                    threshold_string += to_string(threshold_list[t]);

                    int baseline_match_num_by_threshold_by_mode = 0;
                    int query_match_num_by_threshold_by_mode = 0;

                    int baseline_edit_distance_by_threshold_by_mode = 0;
                    int query_edit_distance_by_threshold_by_mode = 0;

                    for(int i = 0; i < thread_num; i++){
                        baseline_match_num_by_threshold_by_mode += baseline_total_match_num[i][t]->at(mode_index);
                        query_match_num_by_threshold_by_mode += query_total_match_num[i][t]->at(mode_index);

                        baseline_edit_distance_by_threshold_by_mode += baseline_total_edit_distance[i][t]->at(mode_index);
                        query_edit_distance_by_threshold_by_mode += query_total_edit_distance[i][t]->at(mode_index);
                    }

                    baseline_match_num_string += to_string(baseline_match_num_by_threshold_by_mode);
                    query_match_num_string += to_string(query_match_num_by_threshold_by_mode);
                    query_total_num_string += to_string((int)(query_variant_total_num * (1-per_list[t])) );

                    baseline_edit_distance_string += to_string(baseline_edit_distance_by_threshold_by_mode);
                    query_edit_distance_string += to_string(query_edit_distance_by_threshold_by_mode);

                    if(t < threshold_num-1){
                        threshold_string += ",";
                        baseline_match_num_string += ",";
                        query_match_num_string += ",";
                        query_total_num_string += ",";
                        baseline_edit_distance_string += ",";
                        query_edit_distance_string += ",";
                    }
                                  
                }

                string total_match_num_string = to_string(score_unit) + "\t" +
                                                to_string(match_mode) + "\t" + 
                                                to_string(score_scheme) + "\t" +
                                                threshold_string + "\t" +
                                                baseline_match_num_string + "\t" + 
                                                query_match_num_string + "\t" + 
                                                query_total_num_string;// + "\t" + to_string(mode_index);
                cout << total_match_num_string << "\t" << baseline_edit_distance_string << "\t" << query_edit_distance_string << endl;;
                output_stat_file << total_match_num_string << endl;
            }
        }
    }
    output_stat_file.close();

    int bench_mode_index = GetIndexFromMatchScore(0, 0, 0);

    for(int x = 0; x < score_unit_list.size(); x++){
        score_unit = score_unit_list[x];
        for(int y = 0; y < match_mode_list.size(); y++){
            match_mode = match_mode_list[y];
            for(int z = 0; z < score_scheme_list.size(); z++){
                score_scheme = score_scheme_list[z];
                int mode_index = GetIndexFromMatchScore(score_unit, match_mode, score_scheme);
                string filename_index = to_string(score_unit) + "_" + to_string(match_mode) + "_" + to_string(score_scheme);
                
                ofstream output_complex_file;
                output_complex_file.open(output_dir + "/" + output_prefix+"."+filename_index+".match");

                output_complex_file << "##VCF1:" << ref_vcf_filename << endl;
                output_complex_file << "##VCF2:" << que_vcf_filename << endl;
                output_complex_file << "#CHROM\tPOS\tREF\tALT\tVCF1\tVCF2\tPHASE1\tPHASE2\tSCORE" << endl;

                for(int i = 0; i < thread_num; i++){
                    for(int k = 0; k < match_records_by_mode_by_thread[i][mode_index]->size(); k++){
                        if (match_records_by_mode_by_thread[i][mode_index]->at(k).find_first_not_of(' ') != std::string::npos) {
                            //if(match_records_by_mode_by_thread[i][mode_index]->at(k)[0] == '$'){
                                //int bench_mode_index = stoi(match_records_by_mode_by_thread[i][mode_index]->at(k).erase(0,1));
                                //output_complex_file << match_records_by_mode_by_thread[i][0]->at(k);
                            //}else{
                                output_complex_file << match_records_by_mode_by_thread[i][mode_index]->at(k);
                            //}
                        }
                    }
                }
                output_complex_file.close();
            }
        }
    }

    // int max_path_num = 0;
    // for(int i = 0; i < thread_num; i++){
    //     for(int j = 0; j < MATCH_MODE_NUM; j++){
    //         max_path_num = max(max_path_num, max_path_num_by_mode_by_thread[i][j]);
    //         //max_path_num += max_path_num_by_mode_by_thread[i][j];
    //     }
    // }

    //cout << "max path number: " << max_path_num << endl;

    // clear all matching records
	for(int i = 0; i < thread_num; i++){
        for(int j = 0; j < MATCH_MODE_NUM; j++){
            delete match_records_by_mode_by_thread[i][j];

        }
        for(int j = 0; j < ROC_SAMPLE_NUM; j++){
            delete baseline_total_match_num[i][j];
            delete query_total_match_num[i][j];

            delete baseline_total_edit_distance[i][j];
            delete query_total_edit_distance[i][j];
        }
        delete[] match_records_by_mode_by_thread[i];
        delete[] baseline_total_match_num[i];
        delete[] query_total_match_num[i];
        
        delete[] baseline_total_edit_distance[i];
        delete[] query_total_edit_distance[i];
	}
	delete[] match_records_by_mode_by_thread;
    delete[] baseline_total_match_num;
    delete[] query_total_match_num;

    delete[] baseline_total_edit_distance;
    delete[] query_total_edit_distance;
    //max_path_num_by_mode_by_thread.clear();

}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x738, %rsp            # imm = 0x738
movq %rdi, %r12
andl $0x0, 0x2c(%rsp)
movq 0x168(%rdi), %rax
subq 0x160(%rdi), %rax
pushq $0x18
popq %r14
cqto
idivq %r14
movq %rax, %rcx
movslq 0x4(%rdi), %rbx
cltd
idivl %ebx
movl %eax, %edx
imull %ebx, %edx
xorl %esi, %esi
cmpl %ecx, %edx
setl %sil
addl %eax, %esi
leaq (,%rbx,8), %rax
testq %rbx, %rbx
movl %esi, 0x18(%rsp)
movl %esi, 0x14(%rsp)
pushq $-0x1
popq %r15
cmovnsq %rax, %r15
movq %r15, %rdi
callq 0x5030
movq %r12, (%rsp)
movq %rax, 0x178(%r12)
xorl %r12d, %r12d
testl %ebx, %ebx
movl $0x0, %r13d
cmovgl %ebx, %r13d
cmpq %r13, %r12
je 0x17641
movl $0x80, %edi
callq 0x5030
movq (%rsp), %rcx
movq 0x178(%rcx), %rcx
movq %rax, (%rcx,%r12,8)
xorl %ebp, %ebp
cmpq $0x10, %rbp
je 0x1763c
movq %r14, %rdi
callq 0x5300
xorps %xmm0, %xmm0
movups %xmm0, (%rax)
andq $0x0, 0x10(%rax)
movq (%rsp), %rcx
movq 0x178(%rcx), %rcx
movq (%rcx,%r12,8), %rcx
movq %rax, (%rcx,%rbp,8)
incq %rbp
jmp 0x1760b
incq %r12
jmp 0x175eb
movq %r15, %rdi
callq 0x5030
movq (%rsp), %r14
movq %rax, 0x180(%r14)
movq %r15, %rdi
callq 0x5030
movq %rax, 0x188(%r14)
movq %r15, %rdi
callq 0x5030
movq %rax, 0x190(%r14)
movq %r15, %rdi
callq 0x5030
movq %rax, 0x198(%r14)
xorl %ebp, %ebp
pushq $0x18
popq %r14
pushq $0x10
popq %r12
leaq 0x338(%rsp), %r13
movslq %ebx, %rax
cmpq %rax, %rbp
jge 0x1782b
pushq $0x28
popq %r15
movq %r15, %rdi
callq 0x5030
movq (%rsp), %rbx
movq 0x180(%rbx), %rcx
movq %rax, (%rcx,%rbp,8)
movq %r15, %rdi
callq 0x5030
movq 0x188(%rbx), %rcx
movq %rax, (%rcx,%rbp,8)
movq %r15, %rdi
callq 0x5030
movq 0x190(%rbx), %rcx
movq %rax, (%rcx,%rbp,8)
movq %r15, %rdi
callq 0x5030
movq 0x198(%rbx), %rcx
movq %rax, (%rcx,%rbp,8)
xorl %ebx, %ebx
cmpq $0x28, %rbx
je 0x1781c
movq %r14, %rdi
callq 0x5300
xorps %xmm0, %xmm0
movups %xmm0, (%rax)
andq $0x0, 0x10(%rax)
movq (%rsp), %r15
movq 0x180(%r15), %rcx
movq (%rcx,%rbp,8), %rcx
movq %rax, (%rcx,%rbx)
movq 0x180(%r15), %rax
movq (%rax,%rbp,8), %rax
movq (%rax,%rbx), %rdi
andl $0x0, 0x338(%rsp)
movq %r12, %rsi
movq %r13, %rdx
callq 0x1aa82
movq %r14, %rdi
callq 0x5300
xorps %xmm0, %xmm0
movups %xmm0, (%rax)
andq $0x0, 0x10(%rax)
movq 0x188(%r15), %rcx
movq (%rcx,%rbp,8), %rcx
movq %rax, (%rcx,%rbx)
movq 0x188(%r15), %rax
movq (%rax,%rbp,8), %rax
movq (%rax,%rbx), %rdi
andl $0x0, 0x338(%rsp)
movq %r12, %rsi
movq %r13, %rdx
callq 0x1aa82
movq %r14, %rdi
callq 0x5300
xorps %xmm0, %xmm0
movups %xmm0, (%rax)
andq $0x0, 0x10(%rax)
movq 0x190(%r15), %rcx
movq (%rcx,%rbp,8), %rcx
movq %rax, (%rcx,%rbx)
movq 0x190(%r15), %rax
movq (%rax,%rbp,8), %rax
movq (%rax,%rbx), %rdi
andl $0x0, 0x338(%rsp)
movq %r12, %rsi
movq %r13, %rdx
callq 0x1aa82
movq %r14, %rdi
callq 0x5300
xorps %xmm0, %xmm0
movups %xmm0, (%rax)
andq $0x0, 0x10(%rax)
movq 0x198(%r15), %rcx
movq (%rcx,%rbp,8), %rcx
movq %rax, (%rcx,%rbx)
movq 0x198(%r15), %rax
movq (%rax,%rbp,8), %rax
movq (%rax,%rbx), %rdi
andl $0x0, 0x338(%rsp)
movq %r12, %rsi
movq %r13, %rdx
callq 0x1aa82
addq $0x8, %rbx
jmp 0x176f5
incq %rbp
movq (%rsp), %rax
movl 0x4(%rax), %ebx
jmp 0x17693
xorps %xmm0, %xmm0
leaq 0x100(%rsp), %rax
movaps %xmm0, (%rax)
andq $0x0, 0x10(%rax)
xorl %eax, %eax
leaq 0x538(%rsp), %r12
leaq 0x2c(%rsp), %r15
leaq 0x14(%rsp), %r13
leaq 0x28(%rsp), %rbp
movl %eax, 0x28(%rsp)
decl %ebx
cmpl %ebx, %eax
jae 0x178e0
leaq -0x6f20(%rip), %rax     # 0x10948
movq %rax, 0x338(%rsp)
andq $0x0, 0x340(%rsp)
movq (%rsp), %rax
movq %rax, 0xe0(%rsp)
movq %r12, %rdi
leaq 0x338(%rsp), %rsi
leaq 0xe0(%rsp), %rdx
movq %r15, %rcx
movq %r13, %r8
movq %rbp, %r9
callq 0x1aab6
leaq 0x100(%rsp), %rdi
movq %r12, %rsi
callq 0x1d984
movq %r12, %rdi
callq 0x19f4a
movl 0x14(%rsp), %eax
movl %eax, 0x2c(%rsp)
addl 0x18(%rsp), %eax
movl %eax, 0x14(%rsp)
movl 0x28(%rsp), %eax
incl %eax
movq (%rsp), %rcx
movl 0x4(%rcx), %ebx
jmp 0x17857
movq (%rsp), %r13
je 0x17901
movq 0x186d3(%rip), %rdi     # 0x2ffc0
leaq 0xaf69(%rip), %rsi      # 0x2285d
callq 0x52f0
movq %rax, %rdi
callq 0x5190
movslq 0x2c(%rsp), %rsi
movq 0x168(%r13), %rax
subq 0x160(%r13), %rax
cqto
idivq %r14
cmpq %rsi, %rax
jbe 0x17930
movl 0x14(%rsp), %edx
movl 0x28(%rsp), %ecx
movq %r13, %rdi
callq 0x10948
jmp 0x1794b
movq 0x18689(%rip), %rdi     # 0x2ffc0
leaq 0xaf3f(%rip), %rsi      # 0x2287d
callq 0x52f0
movq %rax, %rdi
callq 0x5190
movq 0x100(%rsp), %rdi
movq 0x108(%rsp), %rsi
movq 0x1866e(%rip), %rdx     # 0x2ffd0
xorl %ecx, %ecx
callq 0x19f57
movq 0x18650(%rip), %rdi     # 0x2ffc0
leaq 0xaf25(%rip), %rsi      # 0x2289c
callq 0x52f0
movq %rax, %rdi
callq 0x5190
leaq 0x338(%rsp), %rdi
callq 0x5510
leaq 0x1c0(%r13), %rsi
leaq 0xac0c(%rip), %rdx      # 0x225ab
leaq 0xc0(%rsp), %rdi
movq %rsi, 0x130(%rsp)
callq 0x96b0
leaq 0x1a0(%r13), %rdx
leaq 0xe0(%rsp), %rdi
leaq 0xc0(%rsp), %rsi
movq %rdx, 0x128(%rsp)
callq 0x9691
leaq 0xaed0(%rip), %rdx      # 0x228af
leaq 0x538(%rsp), %rdi
leaq 0xe0(%rsp), %rsi
callq 0x7fce
leaq 0x338(%rsp), %rdi
leaq 0x538(%rsp), %rsi
pushq $0x10
popq %rdx
callq 0x5180
leaq 0x538(%rsp), %rdi
callq 0x55e8
leaq 0xe0(%rsp), %rdi
callq 0x55e8
leaq 0xc0(%rsp), %rdi
callq 0x55e8
movq 0x18586(%rip), %rdi     # 0x2ffc0
leaq 0xae74(%rip), %rsi      # 0x228b5
callq 0x52f0
movq %rax, %rdi
callq 0x5190
leaq 0xae86(%rip), %rsi      # 0x228db
leaq 0xe0(%rsp), %rdi
leaq 0x538(%rsp), %rdx
callq 0x72ee
movq 0x1854f(%rip), %rdi     # 0x2ffc0
leaq 0xe0(%rsp), %rsi
callq 0x52c0
movq %rax, %rdi
callq 0x5190
leaq 0xaed3(%rip), %rsi      # 0x22960
leaq 0x338(%rsp), %rdi
callq 0x52f0
movl 0x48(%r13), %esi
movq %rax, %rdi
callq 0x5530
movq %rax, %rdi
callq 0x5190
leaq 0xaeb7(%rip), %rsi      # 0x2296c
leaq 0x338(%rsp), %rdi
callq 0x52f0
movl 0x4c(%r13), %esi
movq %rax, %rdi
callq 0x5530
movq %rax, %rdi
callq 0x5190
leaq 0x338(%rsp), %rdi
leaq 0xe0(%rsp), %rsi
callq 0x52c0
movq %rax, %rdi
callq 0x5190
xorl %edx, %edx
leaq 0xaaae(%rip), %rbx      # 0x225aa
leaq 0xc0(%rsp), %r15
leaq 0x138(%rsp), %r14
leaq 0x158(%rsp), %r12
movq 0x1f0(%r13), %rax
movq 0x1f8(%r13), %rcx
subq %rax, %rcx
sarq $0x2, %rcx
cmpq %rdx, %rcx
jbe 0x18184
movq %rdx, 0x118(%rsp)
movl (%rax,%rdx,4), %eax
movq %rax, 0x58(%rsp)
addl %eax, %eax
andl $0x2, %eax
movl %eax, 0x7c(%rsp)
xorl %edx, %edx
movq 0x208(%r13), %rax
movq 0x210(%r13), %rcx
subq %rax, %rcx
sarq $0x2, %rcx
cmpq %rdx, %rcx
jbe 0x18174
movq %rdx, 0x120(%rsp)
movl (%rax,%rdx,4), %eax
movl %eax, 0x24(%rsp)
andl $0x1, %eax
orl 0x7c(%rsp), %eax
shll $0x2, %eax
movl %eax, 0x60(%rsp)
xorl %edx, %edx
movq 0x220(%r13), %rax
movq 0x228(%r13), %rcx
subq %rax, %rcx
sarq $0x2, %rcx
cmpq %rdx, %rcx
jbe 0x18164
movq %rdx, 0x68(%rsp)
movl (%rax,%rdx,4), %eax
movl %eax, 0x30(%rsp)
leaq 0x538(%rsp), %rdi
movq %rbx, %rsi
movq %r15, %rdx
callq 0x72ee
movq %r15, %rdi
movq %rbx, %rsi
movq %r14, %rdx
callq 0x72ee
movq %r14, %rdi
movq %rbx, %rsi
movq %r12, %rdx
callq 0x72ee
movq %r12, %rdi
movq %rbx, %rsi
leaq 0xa0(%rsp), %rbp
movq %rbp, %rdx
callq 0x72ee
movq %rbp, %rdi
movq %rbx, %rsi
leaq 0x80(%rsp), %rbp
movq %rbp, %rdx
callq 0x72ee
movq %rbp, %rdi
movq %rbx, %rsi
leaq 0x38(%rsp), %rdx
callq 0x72ee
movl 0x30(%rsp), %eax
andl $0x3, %eax
orl 0x60(%rsp), %eax
movl %eax, %eax
movq %rax, 0x70(%rsp)
xorl %ebx, %ebx
movslq 0x268(%r13), %rax
cmpq %rax, %rbx
jge 0x17e81
movq 0x250(%r13), %rax
movsd (%rax,%rbx,8), %xmm0
leaq 0x38(%rsp), %r14
movq %r14, %rdi
callq 0x1ab5c
leaq 0x538(%rsp), %rdi
movq %r14, %rsi
callq 0x55c0
movq %r14, %rdi
callq 0x55e8
xorl %r12d, %r12d
xorl %ebp, %ebp
movl $0x0, 0x18(%rsp)
movl $0x0, 0x10(%rsp)
movl $0x0, 0xc(%rsp)
movslq 0x4(%r13), %rax
cmpq %rax, %r12
jge 0x17d31
movq 0x180(%r13), %rax
movq (%rax,%r12,8), %rax
movq (%rax,%rbx,8), %rdi
movq %rbx, %r14
movq 0x70(%rsp), %rbx
movq %rbx, %rsi
callq 0x1a1ca
movq %r13, %r15
addl (%rax), %ebp
movq 0x188(%r13), %rax
movq (%rax,%r12,8), %rax
movq (%rax,%r14,8), %rdi
movq %rbx, %rsi
callq 0x1a1ca
movl 0x18(%rsp), %ecx
addl (%rax), %ecx
movl %ecx, 0x18(%rsp)
movq 0x190(%r15), %rax
movq (%rax,%r12,8), %rax
movq (%rax,%r14,8), %rdi
movq %rbx, %rsi
callq 0x1a1ca
movl (%rax), %r13d
movq 0x198(%r15), %rax
movq (%rax,%r12,8), %rax
movq (%rax,%r14,8), %rdi
movq %rbx, %rsi
callq 0x1a1ca
addl %r13d, 0x10(%rsp)
movl 0xc(%rsp), %ecx
addl (%rax), %ecx
movl %ecx, 0xc(%rsp)
incq %r12
movq %r15, %r13
movq %r14, %rbx
jmp 0x17c91
leaq 0x38(%rsp), %rdi
movq %rdi, %r14
movl %ebp, %esi
callq 0x8011
leaq 0xc0(%rsp), %r15
movq %r15, %rdi
movq %r14, %rbp
movq %r14, %rsi
callq 0x55c0
movq %rbp, %rdi
callq 0x55e8
movq %rbp, %rdi
movl 0x18(%rsp), %esi
callq 0x8011
leaq 0x138(%rsp), %r14
movq %r14, %rdi
movq %rbp, %rsi
callq 0x55c0
movq %rbp, %rdi
callq 0x55e8
cvtsi2ssl 0x4c(%r13), %xmm0
movq 0x270(%r13), %rax
movss 0xa522(%rip), %xmm1     # 0x222bc
subss (%rax,%rbx,4), %xmm1
mulss %xmm0, %xmm1
cvttss2si %xmm1, %esi
movq %rbp, %rdi
callq 0x8011
leaq 0x158(%rsp), %r12
movq %r12, %rdi
movq %rbp, %rsi
callq 0x55c0
movq %rbp, %rdi
callq 0x55e8
movq %rbp, %rdi
movl 0x10(%rsp), %esi
callq 0x8011
leaq 0xa0(%rsp), %rdi
movq %rbp, %rsi
callq 0x55c0
movq %rbp, %rdi
callq 0x55e8
movq %rbp, %rdi
movl 0xc(%rsp), %esi
callq 0x8011
leaq 0x80(%rsp), %rdi
movq %rbp, %rsi
callq 0x55c0
movq %rbp, %rdi
callq 0x55e8
movslq 0x268(%r13), %rax
decq %rax
cmpq %rax, %rbx
leaq 0xa723(%rip), %rbp      # 0x22549
jge 0x17e79
leaq 0x538(%rsp), %rdi
movq %rbp, %rsi
callq 0x55a0
movq %r15, %rdi
movq %rbp, %rsi
callq 0x55a0
movq %r14, %rdi
movq %rbp, %rsi
callq 0x55a0
movq %r12, %rdi
movq %rbp, %rsi
callq 0x55a0
leaq 0xa0(%rsp), %rdi
movq %rbp, %rsi
callq 0x55a0
leaq 0x80(%rsp), %rdi
movq %rbp, %rsi
callq 0x55a0
incq %rbx
jmp 0x17c33
leaq 0x1f8(%rsp), %rbx
movq %rbx, %rdi
movq 0x58(%rsp), %rsi
callq 0x8011
leaq 0x178(%rsp), %rdi
movq %rbx, %rsi
leaq 0xa701(%rip), %rdx      # 0x225a9
callq 0x7fce
leaq 0x1d8(%rsp), %rbx
movq %rbx, %rdi
movl 0x24(%rsp), %esi
callq 0x8011
leaq 0x218(%rsp), %rbp
movq %rbp, %rdi
leaq 0x178(%rsp), %rsi
movq %rbx, %rdx
callq 0x94bb
leaq 0x198(%rsp), %rdi
movq %rbp, %rsi
leaq 0xa6bb(%rip), %rdx      # 0x225a9
callq 0x7fce
leaq 0x1b8(%rsp), %rbx
movq %rbx, %rdi
movl 0x30(%rsp), %esi
callq 0x8011
leaq 0x238(%rsp), %rbp
movq %rbp, %rdi
leaq 0x198(%rsp), %rsi
movq %rbx, %rdx
callq 0x94bb
leaq 0x258(%rsp), %rbx
movq %rbx, %rdi
movq %rbp, %rsi
leaq 0xa672(%rip), %rdx      # 0x225a9
callq 0x7fce
leaq 0x278(%rsp), %rbp
movq %rbp, %rdi
movq %rbx, %rsi
leaq 0x538(%rsp), %rdx
callq 0x9691
leaq 0x298(%rsp), %rbx
movq %rbx, %rdi
movq %rbp, %rsi
leaq 0xa63d(%rip), %rdx      # 0x225a9
callq 0x7fce
leaq 0x2b8(%rsp), %rbp
movq %rbp, %rdi
movq %rbx, %rsi
movq %r15, %rdx
callq 0x9691
leaq 0x2d8(%rsp), %rbx
movq %rbx, %rdi
movq %rbp, %rsi
leaq 0xa60d(%rip), %rdx      # 0x225a9
callq 0x7fce
leaq 0x2f8(%rsp), %rbp
movq %rbp, %rdi
movq %rbx, %rsi
movq %r14, %rdx
callq 0x9691
leaq 0x318(%rsp), %rdi
movq %rbp, %rsi
leaq 0xa5e0(%rip), %rdx      # 0x225a9
callq 0x7fce
leaq 0x38(%rsp), %rbx
movq %rbx, %rdi
leaq 0x318(%rsp), %rbp
movq %rbp, %rsi
movq %r12, %rdx
callq 0x9691
movq %rbp, %rdi
callq 0x55e8
leaq 0x2f8(%rsp), %rdi
callq 0x55e8
leaq 0x2d8(%rsp), %rdi
callq 0x55e8
leaq 0x2b8(%rsp), %rdi
callq 0x55e8
leaq 0x298(%rsp), %rdi
callq 0x55e8
leaq 0x278(%rsp), %rdi
callq 0x55e8
leaq 0x258(%rsp), %rdi
callq 0x55e8
leaq 0x238(%rsp), %rdi
callq 0x55e8
leaq 0x1b8(%rsp), %rdi
callq 0x55e8
leaq 0x198(%rsp), %rdi
callq 0x55e8
leaq 0x218(%rsp), %rdi
callq 0x55e8
leaq 0x1d8(%rsp), %rdi
callq 0x55e8
leaq 0x178(%rsp), %rdi
callq 0x55e8
leaq 0x1f8(%rsp), %rdi
callq 0x55e8
movq 0x17f1f(%rip), %rdi     # 0x2ffc0
movq %rbx, %rsi
callq 0x52c0
leaq 0xa0(%rsp), %rbx
movq %rax, %rdi
leaq 0xa4ee(%rip), %rsi      # 0x225a9
callq 0x52f0
movq %rax, %rdi
movq %rbx, %rsi
callq 0x52c0
movq %rax, %rdi
leaq 0xa4d4(%rip), %rsi      # 0x225a9
callq 0x52f0
movq %rax, %rdi
leaq 0x80(%rsp), %rsi
callq 0x52c0
movq %rax, %rdi
callq 0x5190
leaq 0x338(%rsp), %rdi
leaq 0x38(%rsp), %rsi
callq 0x52c0
movq %rax, %rdi
callq 0x5190
leaq 0x38(%rsp), %rdi
callq 0x55e8
leaq 0x80(%rsp), %rdi
callq 0x55e8
movq %rbx, %rdi
callq 0x55e8
movq %r12, %rdi
callq 0x55e8
movq %r14, %rdi
callq 0x55e8
movq %r15, %rdi
callq 0x55e8
leaq 0x538(%rsp), %rdi
callq 0x55e8
movq 0x68(%rsp), %rdx
incq %rdx
leaq 0xa44b(%rip), %rbx      # 0x225aa
jmp 0x17b8a
movq 0x120(%rsp), %rdx
incq %rdx
jmp 0x17b4d
movq 0x118(%rsp), %rdx
incq %rdx
jmp 0x17b14
leaq 0x338(%rsp), %rdi
callq 0x5400
leaq 0x8(%r13), %rax
movq %rax, 0x30(%rsp)
leaq 0x28(%r13), %rax
movq %rax, 0x68(%rsp)
xorl %edx, %edx
leaq 0x158(%rsp), %r12
movq %r13, %rcx
leaq 0x538(%rsp), %r13
pushq $0x20
popq %rbp
movq 0x1f0(%rcx), %rax
movq 0x1f8(%rcx), %rcx
subq %rax, %rcx
sarq $0x2, %rcx
cmpq %rdx, %rcx
jbe 0x1851d
movq %rdx, 0x58(%rsp)
movl (%rax,%rdx,4), %eax
movq %rax, 0x70(%rsp)
addl %eax, %eax
andl $0x2, %eax
movl %eax, 0x24(%rsp)
xorl %edx, %edx
movq (%rsp), %rcx
movq 0x208(%rcx), %rax
movq 0x210(%rcx), %rcx
subq %rax, %rcx
sarq $0x2, %rcx
cmpq %rdx, %rcx
jbe 0x1850c
movq %rdx, 0x60(%rsp)
movl (%rax,%rdx,4), %eax
movl %eax, 0xc(%rsp)
andl $0x1, %eax
orl 0x24(%rsp), %eax
shll $0x2, %eax
movl %eax, 0x10(%rsp)
xorl %edx, %edx
movq (%rsp), %rcx
movq 0x220(%rcx), %rax
movq 0x228(%rcx), %rcx
subq %rax, %rcx
sarq $0x2, %rcx
cmpq %rdx, %rcx
jbe 0x184ff
movq %rdx, 0x18(%rsp)
movl (%rax,%rdx,4), %r14d
leaq 0xa0(%rsp), %rbx
movq %rbx, %rdi
movq 0x70(%rsp), %rsi
callq 0x8011
movq %r12, %rdi
movq %rbx, %rsi
leaq 0xa6f9(%rip), %rdx      # 0x22975
callq 0x7fce
leaq 0x80(%rsp), %r15
movq %r15, %rdi
movl 0xc(%rsp), %esi
callq 0x8011
leaq 0x138(%rsp), %rbx
movq %rbx, %rdi
movq %r12, %rsi
movq %r15, %rdx
callq 0x94bb
movq %r13, %rdi
movq %rbx, %rsi
leaq 0xa6bd(%rip), %rdx      # 0x22975
callq 0x7fce
leaq 0x38(%rsp), %rbx
movq %rbx, %rdi
movl %r14d, %esi
callq 0x8011
leaq 0xc0(%rsp), %rdi
movq %r13, %rsi
movq %rbx, %rdx
callq 0x94bb
movq %rbx, %rdi
callq 0x55e8
movq %r13, %rdi
callq 0x55e8
leaq 0x138(%rsp), %rdi
callq 0x55e8
leaq 0x80(%rsp), %rdi
callq 0x55e8
movq %r12, %rdi
callq 0x55e8
leaq 0xa0(%rsp), %rdi
callq 0x55e8
movq %r13, %rdi
callq 0x5510
movq %rbx, %rdi
movq 0x130(%rsp), %rsi
leaq 0xa272(%rip), %rdx      # 0x225ab
callq 0x96b0
leaq 0x80(%rsp), %r15
movq %r15, %rdi
movq %rbx, %rsi
movq 0x128(%rsp), %rdx
callq 0x9691
leaq 0xa0(%rsp), %rbx
movq %rbx, %rdi
movq %r15, %rsi
leaq 0xa6d0(%rip), %rdx      # 0x22a3e
callq 0x7fce
movq %r12, %rdi
movq %rbx, %rsi
leaq 0xc0(%rsp), %rdx
callq 0x9691
leaq 0x138(%rsp), %r15
movq %r15, %rdi
movq %r12, %rsi
leaq 0xa5dc(%rip), %rdx      # 0x22977
callq 0x7fce
movq %r13, %rdi
movq %r15, %rsi
pushq $0x10
popq %rdx
callq 0x5180
movq %r15, %rdi
callq 0x55e8
movq %r12, %rdi
callq 0x55e8
leaq 0xa0(%rsp), %rdi
callq 0x55e8
leaq 0x80(%rsp), %rdi
callq 0x55e8
leaq 0x38(%rsp), %rdi
callq 0x55e8
movq %r13, %rdi
leaq 0xa592(%rip), %rsi      # 0x2297e
callq 0x52f0
movq %rax, %rdi
movq 0x30(%rsp), %rsi
callq 0x52c0
movq %rax, %rdi
callq 0x5190
movq %r13, %rdi
leaq 0xa576(%rip), %rsi      # 0x22986
callq 0x52f0
movq %rax, %rdi
movq 0x68(%rsp), %rsi
callq 0x52c0
movq %rax, %rdi
callq 0x5190
movq %r13, %rdi
leaq 0xa55a(%rip), %rsi      # 0x2298e
callq 0x52f0
movq %rax, %rdi
callq 0x5190
andl $0x3, %r14d
orl 0x10(%rsp), %r14d
movl %r14d, %ebx
xorl %r12d, %r12d
movq (%rsp), %rax
movslq 0x4(%rax), %rax
cmpq %rax, %r12
jge 0x184cd
xorl %r14d, %r14d
movq (%rsp), %rax
movq 0x178(%rax), %rax
movq (%rax,%r12,8), %rax
movq (%rax,%rbx,8), %rdi
movq 0x8(%rdi), %rax
subq (%rdi), %rax
sarq $0x5, %rax
cmpq %r14, %rax
jbe 0x184c8
movq %r14, %rsi
callq 0x1ab80
movq %rax, %rdi
movl %ebp, %esi
xorl %edx, %edx
callq 0x52d0
cmpq $-0x1, %rax
je 0x184c3
movq (%rsp), %rax
movq 0x178(%rax), %rax
movq (%rax,%r12,8), %rax
movq (%rax,%rbx,8), %rdi
movq %r14, %rsi
callq 0x1ab80
movq %r13, %rdi
movq %rax, %rsi
callq 0x52c0
incq %r14
jmp 0x18460
incq %r12
jmp 0x18450
movq %r13, %rdi
callq 0x5400
movq %r13, %rdi
callq 0x5430
leaq 0xc0(%rsp), %rdi
callq 0x55e8
movq 0x18(%rsp), %rdx
incq %rdx
leaq 0x158(%rsp), %r12
jmp 0x1822f
movq 0x60(%rsp), %rdx
incq %rdx
jmp 0x181f1
movq 0x58(%rsp), %rdx
incq %rdx
movq (%rsp), %rcx
jmp 0x181bb
xorl %ebx, %ebx
pushq $0x18
popq %r14
movq (%rsp), %r13
movslq 0x4(%r13), %rax
cmpq %rax, %rbx
jge 0x1868b
xorl %r12d, %r12d
cmpq $0x10, %r12
je 0x18569
movq 0x178(%r13), %rax
movq (%rax,%rbx,8), %rax
movq (%rax,%r12,8), %r15
testq %r15, %r15
je 0x18559
movq %r15, %rdi
callq 0xadcc
movq %r15, %rdi
movq %r14, %rsi
callq 0x5310
incq %r12
jmp 0x18537
xorl %r12d, %r12d
cmpq $0x5, %r12
je 0x1861a
movq 0x180(%r13), %rax
movq (%rax,%rbx,8), %rax
movq (%rax,%r12,8), %r15
testq %r15, %r15
je 0x18592
movq %r15, %rdi
callq 0xce14
movq %r15, %rdi
movq %r14, %rsi
callq 0x5310
movq 0x188(%r13), %rax
movq (%rax,%rbx,8), %rax
movq (%rax,%r12,8), %r15
testq %r15, %r15
je 0x185b9
movq %r15, %rdi
callq 0xce14
movq %r15, %rdi
movq %r14, %rsi
callq 0x5310
movq 0x190(%r13), %rax
movq (%rax,%rbx,8), %rax
movq (%rax,%r12,8), %r15
testq %r15, %r15
je 0x185e0
movq %r15, %rdi
callq 0xce14
movq %r15, %rdi
movq %r14, %rsi
callq 0x5310
movq 0x198(%r13), %rax
movq (%rax,%rbx,8), %rax
movq (%rax,%r12,8), %r15
testq %r15, %r15
je 0x18607
movq %r15, %rdi
callq 0xce14
movq %r15, %rdi
movq %r14, %rsi
callq 0x5310
incq %r12
jmp 0x1856c
movq 0x178(%r13), %rax
movq (%rax,%rbx,8), %rdi
testq %rdi, %rdi
je 0x1862f
callq 0x53a0
movq 0x180(%r13), %rax
movq (%rax,%rbx,8), %rdi
testq %rdi, %rdi
je 0x18644
callq 0x53a0
movq 0x188(%r13), %rax
movq (%rax,%rbx,8), %rdi
testq %rdi, %rdi
je 0x18659
callq 0x53a0
movq 0x190(%r13), %rax
movq (%rax,%rbx,8), %rdi
testq %rdi, %rdi
je 0x1866e
callq 0x53a0
movq 0x198(%r13), %rax
movq (%rax,%rbx,8), %rdi
testq %rdi, %rdi
je 0x18683
callq 0x53a0
incq %rbx
jmp 0x18527
movq 0x178(%r13), %rdi
testq %rdi, %rdi
je 0x1869c
callq 0x53a0
movq 0x180(%r13), %rdi
testq %rdi, %rdi
je 0x186ad
callq 0x53a0
movq 0x188(%r13), %rdi
testq %rdi, %rdi
je 0x186be
callq 0x53a0
movq 0x190(%r13), %rdi
testq %rdi, %rdi
je 0x186cf
callq 0x53a0
movq 0x198(%r13), %rdi
testq %rdi, %rdi
je 0x186e0
callq 0x53a0
leaq 0xe0(%rsp), %rdi
callq 0x55e8
leaq 0x338(%rsp), %rdi
callq 0x5430
leaq 0x100(%rsp), %rdi
callq 0x19fa8
addq $0x738, %rsp            # imm = 0x738
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
jmp 0x1897c
jmp 0x1875b
movq %rax, %rbx
leaq 0x538(%rsp), %rdi
callq 0x55e8
jmp 0x18735
movq %rax, %rbx
leaq 0xe0(%rsp), %rdi
callq 0x55e8
jmp 0x18747
movq %rax, %rbx
leaq 0xc0(%rsp), %rdi
jmp 0x18a2d
jmp 0x1875b
jmp 0x18855
movq %rax, %rbx
jmp 0x18a32
jmp 0x18855
jmp 0x1897c
movq %rax, %rbx
leaq 0x138(%rsp), %rdi
callq 0x55e8
jmp 0x18782
movq %rax, %rbx
leaq 0x158(%rsp), %rdi
callq 0x55e8
jmp 0x187a3
movq %rax, %rbx
jmp 0x187c2
jmp 0x189ba
movq %rax, %rbx
jmp 0x187e6
movq %rax, %rbx
leaq 0xa0(%rsp), %rdi
callq 0x55e8
jmp 0x187b5
movq %rax, %rbx
leaq 0x80(%rsp), %rdi
callq 0x55e8
leaq 0x38(%rsp), %rdi
callq 0x55e8
jmp 0x189bd
movq %rax, %rbx
jmp 0x189ca
movq %rax, %rbx
leaq 0x38(%rsp), %rdi
callq 0x55e8
leaq 0x538(%rsp), %rdi
callq 0x55e8
jmp 0x187f8
movq %rax, %rbx
leaq 0x138(%rsp), %rdi
callq 0x55e8
jmp 0x1880a
movq %rax, %rbx
leaq 0x80(%rsp), %rdi
callq 0x55e8
jmp 0x1881c
movq %rax, %rbx
leaq 0x158(%rsp), %rdi
callq 0x55e8
leaq 0xa0(%rsp), %rdi
jmp 0x18a20
movq %rax, %rbx
jmp 0x18829
jmp 0x1897c
movq %rax, %rbx
leaq 0x538(%rsp), %rdi
callq 0x19f4a
jmp 0x18a3f
movq %rax, %rbx
jmp 0x18a3f
jmp 0x189ba
movq %rax, %rbx
leaq 0x318(%rsp), %rdi
callq 0x55e8
jmp 0x188b7
movq %rax, %rbx
jmp 0x188f8
movq %rax, %rbx
jmp 0x188c4
movq %rax, %rbx
jmp 0x188eb
movq %rax, %rbx
jmp 0x188d1
movq %rax, %rbx
jmp 0x188de
movq %rax, %rbx
jmp 0x1892c
movq %rax, %rbx
jmp 0x18946
jmp 0x189d4
movq %rax, %rbx
jmp 0x1891f
movq %rax, %rbx
jmp 0x18905
movq %rax, %rbx
jmp 0x18953
movq %rax, %rbx
leaq 0x2f8(%rsp), %rdi
callq 0x55e8
leaq 0x2d8(%rsp), %rdi
callq 0x55e8
leaq 0x2b8(%rsp), %rdi
callq 0x55e8
leaq 0x298(%rsp), %rdi
callq 0x55e8
leaq 0x278(%rsp), %rdi
callq 0x55e8
leaq 0x258(%rsp), %rdi
callq 0x55e8
leaq 0x238(%rsp), %rdi
callq 0x55e8
leaq 0x1b8(%rsp), %rdi
callq 0x55e8
leaq 0x198(%rsp), %rdi
callq 0x55e8
leaq 0x218(%rsp), %rdi
callq 0x55e8
leaq 0x1d8(%rsp), %rdi
callq 0x55e8
leaq 0x178(%rsp), %rdi
callq 0x55e8
leaq 0x1f8(%rsp), %rdi
jmp 0x189af
movq %rax, %rbx
jmp 0x18912
movq %rax, %rbx
jmp 0x18939
movq %rax, %rbx
jmp 0x18a0b
movq %rax, %rbx
jmp 0x189f1
movq %rax, %rbx
jmp 0x189fe
movq %rax, %rbx
jmp 0x18a25
movq %rax, %rbx
jmp 0x18a18
movq %rax, %rbx
jmp 0x189e4
jmp 0x189a7
jmp 0x189d4
jmp 0x189a7
jmp 0x189a7
jmp 0x189a7
jmp 0x189d4
jmp 0x189d4
jmp 0x189d4
jmp 0x189d4
jmp 0x189a7
jmp 0x189a7
movq %rax, %rbx
leaq 0x38(%rsp), %rdi
callq 0x55e8
jmp 0x189d7
jmp 0x189d4
jmp 0x189d4
movq %rax, %rbx
leaq 0x538(%rsp), %rdi
callq 0x5430
leaq 0xc0(%rsp), %rdi
jmp 0x18a20
movq %rax, %rbx
leaq 0x80(%rsp), %rdi
callq 0x55e8
leaq 0xa0(%rsp), %rdi
callq 0x55e8
leaq 0x158(%rsp), %rdi
callq 0x55e8
leaq 0x138(%rsp), %rdi
callq 0x55e8
leaq 0xc0(%rsp), %rdi
callq 0x55e8
leaq 0x538(%rsp), %rdi
callq 0x55e8
leaq 0xe0(%rsp), %rdi
callq 0x55e8
leaq 0x338(%rsp), %rdi
callq 0x5430
leaq 0x100(%rsp), %rdi
callq 0x19fa8
movq %rbx, %rdi
callq 0x5540