// File: /workspace/github_cpp_makefile_star2_O2/BenLangmead[P]bowtie/./ebwt_search_backtrack.h
// Function: EbwtRangeSource::advanceBranch(int, unsigned short, PathManager&)
virtual void
	advanceBranch(int until, uint16_t minCost, PathManager& pm) {
		assert(curEbwt_ != NULL);

		// Let this->foundRange = false; we'll set it to true iff this call
		// to advance yielded a new valid-alignment range.
		this->foundRange = false;

		// Can't have already exceeded weighted hamming distance threshold
		assert_gt(qry_->length(), 0);
		assert_leq(qlen_, qry_->length());
		assert_geq(qual_->length(), qry_->length());
		assert(!pm.empty());

		do {
			assert(pm.repOk());
			// Get the highest-priority branch according to the priority
			// queue in 'pm'
			Branch* br = pm.front();
			// Shouldn't be curtailed or exhausted
			assert(!br->exhausted_);
			assert(!br->curtailed_);
			assert_gt(br->depth3_, 0);
			assert_leq(br->ham_, qualLim_);
			if(verbose_) {
				br->print(*qry_, *qual_, minCost, cout, (halfAndHalf_>0), partial_, fw_, ebwt_->fw());
				if(!br->edits_.empty()) {
					cout << "Edit: ";
					for(size_t i = 0; i < br->edits_.size(); i++) {
						Edit e = br->edits_.get(i);
						cout << (curEbwt_->fw() ? (qlen_ - e.pos - 1) : e.pos)
							 << (char)e.chr;
						if(i < br->edits_.size()-1) cout << " ";
					}
					cout << endl;
				}

			}
			assert(br->repOk((uint32_t)qlen_));

			ASSERT_ONLY(int stratum = br->cost_ >> 14); // shift the stratum over
			assert_lt(stratum, 4);
			// Not necessarily true with rounding
			uint32_t depth = br->tipDepth();

			const Ebwt& ebwt = *ebwt_;

			if(halfAndHalf_ > 0) assert_gt(depth3_, depth5_);

			bool reportedPartial = false;
			bool invalidExact = false;
			bool empty = false;
			bool hit = false;
			uint16_t cost = br->cost_;
			uint32_t cur = 0;
			uint32_t nedits = 0;

			if(halfAndHalf_ && !hhCheckTop(br, depth, 0)) {
				// Stop extending this branch because it violates a half-
				// and-half constraint
				if(metrics_ != NULL) metrics_->curBacktracks_++;
				pm.curtail(br, (uint32_t)qlen_, depth3_, qualOrder_);
				goto bail;
			}

			cur = (uint32_t)(qlen_ - depth - 1); // current offset into qry_
			if(depth < qlen_) {
				// Determine whether ranges at this location are candidates
				// for backtracking
				int c = (int)(*qry_)[cur]; // get char at this position
				int nextc = -1;
				if(cur < qlen_-1) nextc = (int)(*qry_)[cur+1];
				assert_leq(c, 4);
				// If any uncalled base's penalty is still under
				// the ceiling, then this position is an alternative
				uint8_t q[4] = {'!', '!', '!', '!'};
				uint8_t bestq;
				// get unrounded penalties at this position
				bestq = q[0] = q[1] = q[2] = q[3] =
					mmPenalty(maqPenalty_, qualAt(cur));

				// The current query position is a legit alternative if it a) is
				// not in the unrevisitable region, and b) its selection would
				// not necessarily cause the quality ceiling (if one exists) to
				// be exceeded
				bool curIsAlternative = (depth >= br->depth0_) &&
				                        (br->ham_ + bestq <= qualLim_);
				ASSERT_ONLY(TIndexOffU obot = br->bot_);
				TIndexOffU otop = br->top_;

				// If c is 'N', then it's a mismatch
				if(c == 4 && depth > 0) {
					// Force the 'else if(curIsAlternative)' or 'else'
					// branches below
					br->top_ = br->bot_ = 1;
				} else if(c == 4) {
					// We'll take the 'if(br->top == 0 && br->bot == 0)'
					// branch below
					assert_eq(0, br->top_);
					assert_eq(0, br->bot_);
				}

				// Get the range state for the current position
				RangeState *rs = br->rangeState();
				assert(rs != NULL);
				// Calculate the ranges for this position
				if(br->top_ == 0 && br->bot_ == 0) {
					// Calculate first quartet of ranges using the _fchr[]
					// array
								  rs->tops[0] = ebwt._fchr[0];
					rs->bots[0] = rs->tops[1] = ebwt._fchr[1];
					rs->bots[1] = rs->tops[2] = ebwt._fchr[2];
					rs->bots[2] = rs->tops[3] = ebwt._fchr[3];
					rs->bots[3]               = ebwt._fchr[4];
					ASSERT_ONLY(int r =)
					br->installRanges(c, nextc, qualLim_ - br->ham_, q);
					assert(r < 4 || c == 4);
					// Update top and bot
					if(c < 4) {
						br->top_ = rs->tops[c];
						br->bot_ = rs->bots[c];
					}
				} else if(curIsAlternative && (br->bot_ > br->top_ || c == 4)) {
					// Calculate next quartet of ranges.  We hope that the
					// appropriate cache lines are prefetched.
					assert(br->ltop_.valid());
								  rs->tops[0] =
					rs->bots[0] = rs->tops[1] =
					rs->bots[1] = rs->tops[2] =
					rs->bots[2] = rs->tops[3] =
					rs->bots[3]               = 0;
					if(br->lbot_.valid()) {
						if(metrics_ != NULL) metrics_->curBwtOps_++;
						ebwt.mapLFEx(br->ltop_, br->lbot_, (TIndexOffU*)rs->tops, (TIndexOffU*)rs->bots);
					} else {
#ifndef NDEBUG
						TIndexOffU tmptops[] = {0, 0, 0, 0};
						TIndexOffU tmpbots[] = {0, 0, 0, 0};
						SideLocus ltop, lbot;
						ltop.initFromRow(otop, ebwt_->_eh, ebwt_->_ebwt);
						lbot.initFromRow(obot, ebwt_->_eh, ebwt_->_ebwt);
						ebwt.mapLFEx(ltop, lbot, tmptops, tmpbots);
#endif
						if(metrics_ != NULL) metrics_->curBwtOps_++;
						int cc = ebwt.mapLF1((TIndexOffU&)otop, br->ltop_);
						br->top_ = otop;
						assert(cc == -1 || (cc >= 0 && cc < 4));
						if(cc >= 0) {
							assert_lt(cc, 4);
							rs->tops[cc] = br->top_;
							rs->bots[cc] = (br->top_ + 1);
						}
#ifndef NDEBUG
						for(int i = 0; i < 4; i++) {
							assert_eq(tmpbots[i] - tmptops[i],
							          rs->bots[i] - rs->tops[i]);
						}
#endif
					}
					ASSERT_ONLY(int r =)
					br->installRanges(c, nextc, qualLim_ - br->ham_, q);
					assert(r < 4 || c == 4);
					// Update top and bot
					if(c < 4) {
						br->top_ = rs->tops[c];
						br->bot_ = rs->bots[c];
					} else {
						br->top_ = br->bot_ = 1;
					}
				} else if(br->bot_ > br->top_) {
					// This read position is not a legitimate backtracking
					// alternative.  No need to do the bookkeeping for the
					// entire quartet, just do c.  We hope that the
					// appropriate cache lines are prefetched before now;
					// otherwise, we're about to take an expensive cache
					// miss.
					assert(br->ltop_.valid());
					rs->eliminated_ = true; // eliminate all alternatives leaving this node
					assert(br->eliminated(br->len_));
					if(c < 4) {
						if(br->top_ + 1 == br->bot_) {
							if(metrics_ != NULL) metrics_->curBwtOps_++;
							br->bot_ = br->top_ = ebwt.mapLF1(br->top_, br->ltop_, c);
							if(br->bot_ != OFF_MASK) br->bot_++;
						} else {
							if(metrics_ != NULL) metrics_->curBwtOps_++;
							br->top_ = ebwt.mapLF(br->ltop_, c);
							assert(br->lbot_.valid());
							if(metrics_ != NULL) metrics_->curBwtOps_++;
							br->bot_ = ebwt.mapLF(br->lbot_, c);
						}
					}
				} else {
					rs->eliminated_ = true;
				}
				assert(rs->repOk());
				// br->top_ and br->bot_ now contain the next top and bot
			} else {
				// The continuation had already processed the whole read
				assert_eq(qlen_, depth);
				cur = 0;
			}
			empty = (br->top_ == br->bot_);
			hit = (cur == 0 && !empty);

			// Check whether we've obtained an exact alignment when
			// we've been instructed not to report exact alignments
			nedits = (uint32_t)br->edits_.size();
			invalidExact = (hit && nedits == 0 && !reportExacts_);
			assert_leq(br->ham_, qualLim_);

			// Set this to true if the only way to make legal progress
			// is via one or more additional backtracks.
			if(halfAndHalf_ && !hhCheck(br, depth, empty)) {
				// This alignment doesn't satisfy the half-and-half
				// requirements; reject it
				if(metrics_ != NULL) metrics_->curBacktracks_++;
				pm.curtail(br, (uint32_t)qlen_, depth3_, qualOrder_);
				goto bail;
			}

			if(hit &&            // there is a range to report
			   !invalidExact &&  // not disqualified by no-exact-hits setting
			   !reportedPartial) // not an already-reported partial alignment
			{
				if(verbose_) {
					if(partial_) {
						cout << " Partial alignment:" << endl;
					} else {
						cout << " Final alignment:" << endl;
					}
					br->len_++;
					br->print((*qry_), (*qual_), minCost, cout, halfAndHalf_ > 0, partial_, fw_, ebwt_->fw());
					br->len_--;
					cout << endl;
				}
				assert_gt(br->bot_, br->top_);
				assert_leq(br->ham_, qualLim_);
				assert_leq((uint32_t)(br->cost_ & ~0xc000), qualLim_);
				if(metrics_ != NULL) metrics_->setReadHasRange();
				curRange_.top     = br->top_;
				curRange_.bot     = br->bot_;
				curRange_.cost    = br->cost_;
				curRange_.stratum = (br->cost_ >> 14);
				curRange_.numMms  = nedits;
				curRange_.fw      = fw_;
				curRange_.mms.clear();
				curRange_.refcs.clear();
				for(size_t i = 0; i < nedits; i++) {
					curRange_.mms.push_back((uint32_t)(qlen_ - br->edits_.get(i).pos - 1));
					curRange_.refcs.push_back((char)br->edits_.get(i).chr);
				}
				addPartialEdits();
				curRange_.ebwt    = ebwt_;
				this->foundRange  = true;
	#ifndef NDEBUG
				TIndexOff top2 = (TIndexOff)br->top_;
				top2++; // ensure it's not 0
				if(ebwt_->fw()) top2 = -top2;
				assert(allTops_.find(top2) == allTops_.end());
				allTops_.insert(top2);
	#endif
				assert(curRange_.repOk());
				// Must curtail because we've consumed the whole pattern
				if(metrics_ != NULL) metrics_->curBacktracks_++;
				pm.curtail(br, (uint32_t)qlen_, depth3_, qualOrder_);
			} else if(empty || cur == 0) {
				// The branch couldn't be extended further
				if(metrics_ != NULL) metrics_->curBacktracks_++;
				pm.curtail(br, (uint32_t)qlen_, depth3_, qualOrder_);
			} else {
				// Extend the branch by one position; no change to its cost
				// so there's no need to reconsider where it lies in the
				// priority queue
				assert_neq(0, cur);
				br->extend();
			}
		bail:
			// Make sure the front element of the priority queue is
			// extendable (i.e. not curtailed) and then prep it.
			if(!pm.splitAndPrep(rand_, (uint32_t)qlen_, qualLim_, depth3_,
			                    qualOrder_,
			                    ebwt_->_eh, ebwt_->_ebwt, ebwt_->_fw))
			{
				pm.reset(0);
				assert(pm.empty());
			}
			if(pm.empty()) {
				// No more branches
				break;
			}
			assert(!pm.front()->curtailed_);
			assert(!pm.front()->exhausted_);

			if(until == ADV_COST_CHANGES && pm.front()->cost_ != cost) break;
			else if(until == ADV_STEP) break;

		} while(!this->foundRange);
		if(!pm.empty()) {
			assert(!pm.front()->curtailed_);
			assert(!pm.front()->exhausted_);
		}
	}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x58, %rsp
movq %rcx, %r13
movq %rdi, %r14
movb $0x0, 0x9(%rdi)
leaq 0xd0(%rdi), %rax
movq %rax, 0x50(%rsp)
leaq 0xf0(%rdi), %rax
movq %rax, 0x48(%rsp)
leaq 0xa0(%rdi), %rax
movq %rax, 0x40(%rsp)
movzwl %dx, %eax
movl %eax, 0x20(%rsp)
movq %rcx, 0x28(%rsp)
movl %esi, 0xc(%rsp)
movq %r13, %rdi
callq 0x24242
movq %rax, %rbp
cmpb $0x1, 0xb4(%r14)
jne 0x22714
movq 0x18(%r14), %rsi
movq 0x58(%r14), %rdx
xorl %r9d, %r9d
cmpl $0x0, 0x90(%r14)
setg %r9b
movzbl 0x94(%r14), %eax
movzbl 0x70(%r14), %r10d
movq 0x68(%r14), %rcx
movzbl 0x10(%rcx), %r11d
subq $0x8, %rsp
movq %rbp, %rdi
movl 0x28(%rsp), %ecx
movq 0x3f980(%rip), %r8      # 0x61fb0
pushq %r11
pushq %r10
pushq %rax
callq 0x24626
addq $0x20, %rsp
cmpq $0x0, 0x50(%rbp)
je 0x22714
movq 0x3f960(%rip), %rdi     # 0x61fb0
leaq 0x28378(%rip), %rsi     # 0x4a9cf
callq 0x94e0
leaq 0x58(%rbp), %rbx
xorl %r15d, %r15d
cmpq 0x50(%rbp), %r15
jae 0x22708
movq %rbx, %rax
cmpq $0x6, %r15
jb 0x22696
cmpq $0x15, %r15
ja 0x2268a
movq 0x70(%rbp), %rax
leaq (%rax,%r15,4), %rax
addq $-0x18, %rax
jmp 0x22696
movq 0x78(%rbp), %rax
leaq (%rax,%r15,4), %rax
addq $-0x58, %rax
movl (%rax), %r12d
movq 0x10(%r14), %rax
cmpb $0x1, 0x10(%rax)
jne 0x226b9
movl %r12d, %eax
notl %eax
shrl $0x14, %eax
orl $0xfffffc00, %eax       # imm = 0xFFFFFC00
movslq %eax, %rsi
addq 0x50(%r14), %rsi
jmp 0x226c5
movl %r12d, %esi
shrl $0x14, %esi
andl $0x3ff, %esi            # imm = 0x3FF
movq 0x3f8e4(%rip), %rdi     # 0x61fb0
callq 0x9310
movsbl %r12b, %esi
movq %rax, %rdi
callq 0x95a0
movq 0x50(%rbp), %rax
decq %rax
cmpq %rax, %r15
jae 0x226fc
movq 0x3f8c0(%rip), %rdi     # 0x61fb0
leaq 0x28711(%rip), %rsi     # 0x4ae08
callq 0x94e0
incq %r15
addq $0x4, %rbx
jmp 0x22663
movq 0x3f8a1(%rip), %rdi     # 0x61fb0
callq 0x9210
movzwl 0xe(%rbp), %ebx
movzwl 0x10(%rbp), %r15d
addw 0xc(%rbp), %bx
movzwl %bx, %r12d
movq 0x68(%r14), %rax
movq %rax, 0x10(%rsp)
cmpl $0x0, 0x90(%r14)
je 0x22754
movq %r14, %rdi
movq %rbp, %rsi
movl %r12d, %edx
xorl %ecx, %ecx
pushq $-0x1
popq %r8
callq 0x24bca
testb %al, %al
je 0x227e8
movw %r15w, 0x8(%rsp)
movq 0x50(%r14), %rax
movl %r12d, %ecx
movb $0x1, %sil
cmpq %rcx, %rax
jbe 0x22a71
movl %ecx, %r15d
notl %r15d
addl %eax, %r15d
movq 0x18(%r14), %rdx
movq 0x8(%rdx), %r8
leaq -0x1(%rax), %rsi
pushq $-0x1
popq %rdx
cmpq %rsi, %r15
jae 0x22791
subl %ecx, %eax
movsbl (%r8,%rax), %edx
movsbl (%r8,%r15), %r13d
movl $0x21212121, 0x1c(%rsp) # imm = 0x21212121
movq 0x58(%r14), %rax
movq 0x8(%rax), %rax
movb (%rax,%r15), %al
leal -0x21(%rax), %ecx
cmpb $0x21, %al
movzbl %cl, %eax
movl $0x0, %ecx
cmovbl %ecx, %eax
cmpb $0x1, 0x84(%r14)
jne 0x227d1
movzbl %al, %eax
leaq 0x42342(%rip), %rcx     # 0x64b10
movb (%rcx,%rax), %al
movzbl %al, %eax
imull $0x1010101, %eax, %ecx  # imm = 0x1010101
movl %ecx, 0x1c(%rsp)
cmpw 0x4(%rbp), %bx
jae 0x2281d
xorl %eax, %eax
jmp 0x2282d
movq 0x180(%r14), %rax
testq %rax, %rax
je 0x227f6
incl (%rax)
movl 0x50(%r14), %edx
movl 0x9c(%r14), %ecx
movzbl 0x85(%r14), %r8d
movq %r13, %rdi
movq %rbp, %rsi
callq 0x24bf2
movl 0xc(%rsp), %ebx
jmp 0x22d6a
movzwl 0x12(%rbp), %ecx
addl %eax, %ecx
cmpl 0x88(%r14), %ecx
setbe %al
movslq %r13d, %r9
movl 0x24(%rbp), %ecx
movl %ecx, 0x24(%rsp)
testl %r12d, %r12d
je 0x22853
cmpb $0x4, %r9b
jne 0x22853
movabsq $0x100000001, %rcx      # imm = 0x100000001
movq %rcx, 0x24(%rbp)
pushq $0x1
popq %rcx
movzwl 0xe(%rbp), %esi
imulq $0x30, %rsi, %rbx
addq 0x18(%rbp), %rbx
testl %ecx, %ecx
jne 0x2286d
cmpl $0x0, 0x28(%rbp)
je 0x229a9
cmpb $0x4, %r9b
sete %sil
movl 0x28(%rbp), %r8d
cmpl %ecx, %r8d
seta %dil
orb %sil, %dil
andb %dil, %al
cmpb $0x1, %al
jne 0x228d4
xorps %xmm0, %xmm0
movups %xmm0, 0x10(%rbx)
movups %xmm0, (%rbx)
cmpb $-0x1, 0x4a(%rbp)
movq 0x180(%r14), %rax
movl %edx, 0x18(%rsp)
movq %r9, 0x30(%rsp)
je 0x22933
testq %rax, %rax
je 0x228b6
incl 0x4(%rax)
leaq 0x10(%rbx), %r8
leaq 0x3c(%rbp), %rdx
leaq 0x2c(%rbp), %rsi
movq 0x10(%rsp), %rdi
movq %rbx, %rcx
callq 0x24d68
jmp 0x22967
movb $0x1, 0x28(%rbx)
cmpl %ecx, %r8d
jbe 0x22a6a
cmpb $0x3, %r13b
jg 0x22a6a
movl 0x24(%rbp), %esi
leal 0x1(%rsi), %ecx
movq 0x180(%r14), %rax
cmpl 0x28(%rbp), %ecx
jne 0x22a2a
testq %rax, %rax
movq 0x10(%rsp), %rdi
je 0x22911
incl 0x4(%rax)
movl 0x24(%rbp), %esi
leaq 0x2c(%rbp), %rdx
movl %r13d, %ecx
callq 0x24e60
movl %eax, 0x24(%rbp)
movl %eax, 0x28(%rbp)
cmpl $-0x1, %eax
je 0x22a6a
incl %eax
jmp 0x22a67
testq %rax, %rax
je 0x2293b
incl 0x4(%rax)
leaq 0x2c(%rbp), %rdx
movq 0x10(%rsp), %rdi
leaq 0x24(%rsp), %rsi
callq 0x24df6
movl 0x24(%rsp), %ecx
movl %ecx, 0x24(%rbp)
testl %eax, %eax
js 0x22967
movl %eax, %eax
movl %ecx, (%rbx,%rax,4)
movl 0x24(%rbp), %ecx
incl %ecx
movl %ecx, 0x10(%rbx,%rax,4)
movl 0x88(%r14), %ecx
movzwl 0x12(%rbp), %eax
subl %eax, %ecx
movq %rbp, %rdi
movl %r13d, %esi
movl 0x18(%rsp), %edx
leaq 0x1c(%rsp), %r8
callq 0x24c7e
movq 0x30(%rsp), %rcx
cmpb $0x3, %cl
jle 0x22a1e
movabsq $0x100000001, %rax      # imm = 0x100000001
movq %rax, 0x24(%rbp)
jmp 0x22a6a
movq 0x10(%rsp), %rcx
movq 0x90(%rcx), %rax
movl (%rax), %eax
movl %eax, (%rbx)
movq 0x90(%rcx), %rax
movl 0x4(%rax), %eax
movl %eax, 0x4(%rbx)
movl %eax, 0x10(%rbx)
movq 0x90(%rcx), %rax
movl 0x8(%rax), %eax
movl %eax, 0x8(%rbx)
movl %eax, 0x14(%rbx)
movq 0x90(%rcx), %rax
movl 0xc(%rax), %eax
movl %eax, 0xc(%rbx)
movl %eax, 0x18(%rbx)
movq 0x90(%rcx), %rax
movl 0x10(%rax), %eax
movl %eax, 0x1c(%rbx)
movl 0x88(%r14), %ecx
movzwl 0x12(%rbp), %eax
subl %eax, %ecx
movq %rbp, %rdi
movl %r13d, %esi
leaq 0x1c(%rsp), %r8
movq %r9, %r13
callq 0x24c7e
movq %r13, %rcx
cmpb $0x3, %cl
jg 0x22a6a
movl (%rbx,%rcx,4), %eax
movl %eax, 0x24(%rbp)
movl 0x10(%rbx,%rcx,4), %eax
jmp 0x22a67
testq %rax, %rax
movq 0x10(%rsp), %rbx
je 0x22a37
incl 0x4(%rax)
leaq 0x2c(%rbp), %rsi
movq %rbx, %rdi
movl %r13d, %edx
callq 0x24ebc
movl %eax, 0x24(%rbp)
movq 0x180(%r14), %rax
testq %rax, %rax
je 0x22a58
incl 0x4(%rax)
leaq 0x3c(%rbp), %rsi
movq %rbx, %rdi
movl %r13d, %edx
callq 0x24ebc
movl %eax, 0x28(%rbp)
testq %r15, %r15
sete %sil
movl %r12d, %edx
movl 0x24(%rbp), %edi
movl 0x28(%rbp), %r13d
cmpl %r13d, %edi
setne %bl
movq 0x50(%rbp), %rax
movq %rax, 0x10(%rsp)
testl %eax, %eax
sete %r15b
movb 0x8c(%r14), %r12b
cmpl $0x0, 0x90(%r14)
je 0x22ace
xorl %ecx, %ecx
cmpl %r13d, %edi
sete %cl
movl %edi, 0x18(%rsp)
movq %r14, %rdi
movb %sil, 0x30(%rsp)
movq %rbp, %rsi
callq 0x24ed8
movl 0x18(%rsp), %edi
movb 0x30(%rsp), %sil
testb %al, %al
je 0x22d1d
andb %sil, %bl
xorb $0x1, %r12b
andb %r12b, %r15b
andb %bl, %r15b
notb %bl
orb %r15b, %bl
testb $0x1, %bl
je 0x22b37
cmpl %r13d, %edi
setne %al
notb %sil
testb %al, %sil
movl 0xc(%rsp), %ebx
movzwl 0x8(%rsp), %r15d
jne 0x22d5a
movq 0x180(%r14), %rax
testq %rax, %rax
movq 0x28(%rsp), %r13
je 0x22b14
incl (%rax)
movl 0x50(%r14), %edx
movl 0x9c(%r14), %ecx
movzbl 0x85(%r14), %r8d
movq %r13, %rdi
movq %rbp, %rsi
callq 0x24bf2
jmp 0x22d6a
cmpb $0x1, 0xb4(%r14)
jne 0x22bcf
cmpb $0x0, 0x94(%r14)
leaq 0x27e96(%rip), %rsi     # 0x4a9ea
leaq 0x27e7b(%rip), %rax     # 0x4a9d6
cmovneq %rax, %rsi
movq 0x3f44a(%rip), %rbx     # 0x61fb0
movq %rbx, %rdi
callq 0x94e0
movq %rax, %rdi
callq 0x9210
incw 0xe(%rbp)
movq 0x18(%r14), %rsi
movq 0x58(%r14), %rdx
xorl %r9d, %r9d
cmpl $0x0, 0x90(%r14)
setg %r9b
movzbl 0x94(%r14), %eax
movzbl 0x70(%r14), %r10d
movq 0x68(%r14), %rcx
movzbl 0x10(%rcx), %r11d
subq $0x8, %rsp
movq %rbp, %rdi
movl 0x28(%rsp), %ecx
movq %rbx, %r8
pushq %r11
pushq %r10
pushq %rax
callq 0x24626
addq $0x20, %rsp
decw 0xe(%rbp)
movq %rbx, %rdi
callq 0x9210
movq 0x180(%r14), %rax
testq %rax, %rax
movq 0x28(%rsp), %r13
je 0x22be4
movb $0x1, 0xb(%rax)
movl 0x24(%rbp), %eax
movl %eax, 0xb8(%r14)
movl 0x28(%rbp), %eax
movl %eax, 0xbc(%r14)
movzwl 0x10(%rbp), %eax
movw %ax, 0xc0(%r14)
shrl $0xe, %eax
movl %eax, 0xc4(%r14)
movq 0x10(%rsp), %rcx
movl %ecx, 0xc8(%r14)
movb 0x70(%r14), %al
movb %al, 0xcc(%r14)
andq $0x0, 0xe8(%r14)
andq $0x0, 0x108(%r14)
movl %ecx, %ebx
movq %rbp, %r15
addq $0x58, %r15
xorl %r12d, %r12d
cmpq %r12, %rbx
je 0x22ce2
movq %r15, %rax
cmpq $0x6, %r12
jb 0x22c73
cmpq $0x15, %r12
ja 0x22c67
movq 0x70(%rbp), %rax
leaq (%rax,%r12,4), %rax
addq $-0x18, %rax
jmp 0x22c73
movq 0x78(%rbp), %rax
leaq (%rax,%r12,4), %rax
addq $-0x58, %rax
movq 0x50(%r14), %rcx
movl (%rax), %eax
notl %eax
shrl $0x14, %eax
orl $0xfffffc00, %eax       # imm = 0xFFFFFC00
addl %eax, %ecx
movl %ecx, 0x3c(%rsp)
movq 0x50(%rsp), %rdi
leaq 0x3c(%rsp), %rsi
callq 0x1bf46
movq %r15, %rax
cmpq $0x6, %r12
jb 0x22cc1
cmpq $0x15, %r12
ja 0x22cb5
movq 0x70(%rbp), %rax
leaq (%rax,%r12,4), %rax
addq $-0x18, %rax
jmp 0x22cc1
movq 0x78(%rbp), %rax
leaq (%rax,%r12,4), %rax
addq $-0x58, %rax
movb (%rax), %al
movb %al, 0xb(%rsp)
movq 0x48(%rsp), %rdi
leaq 0xb(%rsp), %rsi
callq 0x233ce
incq %r12
addq $0x4, %r15
jmp 0x22c41
movq %r14, %rdi
callq 0x2313c
movq 0x68(%r14), %rcx
movq 0x180(%r14), %rax
movq %rcx, 0x110(%r14)
movb $0x1, 0x9(%r14)
testq %rax, %rax
je 0x22d08
incl (%rax)
movl 0x50(%r14), %edx
movl 0x9c(%r14), %ecx
movzbl 0x85(%r14), %r8d
jmp 0x22d43
movq 0x180(%r14), %rax
testq %rax, %rax
je 0x22d2b
incl (%rax)
movl 0x50(%r14), %edx
movl 0x9c(%r14), %ecx
movzbl 0x85(%r14), %r8d
movq 0x28(%rsp), %r13
movq %r13, %rdi
movq %rbp, %rsi
callq 0x24bf2
movl 0xc(%rsp), %ebx
movzwl 0x8(%rsp), %r15d
jmp 0x22d6a
movb $0x0, 0x84(%rbp)
incw 0xe(%rbp)
movq 0x28(%rsp), %r13
movl 0x50(%r14), %edx
movl 0x88(%r14), %ecx
movl 0x9c(%r14), %r8d
movzbl 0x85(%r14), %r9d
movq 0x68(%r14), %rax
leaq 0xf8(%rax), %r10
movzbl 0x10(%rax), %r11d
subq $0x8, %rsp
movq %r13, %rdi
movq 0x48(%rsp), %rsi
pushq %r11
pushq 0xb8(%rax)
pushq %r10
callq 0x24fa0
addq $0x20, %rsp
testb %al, %al
jne 0x22dc1
movq %r13, %rdi
xorl %esi, %esi
callq 0x250e8
movq 0x8(%r13), %rax
cmpq 0x10(%r13), %rax
je 0x22df1
cmpl $0x2, %ebx
je 0x22dd7
cmpl $0x3, %ebx
jne 0x22de6
jmp 0x22df1
movq %r13, %rdi
callq 0x24242
cmpw %r15w, 0x10(%rax)
jne 0x22df1
cmpb $0x1, 0x9(%r14)
jne 0x225d8
addq $0x58, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq