// File: chhylp123[P]hifiasm/inter.cpp
// Function: hc_shortest_k(void*, asg_t const*, unsigned int, int, mg_path_dst_t*, int, int, st_mt_t*, unsigned long*, vec_sp_node_t*, vec_mg_pathv_t*, unsigned long, unsigned long, float)
void hc_shortest_k(void *km0, const asg_t *g, uint32_t src, int32_t n_dst, mg_path_dst_t *dst, int32_t max_dist, int32_t max_k, 
st_mt_t *dst_done, uint64_t *dst_group, vec_sp_node_t *out, vec_mg_pathv_t *res, uint64_t first_src_ban, 
uint64_t detect_mul_way, float len_dif)
{
    sp_node_t *p, *root = 0;
    sp_topk_t *q;
    khash_t(sp) *h;///
    khash_t(sp2) *h2;///alignment->vertice index
    void *km;
    khint_t k;
    int absent;
    int32_t i, j, n_done, n_found;
    uint32_t id;

    // if (res) res->n = 0;///for us, n_pathv = NULL
    if (n_dst <= 0) return;///n_dst: how many candidate vertices
    for (i = 0; i < n_dst; ++i) { // initialize
        mg_path_dst_t *t = &dst[i];
        ///if src and dest are at the same ref id, there are already one path
        if (t->inner)///if two chains are at the same ref id
            t->dist = 0, t->n_path = 1, t->path_end = -1;
        else
            t->dist = -1, t->n_path = 0, t->path_end = -1;
    }
    if (max_k > MG_MAX_SHORT_K) max_k = MG_MAX_SHORT_K;
    km = km_init2(km0, 0x4000);

    // multiple dst[] may have the same dst[].v. We need to group them first.
    // in other words, one ref id may have multiple dst alignment chains
	dst_done->n = 0; kv_resize(uint64_t, *dst_done, (uint64_t)n_dst);
    for (i = 0; i < n_dst; ++i) {
		dst_group[i] = ((((uint64_t)dst[i].v)<<32)|((uint64_t)i));
		dst_done->a[i] = 0;
	}
        
    radix_sort_gfa64(dst_group, dst_group + n_dst);

    h2 = kh_init2(sp2, km); // (h2+dst_group) keeps all destinations from the same ref id
    kh_resize(sp2, h2, n_dst * 2);
    ///please note that one contig in ref may have multiple alignment chains
    ///so h2 is a index that helps us to query it
    ///key(h2) = ref id; value(h2) = start_idx | occ
    for (i = 1, j = 0; i <= n_dst; ++i) {
        if (i == n_dst || dst_group[i]>>32 != dst_group[j]>>32) {
            k = kh_put(sp2, h2, dst_group[j]>>32, &absent);
            kh_val(h2, k) = (((uint64_t)j)<<32)|((uint64_t)(i-j));
            assert(absent);
            j = i;
        }
    }

    h = kh_init2(sp, km); // h keeps visited vertices; path to each visited vertice
    kh_resize(sp, h, 16);

	out->n = 0; kv_resize(sp_node_t*, *out, 16); ///16 is just the initial size    
    id = 0;
    p = gen_sp_node(km, src, 0, id++);///just malloc a node for src; the distance is 0
    p->hash = __ac_Wang_hash(src);///hash is path hash, instead of node hash
    kavl_insert(sp, &root, p, 0);///should be avl tree; p is a node at avl-tree

    ///each cell in the hash table <h> corresponds to one node in the graph
	///each cell in the AVL tree <root> is a path, corresponds to <MG_MAX_SHORT_K> node in the graph
    k = kh_put(sp, h, src, &absent);
    q = &kh_val(h, k);
    ///for normal graph traversal, one node just has one parental node; here each node has at most 16 parental nodes
    q->k = 1, q->p[0] = p, q->mlen = 0, q->qs = q->qe = -1;

    n_done = 0; first_src_ban = first_src_ban?0:1;
    ///the key of avl tree: #define sp_node_cmp(a, b) (((a)->di > (b)->di) - ((a)->di < (b)->di))
    ///the higher bits of (*)->di is distance to src node
    ///so the key of avl tree is distance
    ///in avl tree <root>, one node might be saved multipe times
    while (kavl_size(head, root) > 0) {///thr first root is src
        int32_t i, nv;
        asg_arc_t *av;
        sp_node_t *r;
        ///note that one node in the graph (sp_node_t->v) might be visited multiple times if there are circles
        ///so there might be multipe cells in the avl-tree with the same (sp_node_t->v)
        ///delete the first cell
        r = kavl_erase_first(sp, &root); // take out the closest vertex in the heap (as a binary tree)
        //fprintf(stderr, "XX\t%d\t%d\t%d\t%c%s[%d]\t%d\n", n_out, kavl_size(head, root), n_finished, "><"[(r->v&1)^1], g->seg[r->v>>1].name, r->v, (int32_t)(r->di>>32));
        
		///higher 32 bits might be the distance to root node
        // lower 32 bits now for position in the out[] array
		///r->pre keep the pre-node in the path; follow the pre it is able to recover the whole path
        r->di = ((r->di>>32)<<32)|((uint64_t)out->n); ///n_out is just the id in out
        ///so one node id in graph might be saved multiple times in avl tree and out[]
		kv_push(sp_node_t*, *out, r);

        ///r->v is the dst vertex id
        ///sometimes k==kh_end(h2). Some nodes are found by graph travesal but not in linear chain alignment
        k = kh_get(sp2, h2, r->v);
        // we have reached one dst vertex
        // note that one dst vertex may have multipe alignment chains
        // we can visit some nodes in graph which are not reachable during chaining
        // h2 is used to determine if one node is reachable or not
		// if(src == 2844) {
		// 	fprintf(stderr, "******src->%u, dst->%u, max_dist->%d\n", src, r->v, max_dist);
		// }
        if (k != kh_end(h2) && first_src_ban) { 
            ///node r->v might be visited multiple times
            int32_t j, dist = r->di>>32, off = kh_val(h2, k) >> 32, cnt = (int32_t)kh_val(h2, k);
			// if(src == 2844) {
			// 	fprintf(stderr, "----src->%u, dst->%u, max_dist->%d, cnt->%d\n", src, r->v, max_dist, cnt);
			// }
            //src can reach ref id r->v; there might be not only one alignment chain in r->v
            //so we need to scan all of them
            for (j = 0; j < cnt; ++j) {
                mg_path_dst_t *t = &dst[(int32_t)dst_group[off + j]];///t is a linear alignment at r->v
                int32_t done = 0;
				// if((src>>1) == 51) {
				// 	fprintf(stderr, "###src->%u, dst->%u, max_dist->%d, dist:%d\n", src, r->v, max_dist, dist);
				// }
                ///the src and dest are at the same ref id, say we directly find the shortest path
                if (t->inner) {
                    done = 1;
                } else {
                    int32_t mlen = 0, copy = 0;
                    ///in the first round, we just check reachability without sequence
                    ///so h_seeds = NULL; we can assume mlen = 0
                    /** //path
                    mlen = h_seeds? path_mlen(out, n_out - 1, h, t->qlen) : 0;
                    **/
				   // means this alignment has never been visited before; keep it anyway
				   // note here is the alignment, instead of node
					
				    // if(src == 2844) {
					// 	fprintf(stderr, ">>src->%u, dst->%u, target_dist->%d, dist->%d, max_dist->%d\n", 
					// 	src, r->v, t->target_dist, dist, max_dist);
					// }
                    if (t->n_path == 0) { 
                        copy = 1;
                     // we have a target distance; choose the closest; 
                     // there is already several paths reaching the linear alignment <t>
                    } else if (t->target_dist >= 0) { 
                        // we found the target path; hash is the path hash including multiple nodes, instead of node hash 
                        if (dist == t->target_dist && t->check_hash && r->hash == t->target_hash) { 
                            copy = 1, done = 1;
                        } else {
                            int32_t d0 = t->dist, d1 = dist;
                            d0 = d0 > t->target_dist? d0 - t->target_dist : t->target_dist - d0;
                            d1 = d1 > t->target_dist? d1 - t->target_dist : t->target_dist - d1;
                            ///if the new distance (d1) is smaller than the old distance (d0), update the results
                            ///the length of new path should be closer to t->target_dist
                            if (d1 - mlen/2 < d0 - t->mlen/2) copy = 1;
                        }
                    }
                    if (copy) {
                        t->path_end = out->n-1, t->dist = dist, t->hash = r->hash, t->mlen = mlen, t->is_0 = r->is_0;
                        if (t->target_dist >= 0) {
                            ///src is from li from li to lj, so the dis is generally increased; dijkstra algorithm
                            ///target_dist should be the distance on query
                            if (dist == t->target_dist && t->check_hash && r->hash == t->target_hash) {
								done = 1;
							} else if ((dist > t->target_dist + MG_SHORT_K_EXT) && (dist > (t->target_dist>>4)) && 
								(dist > (t->target_dist*1.25))) {
								done = 1;
							}
                        }
                    }
                    ++t->n_path;///we found a path to the alignment t
                    if (t->n_path >= max_k) done = 1;
                }
                if (detect_mul_way == 0 && dst_done->a[off + j] == 0 && done)
                    dst_done->a[off + j] = 1, ++n_done;
            }
            ///if all alignments have been settle down
            ///pre-end; accelerate the loop
            if (n_done == n_dst) break;
        }
		first_src_ban = 1;
        ///below is used to push new nodes to avl tree for iteration
        nv = asg_arc_n(g, r->v);
        av = asg_arc_a(g, r->v);
        for (i = 0; i < nv; ++i) { // visit all neighbors
            asg_arc_t *ai = &av[i];
            ///v_lv is the (dest_length - overlap_length); it is a normal path length in string graph
            ///ai->v_lv is the path length from r->v to ai->w
            ///(r->di>>32)
            int32_t d = (r->di>>32) + (uint32_t)ai->ul;
            if (d > max_dist) continue; // don't probe vertices too far away
            // h keeps visited vertices; path to each visited vertice
            ///ai->w is the dest ref id; we insert a new ref id, instead of an alignment chain
            k = kh_put(sp, h, ai->v, &absent);///one node might be visited multiple times
            q = &kh_val(h, k);
            if (absent) { // a new vertex visited
                ///q->k: number of walks from src to ai->w
                q->k = 0, q->qs = q->qe = -1; q->mlen = 0;
                ///h_seeds = NULL; so q->mlen = 0
                /** //path
                q->mlen = h_seeds && d + gfa_arc_lw(g, *ai) <= max_dist? node_mlen(km, g, ai->w, &mini, h_seeds, n_seeds, seeds, &q->qs, &q->qe) : 0;
                **/
                //if (ql && qs) fprintf(stderr, "ql=%d,src=%d\tv=%c%s[%d],n_seeds=%d,mlen=%d\n", ql, src, "><"[ai->w&1], g->seg[ai->w>>1].name, ai->w, n_seeds, q->mlen);
            }
            ///if there are less than <max_k> walks from src to ai->w, directly add
            ///if there are more, keep the smallest <max_k> walks
            if (q->k < max_k) { // enough room: add to the heap
                p = gen_sp_node(km, ai->v, d, id++);
                p->pre = out->n - 1;///the parent node of this one 
                p->hash = r->hash + __ac_Wang_hash(ai->v);
                p->is_0 = r->is_0;
                /** //path
                if (ai->rank > 0) p->is_0 = 0;
                **/
                kavl_insert(sp, &root, p, 0);
                q->p[q->k++] = p;
                ks_heapup_sp(q->k, q->p);///adjust heap by distance
            } else if ((int32_t)(q->p[0]->di>>32) > d) { // shorter than the longest path so far: replace the longest
                p = kavl_erase(sp, &root, q->p[0], 0);
                if (p) {
                    p->di = (uint64_t)d<<32 | (id++);
                    p->pre = out->n - 1;
                    p->hash = r->hash + __ac_Wang_hash(ai->v);
                    p->is_0 = r->is_0;
                    /** //path
                    if (ai->rank > 0) p->is_0 = 0;
                    **/
                    kavl_insert(sp, &root, p, 0);
                    ks_heapdown_sp(0, q->k, q->p);
                } else {
                    fprintf(stderr, "Warning: logical bug in gfa_shortest_k(): q->k=%d,q->p[0]->{d,i}={%d,%d},d=%d,src=%u,max_dist=%d,n_dst=%d\n", q->k, (int32_t)(q->p[0]->di>>32), (int32_t)q->p[0]->di, d, src, max_dist, n_dst);
                    km_destroy(km);
                    return;
                }
            } // else: the path is longer than all the existing paths ended at ai->w
        }
    }
    kh_destroy(sp, h);
    // NB: AVL nodes are not deallocated. When km==0, they are memory leaks.

    for (i = 0, n_found = 0; i < n_dst; ++i)
        if (dst[i].n_path > 0) ++n_found;///n_path might be larger than 16
    ///we can assume n_pathv = NULL for now 
    if (n_found > 0 && res) { // then generate the backtrack array
        int32_t n, n_mpath = 1; dst_done->n = 0; kv_resize(uint64_t, *dst_done, out->n); 
		uint64_t *trans = dst_done->a; memset(dst_done->a, 0, out->n*sizeof(*(dst_done->a)));

		if(detect_mul_way) {
			n_mpath = phase_mul_ways(res, dst_done, out, n_dst, dst, max_k, len_dif);
		}
		
		if(n_mpath == 1) {
			// KCALLOC(km, trans, n_out); // used to squeeze unused elements in out[]
			///n_out: how many times that nodes in graph have been visited 
			///note one node might be visited multiples times
			///n_dst: number of alignment chains
			for (i = 0; i < n_dst; ++i) { // mark dst vertices with a target distance
				mg_path_dst_t *t = &dst[i];
				if (t->n_path > 0 && t->target_dist >= 0 && t->path_end >= 0)
					trans[(uint32_t)out->a[t->path_end]->di] = 1;///(int32_t)out[]->di: traverse track corresponds to the alignment chain dst[]
			}
			// for (i = 0; (uint32_t)i < out->n; ++i) { // mark dst vertices without a target distance
			//     k = kh_get(sp2, h2, out->a[i]->v);
			//     if (k != kh_end(h2)) { // TODO: check if this is correct!
			//         int32_t off = kh_val(h2, k)>>32, cnt = (int32_t)kh_val(h2, k);
			//         for (j = off; j < off + cnt; ++j)
			//             if (dst[j].target_dist < 0)
			//                 trans[i] = 1;
			//     }
			// }
			for (i = (int32_t)(out->n) - 1; i >= 0; --i) // mark all predecessors
				if (trans[i] && out->a[i]->pre >= 0)
					trans[out->a[i]->pre] = 1;
			for (i = n = 0; (uint32_t)i < out->n; ++i) // generate coordinate translations
				if (trans[i]) trans[i] = n++;
				else trans[i] = (uint32_t)-1;
			
			kv_resize(mg_pathv_t, *res, res->n + n); //res->n += n;
			for (i = 0; (uint32_t)i < out->n; ++i) { // generate the backtrack array
				mg_pathv_t *p;
				if (trans[i] == (uint32_t)-1) continue;
				p = &res->a[trans[i]+res->n];
				p->v = out->a[i]->v, p->d = out->a[i]->di >> 32;
				p->pre = out->a[i]->pre < 0? out->a[i]->pre:trans[out->a[i]->pre];
			}
			res->n += n;
			for (i = 0; i < n_dst; ++i) // translate "path_end"
				if (dst[i].path_end >= 0)
					dst[i].path_end = trans[dst[i].path_end];
		}
    }

    km_destroy(km);
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x140, %rsp            # imm = 0x140
movq 0x40(%rbp), %rax
movq 0x38(%rbp), %rax
movq 0x30(%rbp), %rax
movq 0x28(%rbp), %rax
movq 0x20(%rbp), %rax
movq 0x18(%rbp), %rax
movl 0x10(%rbp), %eax
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movl %edx, -0x14(%rbp)
movl %ecx, -0x18(%rbp)
movq %r8, -0x20(%rbp)
movl %r9d, -0x24(%rbp)
movss %xmm0, -0x28(%rbp)
movq $0x0, -0x38(%rbp)
cmpl $0x0, -0x18(%rbp)
jg 0x29bec4
jmp 0x29d22f
movl $0x0, -0x64(%rbp)
movl -0x64(%rbp), %eax
cmpl -0x18(%rbp), %eax
jge 0x29bf5d
movq -0x20(%rbp), %rax
movslq -0x64(%rbp), %rcx
imulq $0x30, %rcx, %rcx
addq %rcx, %rax
movq %rax, -0x80(%rbp)
movq -0x80(%rbp), %rax
movl 0xc(%rax), %eax
shrl $0x1f, %eax
cmpl $0x0, %eax
je 0x29bf24
movq -0x80(%rbp), %rax
movl $0x0, 0x1c(%rax)
movq -0x80(%rbp), %rax
movl 0x14(%rax), %ecx
andl $0x80000000, %ecx       # imm = 0x80000000
orl $0x1, %ecx
movl %ecx, 0x14(%rax)
movq -0x80(%rbp), %rax
movl $0xffffffff, 0x18(%rax) # imm = 0xFFFFFFFF
jmp 0x29bf4d
movq -0x80(%rbp), %rax
movl $0xffffffff, 0x1c(%rax) # imm = 0xFFFFFFFF
movq -0x80(%rbp), %rax
movl 0x14(%rax), %ecx
andl $0x80000000, %ecx       # imm = 0x80000000
orl $0x0, %ecx
movl %ecx, 0x14(%rax)
movq -0x80(%rbp), %rax
movl $0xffffffff, 0x18(%rax) # imm = 0xFFFFFFFF
jmp 0x29bf4f
movl -0x64(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x64(%rbp)
jmp 0x29becb
cmpl $0xf, 0x10(%rbp)
jle 0x29bf6a
movl $0xf, 0x10(%rbp)
movq -0x8(%rbp), %rdi
movl $0x4000, %esi           # imm = 0x4000
callq 0x30e130
movq %rax, -0x58(%rbp)
movq 0x18(%rbp), %rax
movq $0x0, (%rax)
movq 0x18(%rbp), %rax
movq 0x8(%rax), %rax
movslq -0x18(%rbp), %rcx
cmpq %rcx, %rax
jae 0x29c063
movslq -0x18(%rbp), %rcx
movq 0x18(%rbp), %rax
movq %rcx, 0x8(%rax)
movq 0x18(%rbp), %rax
movq 0x8(%rax), %rcx
addq $-0x1, %rcx
movq %rcx, 0x8(%rax)
movq 0x18(%rbp), %rax
movq 0x8(%rax), %rcx
shrq %rcx
movq 0x18(%rbp), %rax
orq 0x8(%rax), %rcx
movq %rcx, 0x8(%rax)
movq 0x18(%rbp), %rax
movq 0x8(%rax), %rcx
shrq $0x2, %rcx
movq 0x18(%rbp), %rax
orq 0x8(%rax), %rcx
movq %rcx, 0x8(%rax)
movq 0x18(%rbp), %rax
movq 0x8(%rax), %rcx
shrq $0x4, %rcx
movq 0x18(%rbp), %rax
orq 0x8(%rax), %rcx
movq %rcx, 0x8(%rax)
movq 0x18(%rbp), %rax
movq 0x8(%rax), %rcx
shrq $0x8, %rcx
movq 0x18(%rbp), %rax
orq 0x8(%rax), %rcx
movq %rcx, 0x8(%rax)
movq 0x18(%rbp), %rax
movq 0x8(%rax), %rcx
shrq $0x10, %rcx
movq 0x18(%rbp), %rax
orq 0x8(%rax), %rcx
movq %rcx, 0x8(%rax)
movq 0x18(%rbp), %rax
movq 0x8(%rax), %rcx
addq $0x1, %rcx
movq %rcx, 0x8(%rax)
movq 0x18(%rbp), %rax
movq 0x10(%rax), %rdi
movq 0x18(%rbp), %rax
movq 0x8(%rax), %rsi
shlq $0x3, %rsi
callq 0x2360
movq %rax, %rcx
movq 0x18(%rbp), %rax
movq %rcx, 0x10(%rax)
jmp 0x29c065
movl $0x0, -0x64(%rbp)
movl -0x64(%rbp), %eax
cmpl -0x18(%rbp), %eax
jge 0x29c0bd
movq -0x20(%rbp), %rax
movslq -0x64(%rbp), %rcx
imulq $0x30, %rcx, %rcx
addq %rcx, %rax
movl (%rax), %eax
movl %eax, %edx
shlq $0x20, %rdx
movslq -0x64(%rbp), %rax
orq %rax, %rdx
movq 0x20(%rbp), %rax
movslq -0x64(%rbp), %rcx
movq %rdx, (%rax,%rcx,8)
movq 0x18(%rbp), %rax
movq 0x10(%rax), %rax
movslq -0x64(%rbp), %rcx
movq $0x0, (%rax,%rcx,8)
movl -0x64(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x64(%rbp)
jmp 0x29c06c
movq 0x20(%rbp), %rdi
movq 0x20(%rbp), %rsi
movslq -0x18(%rbp), %rax
shlq $0x3, %rax
addq %rax, %rsi
callq 0x27a9b0
movq -0x58(%rbp), %rdi
callq 0x286060
movq %rax, -0x50(%rbp)
movq -0x50(%rbp), %rdi
movl -0x18(%rbp), %esi
shll %esi
callq 0x2860a0
movl $0x1, -0x64(%rbp)
movl $0x0, -0x68(%rbp)
movl -0x64(%rbp), %eax
cmpl -0x18(%rbp), %eax
jg 0x29c1b8
movl -0x64(%rbp), %eax
cmpl -0x18(%rbp), %eax
je 0x29c137
movq 0x20(%rbp), %rax
movslq -0x64(%rbp), %rcx
movq (%rax,%rcx,8), %rax
shrq $0x20, %rax
movq 0x20(%rbp), %rcx
movslq -0x68(%rbp), %rdx
movq (%rcx,%rdx,8), %rcx
shrq $0x20, %rcx
cmpq %rcx, %rax
je 0x29c1a8
movq -0x50(%rbp), %rdi
movq 0x20(%rbp), %rax
movslq -0x68(%rbp), %rcx
movq (%rax,%rcx,8), %rax
shrq $0x20, %rax
movl %eax, %esi
leaq -0x60(%rbp), %rdx
callq 0x286590
movl %eax, -0x5c(%rbp)
movslq -0x68(%rbp), %rdx
shlq $0x20, %rdx
movl -0x64(%rbp), %eax
subl -0x68(%rbp), %eax
cltq
orq %rax, %rdx
movq -0x50(%rbp), %rax
movq 0x20(%rax), %rax
movl -0x5c(%rbp), %ecx
movq %rdx, (%rax,%rcx,8)
cmpl $0x0, -0x60(%rbp)
je 0x29c183
jmp 0x29c1a2
leaq 0xf479c(%rip), %rdi     # 0x390926
leaq 0xf469e(%rip), %rsi     # 0x39082f
movl $0x3702, %edx           # imm = 0x3702
leaq 0xf6e65(%rip), %rcx     # 0x393002
callq 0x2130
movl -0x64(%rbp), %eax
movl %eax, -0x68(%rbp)
jmp 0x29c1aa
movl -0x64(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x64(%rbp)
jmp 0x29c0fe
movq -0x58(%rbp), %rdi
callq 0x2868e0
movq %rax, -0x48(%rbp)
movq -0x48(%rbp), %rdi
movl $0x10, %esi
callq 0x286920
movq 0x28(%rbp), %rax
movq $0x0, 0x8(%rax)
movq 0x28(%rbp), %rax
cmpq $0x10, 0x10(%rax)
jae 0x29c2b3
movq 0x28(%rbp), %rax
movq $0x10, 0x10(%rax)
movq 0x28(%rbp), %rax
movq 0x10(%rax), %rcx
addq $-0x1, %rcx
movq %rcx, 0x10(%rax)
movq 0x28(%rbp), %rax
movq 0x10(%rax), %rcx
shrq %rcx
movq 0x28(%rbp), %rax
orq 0x10(%rax), %rcx
movq %rcx, 0x10(%rax)
movq 0x28(%rbp), %rax
movq 0x10(%rax), %rcx
shrq $0x2, %rcx
movq 0x28(%rbp), %rax
orq 0x10(%rax), %rcx
movq %rcx, 0x10(%rax)
movq 0x28(%rbp), %rax
movq 0x10(%rax), %rcx
shrq $0x4, %rcx
movq 0x28(%rbp), %rax
orq 0x10(%rax), %rcx
movq %rcx, 0x10(%rax)
movq 0x28(%rbp), %rax
movq 0x10(%rax), %rcx
shrq $0x8, %rcx
movq 0x28(%rbp), %rax
orq 0x10(%rax), %rcx
movq %rcx, 0x10(%rax)
movq 0x28(%rbp), %rax
movq 0x10(%rax), %rcx
shrq $0x10, %rcx
movq 0x28(%rbp), %rax
orq 0x10(%rax), %rcx
movq %rcx, 0x10(%rax)
movq 0x28(%rbp), %rax
movq 0x10(%rax), %rcx
addq $0x1, %rcx
movq %rcx, 0x10(%rax)
movq 0x28(%rbp), %rax
movq (%rax), %rdi
movq 0x28(%rbp), %rax
movq 0x10(%rax), %rsi
shlq $0x3, %rsi
callq 0x2360
movq %rax, %rcx
movq 0x28(%rbp), %rax
movq %rcx, (%rax)
jmp 0x29c2b5
movl $0x0, -0x74(%rbp)
movq -0x58(%rbp), %rdi
movl -0x14(%rbp), %esi
movl -0x74(%rbp), %ecx
movl %ecx, %eax
addl $0x1, %eax
movl %eax, -0x74(%rbp)
xorl %edx, %edx
callq 0x286ee0
movq %rax, -0x30(%rbp)
movl -0x14(%rbp), %edi
callq 0x286f50
movl %eax, %ecx
movq -0x30(%rbp), %rax
movl %ecx, 0x10(%rax)
movq -0x30(%rbp), %rsi
leaq -0x38(%rbp), %rdi
xorl %eax, %eax
movl %eax, %edx
callq 0x280df0
movq -0x48(%rbp), %rdi
movl -0x14(%rbp), %esi
leaq -0x60(%rbp), %rdx
callq 0x286fb0
movl %eax, -0x5c(%rbp)
movq -0x48(%rbp), %rax
movq 0x20(%rax), %rax
movl -0x5c(%rbp), %ecx
imulq $0x88, %rcx, %rcx
addq %rcx, %rax
movq %rax, -0x40(%rbp)
movq -0x40(%rbp), %rax
movl $0x1, (%rax)
movq -0x30(%rbp), %rcx
movq -0x40(%rbp), %rax
movq %rcx, 0x10(%rax)
movq -0x40(%rbp), %rax
movl $0x0, 0x4(%rax)
movq -0x40(%rbp), %rax
movl $0xffffffff, 0xc(%rax)  # imm = 0xFFFFFFFF
movq -0x40(%rbp), %rax
movl $0xffffffff, 0x8(%rax)  # imm = 0xFFFFFFFF
movl $0x0, -0x6c(%rbp)
movq 0x38(%rbp), %rdx
movl $0x1, %eax
xorl %ecx, %ecx
cmpq $0x0, %rdx
cmovnel %ecx, %eax
cltq
movq %rax, 0x38(%rbp)
cmpq $0x0, -0x38(%rbp)
je 0x29c393
movq -0x38(%rbp), %rax
movl 0x2c(%rax), %eax
movl %eax, -0xfc(%rbp)
jmp 0x29c39d
xorl %eax, %eax
movl %eax, -0xfc(%rbp)
jmp 0x29c39d
movl -0xfc(%rbp), %eax
cmpl $0x0, %eax
jbe 0x29cc72
leaq -0x38(%rbp), %rdi
xorl %eax, %eax
movl %eax, %edx
movq %rdx, %rsi
callq 0x2814c0
movq %rax, -0x98(%rbp)
movq -0x98(%rbp), %rax
movq (%rax), %rcx
shrq $0x20, %rcx
shlq $0x20, %rcx
movq 0x28(%rbp), %rax
orq 0x8(%rax), %rcx
movq -0x98(%rbp), %rax
movq %rcx, (%rax)
movq 0x28(%rbp), %rax
movq 0x8(%rax), %rax
movq 0x28(%rbp), %rcx
cmpq 0x10(%rcx), %rax
jne 0x29c457
movq 0x28(%rbp), %rax
cmpq $0x0, 0x10(%rax)
je 0x29c418
movq 0x28(%rbp), %rax
movq 0x10(%rax), %rax
shlq %rax
movq %rax, -0x108(%rbp)
jmp 0x29c426
movl $0x2, %eax
movq %rax, -0x108(%rbp)
jmp 0x29c426
movq -0x108(%rbp), %rcx
movq 0x28(%rbp), %rax
movq %rcx, 0x10(%rax)
movq 0x28(%rbp), %rax
movq (%rax), %rdi
movq 0x28(%rbp), %rax
movq 0x10(%rax), %rsi
shlq $0x3, %rsi
callq 0x2360
movq %rax, %rcx
movq 0x28(%rbp), %rax
movq %rcx, (%rax)
movq -0x98(%rbp), %rdx
movq 0x28(%rbp), %rax
movq (%rax), %rax
movq 0x28(%rbp), %rsi
movq 0x8(%rsi), %rcx
movq %rcx, %rdi
addq $0x1, %rdi
movq %rdi, 0x8(%rsi)
movq %rdx, (%rax,%rcx,8)
movq -0x50(%rbp), %rdi
movq -0x98(%rbp), %rax
movl 0x8(%rax), %esi
callq 0x287300
movl %eax, -0x5c(%rbp)
movl -0x5c(%rbp), %eax
movq -0x50(%rbp), %rcx
cmpl (%rcx), %eax
je 0x29c914
cmpq $0x0, 0x38(%rbp)
je 0x29c914
movq -0x98(%rbp), %rax
movq (%rax), %rax
shrq $0x20, %rax
movl %eax, -0xa0(%rbp)
movq -0x50(%rbp), %rax
movq 0x20(%rax), %rax
movl -0x5c(%rbp), %ecx
movq (%rax,%rcx,8), %rax
shrq $0x20, %rax
movl %eax, -0xa4(%rbp)
movq -0x50(%rbp), %rax
movq 0x20(%rax), %rax
movl -0x5c(%rbp), %ecx
movq (%rax,%rcx,8), %rax
movl %eax, -0xa8(%rbp)
movl $0x0, -0x9c(%rbp)
movl -0x9c(%rbp), %eax
cmpl -0xa8(%rbp), %eax
jge 0x29c905
movq -0x20(%rbp), %rax
movq 0x20(%rbp), %rcx
movl -0xa4(%rbp), %edx
addl -0x9c(%rbp), %edx
movslq %edx, %rdx
movq (%rcx,%rdx,8), %rcx
movslq %ecx, %rcx
imulq $0x30, %rcx, %rcx
addq %rcx, %rax
movq %rax, -0xb0(%rbp)
movl $0x0, -0xb4(%rbp)
movq -0xb0(%rbp), %rax
movl 0xc(%rax), %eax
shrl $0x1f, %eax
cmpl $0x0, %eax
je 0x29c561
movl $0x1, -0xb4(%rbp)
jmp 0x29c899
movl $0x0, -0xb8(%rbp)
movl $0x0, -0xbc(%rbp)
movq -0xb0(%rbp), %rax
movl 0x14(%rax), %eax
andl $0x7fffffff, %eax       # imm = 0x7FFFFFFF
cmpl $0x0, %eax
jne 0x29c598
movl $0x1, -0xbc(%rbp)
jmp 0x29c713
movq -0xb0(%rbp), %rax
cmpl $0x0, 0x4(%rax)
jl 0x29c711
movl -0xa0(%rbp), %eax
movq -0xb0(%rbp), %rcx
cmpl 0x4(%rcx), %eax
jne 0x29c5ff
movq -0xb0(%rbp), %rax
movl 0xc(%rax), %eax
shrl $0x1e, %eax
andl $0x1, %eax
cmpl $0x0, %eax
je 0x29c5ff
movq -0x98(%rbp), %rax
movl 0x10(%rax), %eax
movq -0xb0(%rbp), %rcx
cmpl 0x8(%rcx), %eax
jne 0x29c5ff
movl $0x1, -0xbc(%rbp)
movl $0x1, -0xb4(%rbp)
jmp 0x29c70f
movq -0xb0(%rbp), %rax
movl 0x1c(%rax), %eax
movl %eax, -0xc0(%rbp)
movl -0xa0(%rbp), %eax
movl %eax, -0xc4(%rbp)
movl -0xc0(%rbp), %eax
movq -0xb0(%rbp), %rcx
cmpl 0x4(%rcx), %eax
jle 0x29c645
movl -0xc0(%rbp), %eax
movq -0xb0(%rbp), %rcx
subl 0x4(%rcx), %eax
movl %eax, -0x10c(%rbp)
jmp 0x29c65b
movq -0xb0(%rbp), %rax
movl 0x4(%rax), %eax
subl -0xc0(%rbp), %eax
movl %eax, -0x10c(%rbp)
movl -0x10c(%rbp), %eax
movl %eax, -0xc0(%rbp)
movl -0xc4(%rbp), %eax
movq -0xb0(%rbp), %rcx
cmpl 0x4(%rcx), %eax
jle 0x29c691
movl -0xc4(%rbp), %eax
movq -0xb0(%rbp), %rcx
subl 0x4(%rcx), %eax
movl %eax, -0x110(%rbp)
jmp 0x29c6a7
movq -0xb0(%rbp), %rax
movl 0x4(%rax), %eax
subl -0xc4(%rbp), %eax
movl %eax, -0x110(%rbp)
movl -0x110(%rbp), %eax
movl %eax, -0xc4(%rbp)
movl -0xc4(%rbp), %eax
movl %eax, -0x118(%rbp)
movl -0xb8(%rbp), %eax
movl $0x2, %ecx
cltd
idivl %ecx
movl %eax, %ecx
movl -0x118(%rbp), %eax
subl %ecx, %eax
movl %eax, -0x114(%rbp)
movl -0xc0(%rbp), %ecx
movq -0xb0(%rbp), %rax
movl 0x20(%rax), %eax
movl $0x2, %esi
cltd
idivl %esi
movl %eax, %edx
movl -0x114(%rbp), %eax
subl %edx, %ecx
cmpl %ecx, %eax
jge 0x29c70d
movl $0x1, -0xbc(%rbp)
jmp 0x29c70f
jmp 0x29c711
jmp 0x29c713
cmpl $0x0, -0xbc(%rbp)
je 0x29c852
movq 0x28(%rbp), %rax
movq 0x8(%rax), %rax
subq $0x1, %rax
movl %eax, %ecx
movq -0xb0(%rbp), %rax
movl %ecx, 0x18(%rax)
movl -0xa0(%rbp), %ecx
movq -0xb0(%rbp), %rax
movl %ecx, 0x1c(%rax)
movq -0x98(%rbp), %rax
movl 0x10(%rax), %ecx
movq -0xb0(%rbp), %rax
movl %ecx, 0x24(%rax)
movl -0xb8(%rbp), %ecx
movq -0xb0(%rbp), %rax
movl %ecx, 0x20(%rax)
movq -0x98(%rbp), %rax
movl 0x14(%rax), %edx
movq -0xb0(%rbp), %rax
movl 0x14(%rax), %ecx
andl $0x1, %edx
shll $0x1f, %edx
andl $0x7fffffff, %ecx       # imm = 0x7FFFFFFF
orl %edx, %ecx
movl %ecx, 0x14(%rax)
movq -0xb0(%rbp), %rax
cmpl $0x0, 0x4(%rax)
jl 0x29c850
movl -0xa0(%rbp), %eax
movq -0xb0(%rbp), %rcx
cmpl 0x4(%rcx), %eax
jne 0x29c7eb
movq -0xb0(%rbp), %rax
movl 0xc(%rax), %eax
shrl $0x1e, %eax
andl $0x1, %eax
cmpl $0x0, %eax
je 0x29c7eb
movq -0x98(%rbp), %rax
movl 0x10(%rax), %eax
movq -0xb0(%rbp), %rcx
cmpl 0x8(%rcx), %eax
jne 0x29c7eb
movl $0x1, -0xb4(%rbp)
jmp 0x29c84e
movl -0xa0(%rbp), %eax
movq -0xb0(%rbp), %rcx
movl 0x4(%rcx), %ecx
addl $0x2710, %ecx           # imm = 0x2710
cmpl %ecx, %eax
jle 0x29c84c
movl -0xa0(%rbp), %eax
movq -0xb0(%rbp), %rcx
movl 0x4(%rcx), %ecx
sarl $0x4, %ecx
cmpl %ecx, %eax
jle 0x29c84c
cvtsi2sdl -0xa0(%rbp), %xmm0
movq -0xb0(%rbp), %rax
cvtsi2sdl 0x4(%rax), %xmm1
movsd 0xea008(%rip), %xmm2    # 0x386840
mulsd %xmm2, %xmm1
ucomisd %xmm1, %xmm0
jbe 0x29c84c
movl $0x1, -0xb4(%rbp)
jmp 0x29c84e
jmp 0x29c850
jmp 0x29c852
movq -0xb0(%rbp), %rax
movl 0x14(%rax), %edx
andl $0x7fffffff, %edx       # imm = 0x7FFFFFFF
addl $0x1, %edx
movl 0x14(%rax), %ecx
andl $0x7fffffff, %edx       # imm = 0x7FFFFFFF
andl $0x80000000, %ecx       # imm = 0x80000000
orl %edx, %ecx
movl %ecx, 0x14(%rax)
movq -0xb0(%rbp), %rax
movl 0x14(%rax), %eax
andl $0x7fffffff, %eax       # imm = 0x7FFFFFFF
cmpl 0x10(%rbp), %eax
jl 0x29c897
movl $0x1, -0xb4(%rbp)
jmp 0x29c899
cmpq $0x0, 0x40(%rbp)
jne 0x29c8ef
movq 0x18(%rbp), %rax
movq 0x10(%rax), %rax
movl -0xa4(%rbp), %ecx
addl -0x9c(%rbp), %ecx
movslq %ecx, %rcx
cmpq $0x0, (%rax,%rcx,8)
jne 0x29c8ef
cmpl $0x0, -0xb4(%rbp)
je 0x29c8ef
movq 0x18(%rbp), %rax
movq 0x10(%rax), %rax
movl -0xa4(%rbp), %ecx
addl -0x9c(%rbp), %ecx
movslq %ecx, %rcx
movq $0x1, (%rax,%rcx,8)
movl -0x6c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x6c(%rbp)
jmp 0x29c8f1
movl -0x9c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x9c(%rbp)
jmp 0x29c4f8
movl -0x6c(%rbp), %eax
cmpl -0x18(%rbp), %eax
jne 0x29c912
jmp 0x29cc72
jmp 0x29c914
movq $0x1, 0x38(%rbp)
movq -0x10(%rbp), %rax
movq 0x28(%rax), %rax
movq -0x98(%rbp), %rcx
movl 0x8(%rcx), %ecx
movq (%rax,%rcx,8), %rax
movl %eax, -0x88(%rbp)
movq -0x10(%rbp), %rax
movq 0x8(%rax), %rax
movq -0x10(%rbp), %rcx
movq 0x28(%rcx), %rcx
movq -0x98(%rbp), %rdx
movl 0x8(%rdx), %edx
movq (%rcx,%rdx,8), %rcx
shrq $0x20, %rcx
imulq $0x18, %rcx, %rcx
addq %rcx, %rax
movq %rax, -0x90(%rbp)
movl $0x0, -0x84(%rbp)
movl -0x84(%rbp), %eax
cmpl -0x88(%rbp), %eax
jge 0x29cc6d
movq -0x90(%rbp), %rax
movslq -0x84(%rbp), %rcx
imulq $0x18, %rcx, %rcx
addq %rcx, %rax
movq %rax, -0xd0(%rbp)
movq -0x98(%rbp), %rax
movq (%rax), %rax
shrq $0x20, %rax
movq -0xd0(%rbp), %rcx
movq (%rcx), %rcx
movl %ecx, %ecx
addq %rcx, %rax
movl %eax, -0xd4(%rbp)
movl -0xd4(%rbp), %eax
cmpl -0x24(%rbp), %eax
jle 0x29c9d3
jmp 0x29cc59
movq -0x48(%rbp), %rdi
movq -0xd0(%rbp), %rax
movl 0x8(%rax), %esi
leaq -0x60(%rbp), %rdx
callq 0x286fb0
movl %eax, -0x5c(%rbp)
movq -0x48(%rbp), %rax
movq 0x20(%rax), %rax
movl -0x5c(%rbp), %ecx
imulq $0x88, %rcx, %rcx
addq %rcx, %rax
movq %rax, -0x40(%rbp)
cmpl $0x0, -0x60(%rbp)
je 0x29ca37
movq -0x40(%rbp), %rax
movl $0x0, (%rax)
movq -0x40(%rbp), %rax
movl $0xffffffff, 0xc(%rax)  # imm = 0xFFFFFFFF
movq -0x40(%rbp), %rax
movl $0xffffffff, 0x8(%rax)  # imm = 0xFFFFFFFF
movq -0x40(%rbp), %rax
movl $0x0, 0x4(%rax)
movq -0x40(%rbp), %rax
movl (%rax), %eax
cmpl 0x10(%rbp), %eax
jge 0x29cb09
movq -0x58(%rbp), %rdi
movq -0xd0(%rbp), %rax
movl 0x8(%rax), %esi
movl -0xd4(%rbp), %edx
movl -0x74(%rbp), %ecx
movl %ecx, %eax
addl $0x1, %eax
movl %eax, -0x74(%rbp)
callq 0x286ee0
movq %rax, -0x30(%rbp)
movq 0x28(%rbp), %rax
movq 0x8(%rax), %rax
subq $0x1, %rax
movl %eax, %ecx
movq -0x30(%rbp), %rax
movl %ecx, 0xc(%rax)
movq -0x98(%rbp), %rax
movl 0x10(%rax), %eax
movl %eax, -0x11c(%rbp)
movq -0xd0(%rbp), %rax
movl 0x8(%rax), %edi
callq 0x286f50
movl -0x11c(%rbp), %ecx
addl %eax, %ecx
movq -0x30(%rbp), %rax
movl %ecx, 0x10(%rax)
movq -0x98(%rbp), %rax
movl 0x14(%rax), %ecx
movq -0x30(%rbp), %rax
movl %ecx, 0x14(%rax)
movq -0x30(%rbp), %rsi
leaq -0x38(%rbp), %rdi
xorl %eax, %eax
movl %eax, %edx
callq 0x280df0
movq -0x30(%rbp), %rdx
movq -0x40(%rbp), %rax
movq -0x40(%rbp), %rsi
movl (%rsi), %ecx
movl %ecx, %edi
addl $0x1, %edi
movl %edi, (%rsi)
movslq %ecx, %rcx
movq %rdx, 0x10(%rax,%rcx,8)
movq -0x40(%rbp), %rax
movslq (%rax), %rdi
movq -0x40(%rbp), %rsi
addq $0x10, %rsi
callq 0x281f20
jmp 0x29cc57
movq -0x40(%rbp), %rax
movq 0x10(%rax), %rax
movq (%rax), %rax
shrq $0x20, %rax
cmpl -0xd4(%rbp), %eax
jle 0x29cc55
movq -0x40(%rbp), %rax
movq 0x10(%rax), %rsi
leaq -0x38(%rbp), %rdi
xorl %eax, %eax
movl %eax, %edx
callq 0x2814c0
movq %rax, -0x30(%rbp)
cmpq $0x0, -0x30(%rbp)
je 0x29cbe9
movslq -0xd4(%rbp), %rcx
shlq $0x20, %rcx
movl -0x74(%rbp), %eax
movl %eax, %edx
addl $0x1, %edx
movl %edx, -0x74(%rbp)
movl %eax, %eax
orq %rax, %rcx
movq -0x30(%rbp), %rax
movq %rcx, (%rax)
movq 0x28(%rbp), %rax
movq 0x8(%rax), %rax
subq $0x1, %rax
movl %eax, %ecx
movq -0x30(%rbp), %rax
movl %ecx, 0xc(%rax)
movq -0x98(%rbp), %rax
movl 0x10(%rax), %eax
movl %eax, -0x120(%rbp)
movq -0xd0(%rbp), %rax
movl 0x8(%rax), %edi
callq 0x286f50
movl -0x120(%rbp), %ecx
addl %eax, %ecx
movq -0x30(%rbp), %rax
movl %ecx, 0x10(%rax)
movq -0x98(%rbp), %rax
movl 0x14(%rax), %ecx
movq -0x30(%rbp), %rax
movl %ecx, 0x14(%rax)
movq -0x30(%rbp), %rsi
leaq -0x38(%rbp), %rdi
xorl %eax, %eax
movl %eax, %edx
callq 0x280df0
movq -0x40(%rbp), %rax
movslq (%rax), %rsi
movq -0x40(%rbp), %rdx
addq $0x10, %rdx
xorl %eax, %eax
movl %eax, %edi
callq 0x281e50
jmp 0x29cc53
movq 0x1273f0(%rip), %rax    # 0x3c3fe0
movq (%rax), %rdi
movq -0x40(%rbp), %rax
movl (%rax), %edx
movq -0x40(%rbp), %rax
movq 0x10(%rax), %rax
movq (%rax), %rax
shrq $0x20, %rax
movl %eax, %ecx
movq -0x40(%rbp), %rax
movq 0x10(%rax), %rax
movq (%rax), %rax
movl %eax, %r8d
movl -0xd4(%rbp), %r9d
movl -0x14(%rbp), %r11d
movl -0x24(%rbp), %r10d
movl -0x18(%rbp), %eax
leaq 0xf3d6e(%rip), %rsi     # 0x39099f
movl %r11d, (%rsp)
movl %r10d, 0x8(%rsp)
movl %eax, 0x10(%rsp)
movb $0x0, %al
callq 0x22a0
movq -0x58(%rbp), %rdi
callq 0x30e250
jmp 0x29d22f
jmp 0x29cc55
jmp 0x29cc57
jmp 0x29cc59
movl -0x84(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x84(%rbp)
jmp 0x29c972
jmp 0x29c37d
movq -0x48(%rbp), %rdi
callq 0x287440
movl $0x0, -0x64(%rbp)
movl $0x0, -0x70(%rbp)
movl -0x64(%rbp), %eax
cmpl -0x18(%rbp), %eax
jge 0x29ccc3
movq -0x20(%rbp), %rax
movslq -0x64(%rbp), %rcx
imulq $0x30, %rcx, %rcx
addq %rcx, %rax
movl 0x14(%rax), %eax
andl $0x7fffffff, %eax       # imm = 0x7FFFFFFF
cmpl $0x0, %eax
jle 0x29ccb6
movl -0x70(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x70(%rbp)
jmp 0x29ccb8
movl -0x64(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x64(%rbp)
jmp 0x29cc89
cmpl $0x0, -0x70(%rbp)
jle 0x29d226
cmpq $0x0, 0x30(%rbp)
je 0x29d226
movl $0x1, -0xdc(%rbp)
movq 0x18(%rbp), %rax
movq $0x0, (%rax)
movq 0x18(%rbp), %rax
movq 0x8(%rax), %rax
movq 0x28(%rbp), %rcx
cmpq 0x8(%rcx), %rax
jae 0x29cdce
movq 0x28(%rbp), %rax
movq 0x8(%rax), %rcx
movq 0x18(%rbp), %rax
movq %rcx, 0x8(%rax)
movq 0x18(%rbp), %rax
movq 0x8(%rax), %rcx
addq $-0x1, %rcx
movq %rcx, 0x8(%rax)
movq 0x18(%rbp), %rax
movq 0x8(%rax), %rcx
shrq %rcx
movq 0x18(%rbp), %rax
orq 0x8(%rax), %rcx
movq %rcx, 0x8(%rax)
movq 0x18(%rbp), %rax
movq 0x8(%rax), %rcx
shrq $0x2, %rcx
movq 0x18(%rbp), %rax
orq 0x8(%rax), %rcx
movq %rcx, 0x8(%rax)
movq 0x18(%rbp), %rax
movq 0x8(%rax), %rcx
shrq $0x4, %rcx
movq 0x18(%rbp), %rax
orq 0x8(%rax), %rcx
movq %rcx, 0x8(%rax)
movq 0x18(%rbp), %rax
movq 0x8(%rax), %rcx
shrq $0x8, %rcx
movq 0x18(%rbp), %rax
orq 0x8(%rax), %rcx
movq %rcx, 0x8(%rax)
movq 0x18(%rbp), %rax
movq 0x8(%rax), %rcx
shrq $0x10, %rcx
movq 0x18(%rbp), %rax
orq 0x8(%rax), %rcx
movq %rcx, 0x8(%rax)
movq 0x18(%rbp), %rax
movq 0x8(%rax), %rcx
addq $0x1, %rcx
movq %rcx, 0x8(%rax)
movq 0x18(%rbp), %rax
movq 0x10(%rax), %rdi
movq 0x18(%rbp), %rax
movq 0x8(%rax), %rsi
shlq $0x3, %rsi
callq 0x2360
movq %rax, %rcx
movq 0x18(%rbp), %rax
movq %rcx, 0x10(%rax)
jmp 0x29cdd0
movq 0x18(%rbp), %rax
movq 0x10(%rax), %rax
movq %rax, -0xe8(%rbp)
movq 0x18(%rbp), %rax
movq 0x10(%rax), %rdi
movq 0x28(%rbp), %rax
movq 0x8(%rax), %rdx
shlq $0x3, %rdx
xorl %esi, %esi
callq 0x2100
cmpq $0x0, 0x40(%rbp)
je 0x29ce28
movq 0x30(%rbp), %rdi
movq 0x18(%rbp), %rsi
movq 0x28(%rbp), %rdx
movl -0x18(%rbp), %ecx
movq -0x20(%rbp), %r8
movl 0x10(%rbp), %r9d
movss -0x28(%rbp), %xmm0
callq 0x2d3350
movl %eax, -0xdc(%rbp)
cmpl $0x1, -0xdc(%rbp)
jne 0x29d224
movl $0x0, -0x64(%rbp)
movl -0x64(%rbp), %eax
cmpl -0x18(%rbp), %eax
jge 0x29cec2
movq -0x20(%rbp), %rax
movslq -0x64(%rbp), %rcx
imulq $0x30, %rcx, %rcx
addq %rcx, %rax
movq %rax, -0xf0(%rbp)
movq -0xf0(%rbp), %rax
movl 0x14(%rax), %eax
andl $0x7fffffff, %eax       # imm = 0x7FFFFFFF
cmpl $0x0, %eax
jle 0x29ceb2
movq -0xf0(%rbp), %rax
cmpl $0x0, 0x4(%rax)
jl 0x29ceb2
movq -0xf0(%rbp), %rax
cmpl $0x0, 0x18(%rax)
jl 0x29ceb2
movq -0xe8(%rbp), %rax
movq 0x28(%rbp), %rcx
movq (%rcx), %rcx
movq -0xf0(%rbp), %rdx
movslq 0x18(%rdx), %rdx
movq (%rcx,%rdx,8), %rcx
movq (%rcx), %rcx
movl %ecx, %ecx
movq $0x1, (%rax,%rcx,8)
jmp 0x29ceb4
movl -0x64(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x64(%rbp)
jmp 0x29ce3c
movq 0x28(%rbp), %rax
movq 0x8(%rax), %rax
subl $0x1, %eax
movl %eax, -0x64(%rbp)
cmpl $0x0, -0x64(%rbp)
jl 0x29cf2c
movq -0xe8(%rbp), %rax
movslq -0x64(%rbp), %rcx
cmpq $0x0, (%rax,%rcx,8)
je 0x29cf1f
movq 0x28(%rbp), %rax
movq (%rax), %rax
movslq -0x64(%rbp), %rcx
movq (%rax,%rcx,8), %rax
cmpl $0x0, 0xc(%rax)
jl 0x29cf1f
movq -0xe8(%rbp), %rax
movq 0x28(%rbp), %rcx
movq (%rcx), %rcx
movslq -0x64(%rbp), %rdx
movq (%rcx,%rdx,8), %rcx
movslq 0xc(%rcx), %rcx
movq $0x1, (%rax,%rcx,8)
jmp 0x29cf21
movl -0x64(%rbp), %eax
addl $-0x1, %eax
movl %eax, -0x64(%rbp)
jmp 0x29ced0
movl $0x0, -0xd8(%rbp)
movl $0x0, -0x64(%rbp)
movl -0x64(%rbp), %eax
movq 0x28(%rbp), %rcx
cmpq 0x8(%rcx), %rax
jae 0x29cfa2
movq -0xe8(%rbp), %rax
movslq -0x64(%rbp), %rcx
cmpq $0x0, (%rax,%rcx,8)
je 0x29cf81
movl -0xd8(%rbp), %eax
movl %eax, %ecx
addl $0x1, %ecx
movl %ecx, -0xd8(%rbp)
movslq %eax, %rdx
movq -0xe8(%rbp), %rax
movslq -0x64(%rbp), %rcx
movq %rdx, (%rax,%rcx,8)
jmp 0x29cf95
movq -0xe8(%rbp), %rax
movslq -0x64(%rbp), %rcx
movl $0xffffffff, %edx       # imm = 0xFFFFFFFF
movq %rdx, (%rax,%rcx,8)
jmp 0x29cf97
movl -0x64(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x64(%rbp)
jmp 0x29cf3d
jmp 0x29cfa4
movq 0x30(%rbp), %rax
movq 0x10(%rax), %rax
movq 0x30(%rbp), %rcx
movq 0x8(%rcx), %rcx
movslq -0xd8(%rbp), %rdx
addq %rdx, %rcx
cmpq %rcx, %rax
jae 0x29d097
movq 0x30(%rbp), %rax
movq 0x8(%rax), %rcx
movslq -0xd8(%rbp), %rax
addq %rax, %rcx
movq 0x30(%rbp), %rax
movq %rcx, 0x10(%rax)
movq 0x30(%rbp), %rax
movq 0x10(%rax), %rcx
addq $-0x1, %rcx
movq %rcx, 0x10(%rax)
movq 0x30(%rbp), %rax
movq 0x10(%rax), %rcx
shrq %rcx
movq 0x30(%rbp), %rax
orq 0x10(%rax), %rcx
movq %rcx, 0x10(%rax)
movq 0x30(%rbp), %rax
movq 0x10(%rax), %rcx
shrq $0x2, %rcx
movq 0x30(%rbp), %rax
orq 0x10(%rax), %rcx
movq %rcx, 0x10(%rax)
movq 0x30(%rbp), %rax
movq 0x10(%rax), %rcx
shrq $0x4, %rcx
movq 0x30(%rbp), %rax
orq 0x10(%rax), %rcx
movq %rcx, 0x10(%rax)
movq 0x30(%rbp), %rax
movq 0x10(%rax), %rcx
shrq $0x8, %rcx
movq 0x30(%rbp), %rax
orq 0x10(%rax), %rcx
movq %rcx, 0x10(%rax)
movq 0x30(%rbp), %rax
movq 0x10(%rax), %rcx
shrq $0x10, %rcx
movq 0x30(%rbp), %rax
orq 0x10(%rax), %rcx
movq %rcx, 0x10(%rax)
movq 0x30(%rbp), %rax
movq 0x10(%rax), %rcx
addq $0x1, %rcx
movq %rcx, 0x10(%rax)
movq 0x30(%rbp), %rax
movq (%rax), %rdi
movq 0x30(%rbp), %rax
imulq $0xc, 0x10(%rax), %rsi
callq 0x2360
movq %rax, %rcx
movq 0x30(%rbp), %rax
movq %rcx, (%rax)
jmp 0x29d099
movl $0x0, -0x64(%rbp)
movl -0x64(%rbp), %eax
movq 0x28(%rbp), %rcx
cmpq 0x8(%rcx), %rax
jae 0x29d1ac
movq -0xe8(%rbp), %rax
movslq -0x64(%rbp), %rcx
movl $0xffffffff, %edx       # imm = 0xFFFFFFFF
cmpq %rdx, (%rax,%rcx,8)
jne 0x29d0cc
jmp 0x29d19e
movq 0x30(%rbp), %rax
movq (%rax), %rax
movq -0xe8(%rbp), %rcx
movslq -0x64(%rbp), %rdx
movq (%rcx,%rdx,8), %rcx
movq 0x30(%rbp), %rdx
addq 0x8(%rdx), %rcx
imulq $0xc, %rcx, %rcx
addq %rcx, %rax
movq %rax, -0xf8(%rbp)
movq 0x28(%rbp), %rax
movq (%rax), %rax
movslq -0x64(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movl 0x8(%rax), %ecx
movq -0xf8(%rbp), %rax
movl %ecx, (%rax)
movq 0x28(%rbp), %rax
movq (%rax), %rax
movslq -0x64(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movq (%rax), %rax
shrq $0x20, %rax
movl %eax, %ecx
movq -0xf8(%rbp), %rax
movl %ecx, 0x4(%rax)
movq 0x28(%rbp), %rax
movq (%rax), %rax
movslq -0x64(%rbp), %rcx
movq (%rax,%rcx,8), %rax
cmpl $0x0, 0xc(%rax)
jge 0x29d166
movq 0x28(%rbp), %rax
movq (%rax), %rax
movslq -0x64(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movslq 0xc(%rax), %rax
movq %rax, -0x128(%rbp)
jmp 0x29d18b
movq -0xe8(%rbp), %rax
movq 0x28(%rbp), %rcx
movq (%rcx), %rcx
movslq -0x64(%rbp), %rdx
movq (%rcx,%rdx,8), %rcx
movslq 0xc(%rcx), %rcx
movq (%rax,%rcx,8), %rax
movq %rax, -0x128(%rbp)
movq -0x128(%rbp), %rax
movl %eax, %ecx
movq -0xf8(%rbp), %rax
movl %ecx, 0x8(%rax)
movl -0x64(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x64(%rbp)
jmp 0x29d0a0
movslq -0xd8(%rbp), %rcx
movq 0x30(%rbp), %rax
addq 0x8(%rax), %rcx
movq %rcx, 0x8(%rax)
movl $0x0, -0x64(%rbp)
movl -0x64(%rbp), %eax
cmpl -0x18(%rbp), %eax
jge 0x29d222
movq -0x20(%rbp), %rax
movslq -0x64(%rbp), %rcx
imulq $0x30, %rcx, %rcx
addq %rcx, %rax
cmpl $0x0, 0x18(%rax)
jl 0x29d215
movq -0xe8(%rbp), %rax
movq -0x20(%rbp), %rcx
movslq -0x64(%rbp), %rdx
imulq $0x30, %rdx, %rdx
addq %rdx, %rcx
movslq 0x18(%rcx), %rcx
movq (%rax,%rcx,8), %rax
movl %eax, %ecx
movq -0x20(%rbp), %rax
movslq -0x64(%rbp), %rdx
imulq $0x30, %rdx, %rdx
addq %rdx, %rax
movl %ecx, 0x18(%rax)
jmp 0x29d217
movl -0x64(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x64(%rbp)
jmp 0x29d1c6
jmp 0x29d224
jmp 0x29d226
movq -0x58(%rbp), %rdi
callq 0x30e250
addq $0x140, %rsp            # imm = 0x140
popq %rbp
retq
nopl (%rax,%rax)