// File: /workspace/github_cpp_makefile_star2_O3/chhylp123[P]hifiasm/Correct.cpp
// Function: generate_haplotypes_naive_HiFi(haplotype_evdience_alloc*, overlap_region_alloc*, double, UC_Read*, unsigned long, double, unsigned long)
void generate_haplotypes_naive_HiFi(haplotype_evdience_alloc* hap, overlap_region_alloc* overlap_list, double up, UC_Read* g_read, uint64_t multi_check, double st_rate, uint64_t st_max)
{
    // fprintf(stderr, "[M::%s::] Done\n", __func__);
    if(hap->length == 0) return;
    uint64_t k, l, i, o, *a, ii, m_snp_stat, m_list, m_off;
    int64_t z; 
    SnpStats *s = NULL, *t = NULL;

    for (k = 1, l = 0, i = m_snp_stat = m_list = 0; k <= hap->snp_stat.n; ++k) {///filter snps
        if(k == hap->snp_stat.n || hap->snp_stat.a[k].site != hap->snp_stat.a[l].site) {
            if((l > 0) && (hap->snp_stat.a[l].site == (hap->snp_stat.a[l-1].site + 1))) {
                l = k; continue;
            }
            if((k < hap->snp_stat.n) && ((hap->snp_stat.a[l].site+1) == hap->snp_stat.a[k].site)) {
                l = k; continue;
            }

            for (; i < hap->length && hap->list[i].site != hap->snp_stat.a[l].site; i++);
            assert(i < hap->length && hap->list[i].site == hap->snp_stat.a[l].site);
            m_off = l - m_snp_stat; 
            for (; i < hap->length && hap->list[i].site == hap->snp_stat.a[l].site; i++) {
                assert(hap->list[i].overlapSite>=l && hap->list[i].overlapSite < k);
                // assert(hap->snp_stat.a[hap->list[i].overlapSite].site==hap->list[i].site);
                hap->list[m_list] = hap->list[i]; hap->list[m_list++].overlapSite -= m_off;
            }
        
            for (; l < k; l++) hap->snp_stat.a[m_snp_stat++] = hap->snp_stat.a[l];
        }
    }
    hap->snp_stat.n = m_snp_stat; hap->length = m_list;
    if(hap->snp_stat.n == 0 || hap->length == 0) return;

    // for (k = 0; k < hap->snp_stat.n; k++) {
    //     s = &(hap->snp_stat.a[k]); if(s->site != 1502) continue;
    //     fprintf(stderr, "[M::%s] site::%u, occ_0::%u, occ_1::%u, occ_2::%u, is_homopolymer::%u\n", __func__, s->site, s->occ_0, s->occ_1, s->occ_2, s->is_homopolymer);
    //     prt_sub_read(g_read->seq, g_read->length, s->site, 25);
    //     for (i = 0; i < overlap_list->length; i++) {
    //         if(/**overlap_list->list[i].is_match == 1 &&**/ overlap_list->list[i].x_pos_s <= s->site && s->site <= overlap_list->list[i].x_pos_e) {
    //             fprintf(stderr, "%.*s\tis_match::%u\tid::%u\n", (int)Get_NAME_LENGTH(R_INF, overlap_list->list[i].y_id), Get_NAME(R_INF, overlap_list->list[i].y_id), overlap_list->list[i].is_match, overlap_list->list[i].y_id);
    //         }   
    //     }
    // }
    

    hap->snp_srt.n = 0;
    radix_sort_haplotype_evdience_id_srt(hap->list, hap->list + hap->length);
    for (k = 1, l = 0; k <= hap->length; ++k) {  
        if (k == hap->length || hap->list[k].overlapID != hap->list[l].overlapID) {
            for (i = l, o = 0; i < k; i++) {
                if(hh_tp(hap->list[i])!=1) continue;///mismatch
                s = &(hap->snp_stat.a[hap->list[i].overlapSite]); 
                assert(s->site == hap->list[i].site);
                if(s->occ_0 < 2 || s->occ_1 < 2) continue;
                if(is_st_bs((*s), st_rate, st_max)) continue;
                if(s->occ_0 >= asm_opt.s_hap_cov && s->occ_1 >= asm_opt.infor_cov) o++;///allels must be real
            }

            // if(overlap_list->list[hap->list[l].overlapID].y_id == 4378830 || overlap_list->list[hap->list[l].overlapID].y_id == 4378829 || overlap_list->list[hap->list[l].overlapID].y_id == 4378799) {
            //     fprintf(stderr, "[M::%s-id::%u] o->%lu(%c), l::%lu\n", __func__, overlap_list->list[hap->list[l].overlapID].y_id, o, "+-"[overlap_list->list[hap->list[l].overlapID].y_pos_strand], l);
            //     for (i = l; i < k; i++) {
            //         if(hh_tp(hap->list[i])!=1) continue;///mismatch
            //         s = &(hap->snp_stat.a[hap->list[i].overlapSite]); 
            //         assert(s->site == hap->list[i].site);
            //         if(s->occ_0 < 2 || s->occ_1 < 2) continue;
            //         if(is_st_bs((*s), st_rate, st_max)) continue;
            //         if(s->occ_0 >= asm_opt.s_hap_cov && s->occ_1 >= asm_opt.infor_cov) {
            //             fprintf(stderr, "[M::%s] site::%u, occ_0::%u, occ_1::%u, occ_2::%u, is_homopolymer::%u\n", __func__, s->site, s->occ_0, s->occ_1, s->occ_1, s->is_homopolymer);
            //             prt_sub_read(g_read->seq, g_read->length, s->site, 50);
            //         }
            //     }
            // } 
            // else {
            //     for (i = l, o = 0; i < k; i++) {
            //         if(hh_tp(hap->list[i])!=0) continue;///mismatch
            //         s = &(hap->snp_stat.a[hap->list[i].overlapSite]); 
            //         assert(s->site == hap->list[i].site);
            //         if(s->occ_0 < 2 || s->occ_1 < 2) continue;
            //         if(s->occ_0 >= asm_opt.s_hap_cov && s->occ_1 >= asm_opt.infor_cov) {
            //             if(s->site == 7878 || s->site == 9682) {
                        
            //                 fprintf(stderr, "***[M::%s] site::%u, rid::%u\t%.*s\n", __func__, s->site, overlap_list->list[hap->list[l].overlapID].y_id, (int)Get_NAME_LENGTH(R_INF, overlap_list->list[hap->list[l].overlapID].y_id), 
            //                     Get_NAME(R_INF, overlap_list->list[hap->list[l].overlapID].y_id));
            //                 prt_sub_cigar(&(overlap_list->list[hap->list[l].overlapID]), g_read->length, s->site, 50);
            //             }
            //             // o++;///allels must be real
            //             // fprintf(stderr, "[M::%s] site::%u, occ_0::%u, occ_1::%u, occ_2::%u, is_homopolymer::%u\n", __func__, s->site, s->occ_0, s->occ_1, s->occ_1, s->is_homopolymer);
            //             // prt_sub_read(g_read->seq, g_read->length, s->site, 50);
            //         }
            //     }
            // }

            // if(overlap_list->list[hap->list[l].overlapID].y_id == 20835) {
            //     fprintf(stderr, "***0***[M::%s-id::%u] o->%lu\n", __func__, overlap_list->list[hap->list[l].overlapID].y_id, o);
            // }

            if(o > 0) {
                o = ((uint32_t)-1) - o;
                o <<= 32; o += l; 
                kv_push(uint64_t, hap->snp_srt, o);
            }
            l = k;
        }
    }

    // fprintf(stderr, "[M::%s] snp_srt.n->%lu\n", __func__, ((uint64_t)hap->snp_srt.n));
    
    if (hap->snp_srt.n > 0) {
        radix_sort_bc64(hap->snp_srt.a, hap->snp_srt.a + hap->snp_srt.n);///sort by how many snps in one overlap
        for (k = 0; k < hap->snp_srt.n; k++) {
            o = 0; l = (uint32_t)hap->snp_srt.a[k];
            for (i = l; i < hap->length && hap->list[i].overlapID == hap->list[l].overlapID; i++) {
                if(hh_tp(hap->list[i])!=1) continue;
                s = &(hap->snp_stat.a[hap->list[i].overlapSite]);
                if(s->occ_0 < 2 || s->occ_1 < 2) continue;
                if(is_st_bs((*s), st_rate, st_max)) continue;
                if(s->occ_0 >= asm_opt.s_hap_cov && s->occ_1 >= asm_opt.infor_cov) {
                    o++;
                    // if(overlap_list->list[hap->list[l].overlapID].y_id == 20835) {
                    //     fprintf(stderr, "[M::%s-id::%u] occ_0->%u, occ_1->%u, occ_2->%u, site->%u\n", __func__, overlap_list->list[hap->list[l].overlapID].y_id, s->occ_0, s->occ_1, s->occ_2, s->site);
                    // }
                }
            }
            // if(overlap_list->list[hap->list[l].overlapID].y_id == 4378830 || overlap_list->list[hap->list[l].overlapID].y_id == 4378829) {
            //  fprintf(stderr, "***1***[M::%s-id::%u] o->%lu, l->%lu\n", __func__, overlap_list->list[hap->list[l].overlapID].y_id, o, l);
            // }
            if(o == 0) continue;

            ii = hap->list[l].overlapID;
            if(overlap_list->list[ii].is_match == 1) overlap_list->list[ii].is_match = 2;
            for (i = l; i < hap->length && hap->list[i].overlapID == hap->list[l].overlapID; i++) {
                if(hh_tp(hap->list[i])==1){
                    s = &(hap->snp_stat.a[hap->list[i].overlapSite]);
                    s->score = 1; 
                } ///else if((hh_tp(hap->list[i])==0) && (o>=(overlap_list->list[ii].align_length*up))) {
                else if(hh_tp(hap->list[i])==0) {
                    ///not real allels
                    z = hap->list[i].overlapSite; s = &(hap->snp_stat.a[z]);
                    for (z = hap->list[i].overlapSite; z >= 0; z--) {
                        t = &(hap->snp_stat.a[z]);
                        if(s->site!=t->site) break;
                        // if(t->site == 14217) {
                        //     fprintf(stderr, "[M::%s]\tsite::%u\tn0::%u\tn1::%u\to::%lu\t%.*s\n", __func__, t->site, t->occ_0, t->occ_1, o, (int)Get_NAME_LENGTH(R_INF, overlap_list->list[ii].y_id), Get_NAME(R_INF, overlap_list->list[ii].y_id));
                        // }
                        t->occ_0 -= hap->list[i].cov;
                        assert(t->occ_0 >= 1);
                        if((st_max != ((uint64_t)-1)) && (overlap_list->list[ii].y_pos_strand == 0)) {
                            t->overlap_num -= hap->list[i].cov;
                            assert(t->overlap_num >= 1);
                        }
                    }
                }
            }
        }

        for (k = 0; k < hap->snp_srt.n; k++) {///sorted by how many allels in each overlap; more -> less
            o = 0; l = (uint32_t)hap->snp_srt.a[k];
            for (i = l; i < hap->length && hap->list[i].overlapID == hap->list[l].overlapID; i++) {
                if(hh_tp(hap->list[i])!=1) continue;
                s = &(hap->snp_stat.a[hap->list[i].overlapSite]);
                if(s->occ_0 < 2 || s->occ_1 < 2) continue;
                if(is_st_bs((*s), st_rate, st_max)) continue;
                if(s->score == 1) o++;
            }
            ii = hap->list[l].overlapID;
            ///for HiFi, do not flip trans to cis
            // if(overlap_list->list[ii].is_match == 2 && o == 0) {
            //     overlap_list->list[ii].is_match = 1;
            // }
            if(overlap_list->list[ii].is_match == 1 && o > 0) {
                overlap_list->list[ii].is_match = 2;
            }
        }


        for (k = 1, l = 0; k <= hap->length; ++k) {  ///reset snp_stat
            if (k == hap->length || hap->list[k].overlapID != hap->list[l].overlapID) {
                ii = hap->list[l].overlapID;
                if(overlap_list->list[ii].is_match==1) {
                    for (i = l; i < k; i++) {
                        if(hh_tp(hap->list[i])==1) {
                            hap->snp_stat.a[hap->list[i].overlapSite].score = -1;
                        }
                    }
                }
                l = k;
            }
        } 
    }

    
    if(multi_check) {
        hap->snp_srt.n = 0;
        for (k = 1, l = 0; k <= hap->length; ++k) {  
            if (k == hap->length || hap->list[k].overlapID != hap->list[l].overlapID) {
                if(overlap_list->list[hap->list[l].overlapID].is_match == 2) {
                    l = k;
                    continue;
                }
                for (i = l, o = 0; i < k; i++) {
                    if(hh_tp(hap->list[i])!=1) continue;
                    s = &(hap->snp_stat.a[hap->list[i].overlapSite]);
                    if(s->occ_0 < 2 || s->occ_1 < 2) continue;
                    if(is_st_bs((*s), st_rate, st_max)) continue;
                    if(s->occ_0 >= asm_opt.s_hap_cov && s->occ_1 >= asm_opt.infor_cov) continue;
                    if(s->score == 1) continue;
                    o++; 
                    kv_push(uint64_t, hap->snp_srt, hap->list[i].overlapSite);
                }
                // if(overlap_list->list[hap->list[l].overlapID].y_id == 317 || overlap_list->list[hap->list[l].overlapID].y_id == 287) {
                //     fprintf(stderr, "***2***[M::%s-id::%u] o->%lu\n", __func__, overlap_list->list[hap->list[l].overlapID].y_id, o);
                // }
                hap->snp_srt.n -= o;
                ///there are at least two variants at one read
                if(o>=(overlap_list->list[hap->list[l].overlapID].align_length*up)) {
                    radix_sort_bc64(hap->snp_srt.a + hap->snp_srt.n, hap->snp_srt.a + hap->snp_srt.n + o);
                    a = hap->snp_srt.a + hap->snp_srt.n;
                    for (i = z = 0; i < o; i++) {
                        if(i > 0) s = &(hap->snp_stat.a[a[i-1]]);
                        if(i + 1 < o) t = &(hap->snp_stat.a[a[i+1]]);
                        if(s && s->site + 32 > hap->snp_stat.a[a[i]].site) continue;
                        if(t && hap->snp_stat.a[a[i]].site + 32 > t->site) continue;
                        a[z] = a[i];
                        z++;
                    }
                    if(z >= 2) hap->snp_srt.n += z; 
                }
                l = k;
            }
        }
        if (hap->snp_srt.n > 0) {
            radix_sort_bc64(hap->snp_srt.a, hap->snp_srt.a + hap->snp_srt.n);
            for (k = 1, l = 0; k <= hap->snp_srt.n; ++k) {  
                if(k == hap->snp_srt.n || hap->snp_srt.a[k] != hap->snp_srt.a[l]) {
                    if(k - l >= 2) hap->snp_stat.a[hap->snp_srt.a[l]].score = 1;
                }
                l = k;
            }
        }
    }

    for (k = 1, l = 0; k <= hap->length; ++k) {  
        if (k == hap->length || hap->list[k].overlapID != hap->list[l].overlapID) {
            ii = hap->list[l].overlapID;
            if(overlap_list->list[ii].is_match==2) {
                overlap_list->list[ii].strong = 1;
                overlap_list->mapped_overlaps_length -= 
                                            overlap_list->list[ii].x_pos_e + 1 - overlap_list->list[ii].x_pos_s;
            } else if(overlap_list->list[ii].is_match==1) {
                for (i = l; i < k; i++) {
                    if(hh_tp(hap->list[i])==1 || hh_tp(hap->list[i])==0) {
                        s = &(hap->snp_stat.a[hap->list[i].overlapSite]);
                        if(s->score == 1 && (!(s->occ_0 < 2 || s->occ_1 < 2)) && (!(is_st_bs((*s), st_rate, st_max)))) {
                            overlap_list->list[ii].strong = 1;
                            if(hh_tp(hap->list[i])==1) {
                                overlap_list->list[ii].is_match = 2;
                                overlap_list->mapped_overlaps_length -= 
                                            overlap_list->list[ii].x_pos_e + 1 - overlap_list->list[ii].x_pos_s;
                                break;
                            }
                        }
                    }

                }
            }
            l = k;
        }
    }    
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x48, %rsp
movq %rsi, 0x18(%rsp)
cmpl $0x0, 0x10(%rdi)
je 0x52a4e
movq %rdi, %r14
movq 0x220(%rdi), %rbx
testq %rbx, %rbx
je 0x52154
movq %r8, (%rsp)
movl $0x1, %r13d
xorl %eax, %eax
xorl %edi, %edi
xorl %esi, %esi
xorl %edx, %edx
cmpq %rbx, %r13
je 0x51dd0
movq 0x218(%r14), %r9
leaq (,%r13,4), %r10
addq %r13, %r10
movl 0x20(%r9,%r10,8), %r10d
leaq (%rsi,%rsi,4), %r11
cmpl 0x20(%r9,%r11,8), %r10d
je 0x51f40
testq %rsi, %rsi
je 0x51def
movq 0x218(%r14), %r9
leaq (%rsi,%rsi,4), %r10
movl -0x8(%r9,%r10,8), %r11d
incl %r11d
cmpl %r11d, 0x20(%r9,%r10,8)
je 0x51e19
cmpq %rbx, %r13
jae 0x51e21
movq 0x218(%r14), %r8
leaq (%rsi,%rsi,4), %r9
movl 0x20(%r8,%r9,8), %r9d
incl %r9d
leaq (,%r13,4), %r10
addq %r13, %r10
cmpl 0x20(%r8,%r10,8), %r9d
jne 0x51e21
movq %r13, %rsi
jmp 0x51f40
movl 0x10(%r14), %r11d
cmpq %r11, %rdx
jae 0x52a5d
movq (%r14), %r8
movq 0x218(%r14), %r10
leaq (%rsi,%rsi,4), %r9
movl 0x20(%r10,%r9,8), %ebx
leaq (,%rdx,8), %r10
leaq (%r10,%r10,2), %r10
leaq (%r8,%r10), %r15
cmpl %ebx, (%r15)
je 0x51e6b
incq %rdx
addq $0x18, %r15
addq $0x18, %r10
cmpq %rdx, %r11
jne 0x51e51
jmp 0x52a5d
cmpq %r11, %rdx
jae 0x51ee2
movl %edi, %r11d
subl %esi, %r11d
leaq (,%rax,8), %rbx
leaq (%rbx,%rbx,2), %rbx
movl (%r8,%r10), %ebp
movq 0x218(%r14), %r15
cmpl 0x20(%r15,%r9,8), %ebp
jne 0x51ee2
movl 0x8(%r8,%r10), %r15d
cmpq %r15, %rsi
ja 0x52a7c
cmpq %r15, %r13
jbe 0x52a7c
leaq (%r8,%r10), %r15
movq 0x10(%r15), %r12
movq %r12, 0x10(%r8,%rbx)
movupd (%r15), %xmm2
movupd %xmm2, (%r8,%rbx)
movq (%r14), %r8
incq %rax
addl %r11d, 0x8(%r8,%rbx)
incq %rdx
movl 0x10(%r14), %r15d
addq $0x18, %rbx
addq $0x18, %r10
cmpq %r15, %rdx
jb 0x51e82
cmpq %r13, %rsi
jae 0x51f40
leaq (%rdi,%r13), %r8
subq %rsi, %r8
shlq $0x3, %rdi
leaq (%rdi,%rdi,4), %rdi
leaq (,%rsi,8), %r9
leaq (%r9,%r9,4), %r9
movq 0x218(%r14), %r10
movq 0x20(%r10,%r9), %r11
movq %r11, 0x20(%r10,%rdi)
movupd (%r10,%r9), %xmm3
movupd 0x10(%r10,%r9), %xmm2
movupd %xmm2, 0x10(%r10,%rdi)
movupd %xmm3, (%r10,%rdi)
incq %rsi
addq $0x28, %rdi
addq $0x28, %r9
cmpq %rsi, %r13
jne 0x51f02
movq %r8, %rdi
incq %r13
movq 0x220(%r14), %rbx
cmpq %rbx, %r13
jbe 0x51da5
movq %rdi, 0x220(%r14)
movl %eax, 0x10(%r14)
testq %rdi, %rdi
je 0x52a4e
testl %eax, %eax
je 0x52a4e
movq %rcx, 0x28(%rsp)
movsd %xmm0, 0x38(%rsp)
movsd %xmm1, 0x8(%rsp)
movq $0x0, 0x238(%r14)
movq (%r14), %rdi
movl %eax, %eax
leaq (%rax,%rax,2), %rax
leaq (%rdi,%rax,8), %rsi
callq 0x45897
movl 0x10(%r14), %eax
testq %rax, %rax
je 0x52161
movl $0x1, %ebp
xorl %r13d, %r13d
leaq 0x24379f(%rip), %r11    # 0x295758
movl %eax, %ebx
xorl %r12d, %r12d
cmpq %rax, %rbp
je 0x51fe3
movq (%r14), %rax
leaq (,%rbp,2), %rcx
addq %rbp, %rcx
movl 0x4(%rax,%rcx,8), %ecx
leaq (%r12,%r12,2), %rdx
cmpl 0x4(%rax,%rdx,8), %ecx
je 0x52140
cmpq %rbp, %r12
jae 0x5213d
movq (%r14), %rcx
movq 0x210(%r11), %rax
movq 0x218(%r11), %rdx
leaq (%r12,%r12,2), %rsi
leaq (%rcx,%rsi,8), %rsi
addq $0xc, %rsi
xorl %r15d, %r15d
movq %r12, %rcx
movq (%rsp), %r10
movsd 0x8(%rsp), %xmm3
testb $0x1, (%rsi)
je 0x52080
movq 0x218(%r14), %rdi
movl -0x4(%rsi), %r8d
leaq (%r8,%r8,4), %r8
movl 0x20(%rdi,%r8,8), %r9d
cmpl -0xc(%rsi), %r9d
jne 0x52aba
leaq (%rdi,%r8,8), %r13
movl 0x8(%r13), %r8d
cmpq $0x2, %r8
jb 0x52080
movl 0xc(%r13), %edi
cmpq $0x2, %rdi
jb 0x52080
cmpq $-0x1, %r10
je 0x5206e
movl 0x4(%r13), %r9d
movq (%rsp), %r10
addq %r9, %r10
cmpq %r8, %r10
movq (%rsp), %r10
jae 0x5208e
cmpq %r8, %rdx
jg 0x52080
xorl %r8d, %r8d
cmpq %rdi, %rax
setle %r8b
addq %r8, %r15
incq %rcx
addq $0x18, %rsi
cmpq %rcx, %rbp
jne 0x52019
jmp 0x520c3
xorps %xmm0, %xmm0
cvtsi2sd %r8, %xmm0
movl %r9d, %r9d
xorps %xmm1, %xmm1
cvtsi2sd %r9, %xmm1
movapd %xmm0, %xmm2
mulsd %xmm3, %xmm2
addsd %xmm1, %xmm2
ucomisd %xmm0, %xmm2
setae %r9b
cmpq %r8, %rdx
setg %r8b
orb %r9b, %r8b
je 0x52073
jmp 0x52080
testq %r15, %r15
je 0x5213d
movq 0x238(%r14), %rcx
movq 0x248(%r14), %rax
cmpq 0x240(%r14), %rcx
jne 0x5211a
leaq (%rcx,%rcx), %rsi
testq %rcx, %rcx
movl $0x2, %ecx
cmoveq %rcx, %rsi
movq %rsi, 0x240(%r14)
shlq $0x3, %rsi
movq %rax, %rdi
movq %r11, %rbx
callq 0x2370
movq %rbx, %r11
movq %rax, 0x248(%r14)
movq 0x238(%r14), %rcx
movl 0x10(%r14), %ebx
shlq $0x20, %r15
subq %r15, %r12
movabsq $-0x100000000, %rdx     # imm = 0xFFFFFFFF00000000
addq %rdx, %r12
leaq 0x1(%rcx), %rdx
movq %rdx, 0x238(%r14)
movq %r12, (%rax,%rcx,8)
movq %rbp, %r12
leaq 0x1(%rbp), %rcx
movl %ebx, %eax
cmpq %rax, %rbp
movq %rcx, %rbp
jb 0x51fbe
jmp 0x52166
movl $0x0, 0x10(%r14)
jmp 0x52a4e
xorl %ebx, %ebx
xorl %r13d, %r13d
movq 0x238(%r14), %rax
testq %rax, %rax
je 0x524af
movq 0x248(%r14), %rdi
leaq (%rdi,%rax,8), %rsi
callq 0x45373
movq 0x238(%r14), %rax
movl 0x10(%r14), %ebx
movq %rax, 0x10(%rsp)
testq %rax, %rax
je 0x524c0
movq 0x248(%r14), %r12
xorl %ebp, %ebp
xorl %edi, %edi
movsd 0x8(%rsp), %xmm3
movq %r12, 0x30(%rsp)
movl (%r12,%rdi,8), %r8d
cmpl %r8d, %ebx
jbe 0x52393
movq (%r14), %rax
leaq (%r8,%r8,2), %rcx
movq %rcx, 0x40(%rsp)
leaq (%rax,%rcx,8), %r10
addq $0xc, %r10
movl -0x8(%r10), %r11d
leaq 0x243577(%rip), %rax    # 0x295758
movq 0x210(%rax), %rcx
movq %rcx, 0x20(%rsp)
movq 0x218(%rax), %r12
movq %rbx, %rcx
subq %r8, %rcx
xorl %r15d, %r15d
cmpl %r11d, -0x8(%r10)
jne 0x5229a
testb $0x1, (%r10)
je 0x5225c
movq 0x218(%r14), %rax
movl -0x4(%r10), %edx
leaq (%rdx,%rdx,4), %rdx
leaq (%rax,%rdx,8), %r13
movl 0x8(%r13), %eax
cmpq $0x2, %rax
jb 0x5225c
movl 0xc(%r13), %edx
cmpq $0x2, %rdx
jb 0x5225c
movq (%rsp), %r9
cmpq $-0x1, %r9
je 0x5224a
movl 0x4(%r13), %esi
addq %rsi, %r9
cmpq %rax, %r9
jae 0x52267
cmpq %rax, %r12
jg 0x5225c
xorl %eax, %eax
cmpq %rdx, 0x20(%rsp)
setle %al
addq %rax, %r15
addq $0x18, %r10
decq %rcx
jne 0x521fd
jmp 0x5229a
xorps %xmm0, %xmm0
cvtsi2sd %rax, %xmm0
movl %esi, %esi
xorps %xmm1, %xmm1
cvtsi2sd %rsi, %xmm1
movapd %xmm0, %xmm2
mulsd %xmm3, %xmm2
addsd %xmm1, %xmm2
ucomisd %xmm0, %xmm2
setae %sil
cmpq %rax, %r12
setg %al
orb %sil, %al
je 0x5224f
jmp 0x5225c
testq %r15, %r15
je 0x5238e
movq (%r14), %r10
movq 0x40(%rsp), %rsi
movl 0x4(%r10,%rsi,8), %r11d
movq 0x18(%rsp), %rax
movq (%rax), %rax
imulq $0xa8, %r11, %rcx
cmpb $0x1, 0x2c(%rax,%rcx)
jne 0x522d1
leaq (%rax,%rcx), %rdx
addq $0x2c, %rdx
movb $0x2, (%rdx)
cmpl %r8d, %ebx
movq 0x30(%rsp), %r12
jbe 0x52393
cmpl %r11d, 0x4(%r10,%rsi,8)
jne 0x52393
addq %rax, %rcx
addq $0x1c, %rcx
leaq (%r10,%rsi,8), %rax
testb $0x1, 0xc(%rax)
jne 0x52358
movl 0x8(%rax), %r9d
movq 0x218(%r14), %rsi
leaq (%r9,%r9,4), %rax
leaq (%rsi,%rax,8), %r13
movl 0x20(%r13), %edx
leaq (%r8,%r8,2), %rax
leaq (%r10,%rax,8), %r15
addq $0x10, %r15
incq %r9
movq %r13, %rbp
cmpl 0x20(%rbp), %edx
jne 0x52372
movl (%r15), %eax
subl %eax, 0x8(%rbp)
je 0x52a9b
cmpq $-0x1, (%rsp)
je 0x5234a
cmpl $0x0, (%rcx)
jne 0x5234a
subl %eax, 0x4(%rbp)
je 0x52ad9
addq $-0x28, %rbp
decq %r9
jg 0x52324
movq %rsi, %rbp
jmp 0x52372
movq 0x218(%r14), %rdx
movl 0x8(%rax), %eax
leaq (%rax,%rax,4), %rax
leaq (%rdx,%rax,8), %r13
movl $0x1, 0x1c(%r13)
incq %r8
cmpq %rbx, %r8
je 0x52393
leaq (%r8,%r8,2), %rax
leaq (%r10,%rax,8), %rax
cmpl %r11d, 0x4(%rax)
je 0x522f5
jmp 0x52393
movq 0x30(%rsp), %r12
incq %rdi
cmpq 0x10(%rsp), %rdi
jne 0x521b5
movq 0x248(%r14), %rdx
movq (%r14), %rsi
movq 0x18(%rsp), %rax
movq (%rax), %rdi
leaq 0xc(%rsi), %rax
movq %rax, 0x20(%rsp)
xorl %r9d, %r9d
movq (%rsp), %r10
movl (%rdx,%r9,8), %eax
cmpl %eax, %ebx
jbe 0x5249f
leaq (,%rax,8), %rcx
leaq (%rcx,%rcx,2), %r10
movl 0x4(%rsi,%r10), %ecx
movq %rbx, %r15
subq %rax, %r15
addq 0x20(%rsp), %r10
xorl %r11d, %r11d
cmpl %ecx, -0x8(%r10)
jne 0x52478
testb $0x1, (%r10)
je 0x5246b
movq 0x218(%r14), %rax
movl -0x4(%r10), %r12d
leaq (%r12,%r12,4), %r12
leaq (%rax,%r12,8), %r13
movl 0x8(%r13), %eax
cmpq $0x2, %rax
jb 0x5246b
cmpl $0x2, 0xc(%r13)
jb 0x5246b
cmpq $-0x1, (%rsp)
je 0x5245e
movl 0x4(%r13), %r12d
movq (%rsp), %r8
addq %r12, %r8
cmpq %rax, %r8
jb 0x5245e
xorps %xmm0, %xmm0
cvtsi2sd %rax, %xmm0
movl %r12d, %eax
xorps %xmm1, %xmm1
cvtsi2sd %rax, %xmm1
movapd %xmm0, %xmm2
mulsd %xmm3, %xmm2
addsd %xmm1, %xmm2
ucomisd %xmm0, %xmm2
jae 0x5246b
xorl %eax, %eax
cmpl $0x1, 0x1c(%r13)
sete %al
addq %rax, %r11
addq $0x18, %r10
decq %r15
jne 0x523ee
imulq $0xa8, %rcx, %rax
cmpb $0x1, 0x2c(%rdi,%rax)
jne 0x5249b
testq %r11, %r11
movq (%rsp), %r10
je 0x5249f
addq %rdi, %rax
addq $0x2c, %rax
movb $0x2, (%rax)
jmp 0x5249f
movq (%rsp), %r10
incq %r9
cmpq 0x10(%rsp), %r9
jne 0x523c3
jmp 0x524cc
xorl %ebp, %ebp
movq (%rsp), %r10
movsd 0x8(%rsp), %xmm3
jmp 0x52579
xorl %ebp, %ebp
movq (%rsp), %r10
movsd 0x8(%rsp), %xmm3
testl %ebx, %ebx
je 0x528e3
movq (%r14), %rax
leaq 0xc(%rax), %rcx
movl $0x1, %edx
xorl %esi, %esi
leaq (%rsi,%rsi,2), %rdi
cmpq %rbx, %rdx
jne 0x524f2
movl 0x4(%rax,%rdi,8), %r8d
jmp 0x52507
leaq (%rdx,%rdx,2), %r9
movl 0x4(%rax,%rdi,8), %r8d
cmpl %r8d, 0x4(%rax,%r9,8)
jne 0x52507
movq %rsi, %r8
jmp 0x52566
movl %r8d, %r8d
movq 0x18(%rsp), %r9
movq (%r9), %r9
imulq $0xa8, %r8, %r8
cmpb $0x1, 0x2c(%r9,%r8)
sete %r8b
cmpq %rdx, %rsi
setb %r9b
andb %r8b, %r9b
movq %rdx, %r8
cmpb $0x1, %r9b
jne 0x52566
leaq (%rcx,%rdi,8), %rdi
testb $0x1, (%rdi)
je 0x52557
movq 0x218(%r14), %r8
movl -0x4(%rdi), %r9d
leaq (%r9,%r9,4), %r9
movl $0xffffffff, 0x1c(%r8,%r9,8) # imm = 0xFFFFFFFF
incq %rsi
addq $0x18, %rdi
cmpq %rsi, %rdx
jne 0x5253a
movq %rdx, %r8
leaq 0x1(%rdx), %rdi
movq %r8, %rsi
cmpq %rbx, %rdx
movq %rdi, %rdx
jne 0x524e2
cmpq $0x0, 0x28(%rsp)
je 0x528f6
movq $0x0, 0x238(%r14)
testl %ebx, %ebx
je 0x528f6
movl %ebx, %eax
movl $0x1, %ebx
xorl %r12d, %r12d
leaq 0x2431af(%rip), %r11    # 0x295758
movq (%r14), %rcx
leaq (%r12,%r12,2), %r8
cmpq %rax, %rbx
jne 0x525bc
movl 0x4(%rcx,%r8,8), %edx
jmp 0x525cf
leaq (%rbx,%rbx,2), %rax
movl 0x4(%rcx,%r8,8), %edx
cmpl %edx, 0x4(%rcx,%rax,8)
je 0x52893
movq 0x18(%rsp), %rax
movq (%rax), %rax
movl %edx, %edx
imulq $0xa8, %rdx, %rsi
cmpb $0x2, 0x2c(%rax,%rsi)
je 0x52890
cmpq %rbx, %r12
jae 0x52740
leaq (,%r12,8), %rax
leaq (%rax,%rax,2), %r15
movq $0x0, 0x10(%rsp)
testb $0x1, 0xc(%rcx,%r15)
je 0x5271c
movq 0x218(%r14), %rax
movl 0x8(%rcx,%r15), %edx
leaq (%rdx,%rdx,4), %rdx
leaq (%rax,%rdx,8), %r13
movl 0x8(%r13), %eax
cmpq $0x2, %rax
jb 0x5271c
movl 0xc(%r13), %edx
cmpq $0x2, %rdx
jb 0x5271c
cmpq $-0x1, %r10
je 0x52680
movl 0x4(%r13), %esi
leaq (%rsi,%r10), %rdi
cmpq %rax, %rdi
jb 0x52680
xorps %xmm0, %xmm0
cvtsi2sd %rax, %xmm0
movl %esi, %esi
xorps %xmm1, %xmm1
cvtsi2sd %rsi, %xmm1
movapd %xmm0, %xmm2
mulsd %xmm3, %xmm2
addsd %xmm1, %xmm2
ucomisd %xmm0, %xmm2
jae 0x5271c
cmpq %rax, 0x218(%r11)
jg 0x52696
cmpq %rdx, 0x210(%r11)
jle 0x5271c
cmpl $0x1, 0x1c(%r13)
je 0x5271c
movq 0x238(%r14), %rdx
movq 0x248(%r14), %rax
cmpq 0x240(%r14), %rdx
jne 0x52703
leaq (%rdx,%rdx), %rsi
testq %rdx, %rdx
movl $0x2, %ecx
cmoveq %rcx, %rsi
movq %rsi, 0x240(%r14)
shlq $0x3, %rsi
movq %rax, %rdi
movq %r8, 0x20(%rsp)
callq 0x2370
movq 0x20(%rsp), %r8
leaq 0x243070(%rip), %r11    # 0x295758
movsd 0x8(%rsp), %xmm3
movq (%rsp), %r10
movq %rax, 0x248(%r14)
movq (%r14), %rcx
movq 0x238(%r14), %rdx
incq 0x10(%rsp)
movl 0x8(%rcx,%r15), %esi
leaq 0x1(%rdx), %rdi
movq %rdi, 0x238(%r14)
movq %rsi, (%rax,%rdx,8)
incq %r12
addq $0x18, %r15
cmpq %r12, %rbx
jne 0x52609
movq 0x18(%rsp), %rax
movq (%rax), %rax
movl 0x4(%rcx,%r8,8), %edx
movq 0x10(%rsp), %r15
jmp 0x52743
xorl %r15d, %r15d
movq 0x238(%r14), %rcx
movq %rcx, %rsi
subq %r15, %rsi
movq %rsi, 0x238(%r14)
movq %r15, %xmm0
punpckldq 0x1deb1c(%rip), %xmm0 # xmm0 = xmm0[0],mem[0],xmm0[1],mem[1]
subpd 0x1deb24(%rip), %xmm0   # 0x231290
movapd %xmm0, %xmm1
unpckhpd %xmm0, %xmm1            # xmm1 = xmm1[1],xmm0[1]
imulq $0xa8, %rdx, %rdx
movl 0x28(%rax,%rdx), %eax
xorps %xmm2, %xmm2
cvtsi2sd %rax, %xmm2
addsd %xmm0, %xmm1
mulsd 0x38(%rsp), %xmm2
ucomisd %xmm2, %xmm1
jb 0x52890
movq 0x248(%r14), %rax
leaq (%rax,%rsi,8), %rdi
leaq (%rax,%rcx,8), %rsi
callq 0x45373
testq %r15, %r15
je 0x528a9
movq 0x238(%r14), %rax
shlq $0x3, %rax
addq 0x248(%r14), %rax
movq %r15, %rcx
negq %rcx
movl $0x1, %edx
xorl %esi, %esi
movq (%rsp), %r10
movsd 0x8(%rsp), %xmm3
leaq 0x242f70(%rip), %r11    # 0x295758
cmpq $0x1, %rdx
je 0x52802
movq -0x10(%rax,%rdx,8), %rdi
leaq (%rdi,%rdi,4), %r13
shlq $0x3, %r13
addq 0x218(%r14), %r13
cmpq %r15, %rdx
jae 0x5281a
movq (%rax,%rdx,8), %rdi
leaq (%rdi,%rdi,4), %rbp
shlq $0x3, %rbp
addq 0x218(%r14), %rbp
testq %r13, %r13
je 0x5283d
movl 0x20(%r13), %edi
addl $0x20, %edi
movq 0x218(%r14), %r8
movq -0x8(%rax,%rdx,8), %r9
leaq (%r9,%r9,4), %r9
cmpl 0x20(%r8,%r9,8), %edi
ja 0x5286f
testq %rbp, %rbp
je 0x52863
movq 0x218(%r14), %r8
movq -0x8(%rax,%rdx,8), %rdi
leaq (%rdi,%rdi,4), %r9
movl 0x20(%r8,%r9,8), %r8d
addl $0x20, %r8d
cmpl 0x20(%rbp), %r8d
jbe 0x52868
jmp 0x5286f
movq -0x8(%rax,%rdx,8), %rdi
movq %rdi, (%rax,%rsi,8)
incq %rsi
leaq (%rcx,%rdx), %rdi
incq %rdi
incq %rdx
cmpq $0x1, %rdi
jne 0x527e8
cmpq $0x2, %rsi
jl 0x52890
addq %rsi, 0x238(%r14)
movq %rbx, %r12
leaq 0x1(%rbx), %rcx
movl 0x10(%r14), %eax
cmpq %rax, %rbx
movq %rcx, %rbx
jb 0x525a9
jmp 0x528bf
movq %rbx, %r12
movq (%rsp), %r10
movsd 0x8(%rsp), %xmm3
leaq 0x242e9b(%rip), %r11    # 0x295758
jmp 0x52893
movq 0x238(%r14), %rax
testq %rax, %rax
je 0x528f6
movq 0x248(%r14), %rdi
leaq (%rdi,%rax,8), %rsi
callq 0x45373
movsd 0x8(%rsp), %xmm3
jmp 0x528f6
cmpq $0x0, 0x28(%rsp)
je 0x528f6
movq $0x0, 0x238(%r14)
movl 0x10(%r14), %eax
testq %rax, %rax
je 0x52a4e
movq (%r14), %rcx
leaq 0xc(%rcx), %rdx
movq %rdx, 0x10(%rsp)
movl $0x1, %esi
xorl %edi, %edi
cmpq %rax, %rsi
jne 0x52926
leaq (%rdi,%rdi,2), %r8
movl 0x4(%rcx,%r8,8), %r8d
jmp 0x52942
leaq (%rsi,%rsi,2), %r9
leaq (%rdi,%rdi,2), %r8
movl 0x4(%rcx,%r8,8), %r8d
cmpl %r8d, 0x4(%rcx,%r9,8)
jne 0x52942
movq %rdi, %r11
jmp 0x52a31
movl %r8d, %r8d
movq 0x18(%rsp), %rdx
movq (%rdx), %r9
imulq $0xa8, %r8, %r10
leaq (%r9,%r10), %r8
movzbl 0x2c(%r9,%r10), %ebx
cmpl $0x2, %ebx
je 0x52a16
movq %rsi, %r11
cmpl $0x1, %ebx
jne 0x52a31
movq %rsi, %r11
cmpq %rsi, %rdi
jae 0x52a31
movq 0x218(%r14), %r11
leaq (%r9,%r10), %rbx
addq $0x2e, %rbx
leaq (%rdi,%rdi,2), %r15
movq 0x10(%rsp), %rdx
leaq (%rdx,%r15,8), %r15
movl -0x4(%r15), %r12d
leaq (%r12,%r12,4), %r12
cmpl $0x1, 0x1c(%r11,%r12,8)
jne 0x52a08
leaq (%r11,%r12,8), %r13
movl 0x8(%r13), %r12d
cmpq $0x2, %r12
jb 0x52a08
cmpl $0x2, 0xc(%r13)
jb 0x52a08
movb (%r15), %bpl
cmpq $-0x1, (%rsp)
je 0x529ff
movl 0x4(%r13), %r13d
movq (%rsp), %rdx
addq %r13, %rdx
cmpq %r12, %rdx
jb 0x529ff
xorps %xmm0, %xmm0
cvtsi2sd %r12, %xmm0
movl %r13d, %edx
xorps %xmm1, %xmm1
cvtsi2sd %rdx, %xmm1
movapd %xmm0, %xmm2
mulsd %xmm3, %xmm2
addsd %xmm1, %xmm2
ucomisd %xmm0, %xmm2
jae 0x52a08
movb $0x1, (%rbx)
testb $0x1, %bpl
jne 0x52a46
incq %rdi
addq $0x18, %r15
cmpq %rdi, %rsi
jne 0x5299b
jmp 0x52a2e
movb $0x1, 0x2e(%r8)
movl 0x8(%r8), %edx
subl 0x4(%r8), %edx
incl %edx
movq 0x18(%rsp), %rdi
subq %rdx, 0x18(%rdi)
movq %rsi, %r11
leaq 0x1(%rsi), %rdx
movq %r11, %rdi
cmpq %rax, %rsi
movq %rdx, %rsi
jne 0x52916
jmp 0x52a4e
movb $0x2, 0x2c(%r9,%r10)
jmp 0x52a1b
addq $0x48, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
leaq 0x1df2a4(%rip), %rdi    # 0x231d08
leaq 0x1dece8(%rip), %rsi    # 0x231753
leaq 0x1df2d6(%rip), %rcx    # 0x231d48
movl $0x229f, %edx           # imm = 0x229F
callq 0x2110
leaq 0x1df34c(%rip), %rdi    # 0x231dcf
leaq 0x1decc9(%rip), %rsi    # 0x231753
leaq 0x1df2b7(%rip), %rcx    # 0x231d48
movl $0x22a2, %edx           # imm = 0x22A2
callq 0x2110
leaq 0x1df1a8(%rip), %rdi    # 0x231c4a
leaq 0x1decaa(%rip), %rsi    # 0x231753
leaq 0x1df298(%rip), %rcx    # 0x231d48
movl $0x231d, %edx           # imm = 0x231D
callq 0x2110
leaq 0x1df34a(%rip), %rdi    # 0x231e0b
leaq 0x1dec8b(%rip), %rsi    # 0x231753
leaq 0x1df279(%rip), %rcx    # 0x231d48
movl $0x22c0, %edx           # imm = 0x22C0
callq 0x2110
leaq 0x1df348(%rip), %rdi    # 0x231e28
leaq 0x1dec6c(%rip), %rsi    # 0x231753
leaq 0x1df25a(%rip), %rcx    # 0x231d48
movl $0x2320, %edx           # imm = 0x2320
callq 0x2110