// File: WShabti-Team[P]WShabtiPict/wshabtilib/api/model.cpp
// Function: pictcore::Model::gcd(std::vector<pictcore::Combination*, std::allocator<pictcore::Combination*>>&)
void Model::gcd( ComboCollection &vecCombo )
{
    if( m_parameters.empty() ) return;

    processExclusions( vecCombo );

    fixRowSeeds();

    int maxRange = -1;
    for( ComboCollection::iterator iterC = vecCombo.begin(); iterC != vecCombo.end(); ++iterC )
    {
        if( ( *iterC )->GetRange() > maxRange )
        {
            maxRange = ( *iterC )->GetRange();
        }
    }
    if( maxRange <= 0 ) return;

    GetTask()->AllocWorkbuf( maxRange );

    m_totalCombinations = GlobalZerosCount;

    // main loop: repeat until we've found all required parameter value combinations
    while( GlobalZerosCount > 0 )
    {
        DOUT( L"Main loop: GlobalZerosCount " << GlobalZerosCount << L"\n" );

        if( GetTask()->AbortGeneration() )
        {
            // tear down all the combinations
            for( ComboCollection::iterator i = vecCombo.begin(); i != vecCombo.end(); ++i )
            {
                delete *i;
            }

            throw GenerationError( __FILE__, __LINE__, GenerationCancelled );
        }

        // initialize all parameters to unbound, not on work list
        for( vector<Parameter*>::iterator iter = m_parameters.begin(); iter != m_parameters.end(); ++iter )
        {
            ( *iter )->InitBinding();
        }
        
        int unbound = static_cast<int>( m_parameters.size() );

        // init all combinations bound, counts to zero
        for( ComboCollection::iterator iterC = vecCombo.begin(); iterC != vecCombo.end(); ++iterC )
        {
            ( *iterC )->InitBinding();
        }
        
        // initialize work list to empty
        WorkList worklist;

        // do we have unused seed data?
        // if yes: bind those values, make sure combinations get marked, zero counts (including global) updated
        if( !m_rowSeeds.empty() )
        {
            RowSeed &rowSeed = m_rowSeeds.front();
            for( RowSeed::iterator ir = rowSeed.begin(); ir != rowSeed.end(); ++ir )
            {
                ( ir->first )->MarkPending();
            }
            for( RowSeed::iterator ir = rowSeed.begin(); ir != rowSeed.end(); ++ir )
            {
                // find the parameter in the collection
                Parameter* param = ir->first;
                vector<Parameter*>::iterator found = find( m_parameters.begin(), m_parameters.end(), param );
                assert( found != m_parameters.end() );
                if( found != m_parameters.end() )
                {
                    unbound -= param->Bind( ir->second, worklist );
                }
            }
            m_rowSeeds.pop_front();
        }

        for( int cidx = 0; cidx < static_cast<int>( vecCombo.size() ); ++cidx )
        {
            vecCombo[ cidx ]->Print();
        }

        // Approximate mode must be handled differently from the other modes
        if( m_task->GetGenerationMode() == Approximate )
        {
            // it's a row not an exclusion but Exclusion is a perfect data structure for it
            typedef Exclusion CandidateRow;
            
            CandidateRow candidateRow;

            size_t attempt = 0;
            bool stop = false;
            while( 1 )
            {
                candidateRow = generateRandomRow();

                if( !rowViolatesExclusion( candidateRow ) )
                    break;

                if( ++attempt >= m_task->GetMaxRandomTries() )
                {
                    stop = true;
                    break;
                }
            };
            if( stop ) break; // out of "GlobalZerosCount > 0" loop

            for( CandidateRow::iterator ir = candidateRow.begin(); ir != candidateRow.end(); ++ir )
            {
                ( ir->first )->MarkPending();
            }
            for( CandidateRow::iterator ir = candidateRow.begin(); ir != candidateRow.end(); ++ir )
            {
                // find the parameter in the collection
                Parameter* param = ir->first;
                vector<Parameter*>::iterator found = find( m_parameters.begin(), m_parameters.end(), param );
                assert( found != m_parameters.end() );
                if( found != m_parameters.end() )
                {
                    unbound -= param->Bind( ir->second, worklist );
                }
            }
        }
        // non Approximate aka regular mode
        else
        {
            // loop to build one result vector: while some parameters remain unbound
            while( unbound > 0 )
            {
                if( worklist.IsEmpty() )
                {
                    DOUT( L"Empty worklist: finding a seed combination.\n" );
                    // pick a zero from feasible combination with the most zeros, bind corresponding values
                    int maxZeros = 0;
                    int maxMatch = 0;
                    int ties     = 0;
                    int choice   = -1;
                    for( int cidx = 0; cidx < static_cast<int>( vecCombo.size() ); ++cidx )
                    {
                        if( !vecCombo[ cidx ]->IsFullyBound() )
                        {
                            int open  = 0;
                            int match = 0;

                            // Make sure there's a feasible value set
                            for( int vidx = 0; vidx < vecCombo[ cidx ]->GetRange(); ++vidx )
                            {
                                ComboStatus status = vecCombo[ cidx ]->Feasible( vidx );
                                if( Open == status )
                                {
                                    ++open;
                                }
                                else if( CoveredMatch == status )
                                {
                                    ++match;
                                }
                            }

                            // if combo has the most zeros
                            if( open > maxZeros )
                            {
                                choice   = cidx;
                                ties     = 1;
                                maxZeros = open;
                            }
                            // if number of zeros ties up with some previous choice, pick randomly
                            else if( open == maxZeros
                                 &&  maxZeros > 0
                                 &&  !( rand() % ++ties ) )
                            {
                                choice = cidx;
                            }
                            // no zeros were found anywhere yet, pick the best matching one
                            else if( maxZeros == 0
                                 &&  match > maxMatch )
                            {
                                choice = cidx;
                                ties = 1;
                                maxMatch = match;
                            }
                            // if there's a tie in match, pick randomly
                            else if( maxZeros == 0
                                 &&  match > 0
                                 &&  match == maxMatch
                                 &&  !( rand() % ++ties ) )
                            {
                                choice = cidx;
                            }
                        }
                    } // for cidx
                    assert( choice != -1 );
                    if( -1 == choice )
                    {
                        throw GenerationError( __FILE__, __LINE__, GenerationFailure );
                    }

                    // no combo had any uncovered combinations in it
                    if( 0 == maxZeros )
                    {
                        int totalWeight = 0;
                        int bestValue   = -1;
                        // For each non-excluded value in the bitvec, find total weight
                        for( int vidx = 0; vidx < vecCombo[ choice ]->GetRange(); ++vidx )
                        {
                            if( Excluded != vecCombo[ choice ]->Feasible( vidx ) )
                            {
                                // Pick a value using weighted random choice
                                int weight = vecCombo[ choice ]->Weight( vidx );
                                totalWeight += weight;
                                if( rand() % totalWeight < weight )
                                {
                                    bestValue = vidx;
                                }
                            }
                        }
                        unbound -= vecCombo[ choice ]->Bind( bestValue, worklist );
                    }
                    else
                    {
                        // OK, we picked a combination, now pick a value set
                        vector<int> candidates;
                        for( int vidx = 0; vidx < vecCombo[ choice ]->GetRange(); ++vidx )
                        {
                            if( Open == vecCombo[ choice ]->Feasible( vidx ) )
                            {
                                candidates.push_back( vidx );
                            }
                        }
#if (0)
                        if (candidates.empty())
                        {
                            for (int vidx = 0; vidx < vecCombo[choice]->GetRange(); ++vidx)
                            {
                                if (CoveredMatch == vecCombo[choice]->Feasible(vidx))
                                {
                                    candidates.push_back(vidx);
                                }
                            }
                        }
#endif
                        assert( !candidates.empty() );
                        int zeroVal = candidates[ rand() % candidates.size() ];
                        DOUT( L"Chose value " << zeroVal << L", unbound count was " << unbound << L".\n" );
                        // Bind the values corresponding to the zero
                        unbound -= vecCombo[ choice ]->Bind( zeroVal, worklist );
                        DOUT( L"After combo bind, unbound count was " << unbound << L".\n" );
                    }
                }
                // worklist is NOT empty
                else
                {
                    // pull a parameter from the work list and pick a value
                    Parameter *param = worklist.GetItem();
                    assert( !param->GetBoundCount() );
                    DOUT( L"From worklist " );
                    param->Bind( param->PickValue(), worklist );
                    --unbound;
                }
            } // end: unbound > 0
        } // end: non-Approximate
    }

    m_remainingCombinations = GlobalZerosCount;

    // tear down all the combinations
    for( ComboCollection::iterator i = vecCombo.begin(); i != vecCombo.end(); ++i )
    {
        delete *i;
    }

    resolvePseudoParams();

    // put parameter vector back into original sequence
    sort( m_parameters.begin(), m_parameters.end(), LessThanBySequence() );

    // move results from parameters into this Model
    size_t results = 0;
    for( ParamCollection::iterator ip = m_parameters.begin(); ip != m_parameters.end(); ++ip )
    {
        ( *ip )->GetFirst();
        if( results )
        {
            assert( ( *ip )->GetTempResultCount() == results );
        }
        else
        {
            results = ( *ip )->GetTempResultCount();
        }
    }
    for( size_t n = 0; n < results; ++n )
    {
        ResultRow resultRow;
        for( ParamCollection::iterator ip = m_parameters.begin(); ip != m_parameters.end(); ++ip )
        {
            resultRow.push_back( ( *ip )->GetNext() );
        }

        // remove violating cases, it's needed for preview mode of
        //   generation as in that mode, m_result contains some invalid cases
        bool violatesExclusion = false;

        if( GetTask()->GetGenerationMode() == Preview )
        {
            violatesExclusion = rowViolatesExclusion( resultRow );
        }
        if( !violatesExclusion )
        {
            m_results.push_back( resultRow );
        }
    }

    for( ParamCollection::iterator ip = m_parameters.begin(); ip != m_parameters.end(); ++ip )
    {
        ( *ip )->CleanUp();
    }

    // process all result parameters: mark unknown all result values
    //   that are under or over-specified.
    // only run it on the root; result params should not be part of
    //   any user-defined submodels anyway.
    if( this->GetTask()->GetRootModel() == this )
    {
        markUndefinedValuesInResultParams();
    }
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x4b0, %rsp            # imm = 0x4B0
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq -0x8(%rbp), %rdi
movq %rdi, -0x370(%rbp)
addq $0x8, %rdi
callq 0x1b820
testb $0x1, %al
jne 0x153ad
jmp 0x153b2
jmp 0x16893
movq -0x370(%rbp), %rdi
movq -0x10(%rbp), %rsi
callq 0x168b0
movq -0x370(%rbp), %rdi
callq 0x16ef0
movl $0xffffffff, -0x14(%rbp) # imm = 0xFFFFFFFF
movq -0x10(%rbp), %rdi
callq 0x1b860
movq %rax, -0x20(%rbp)
movq -0x10(%rbp), %rdi
callq 0x1b8d0
movq %rax, -0x28(%rbp)
leaq -0x20(%rbp), %rdi
leaq -0x28(%rbp), %rsi
callq 0x1b890
testb $0x1, %al
jne 0x15402
jmp 0x15439
leaq -0x20(%rbp), %rdi
callq 0x1b900
movq (%rax), %rdi
callq 0x1b920
cmpl -0x14(%rbp), %eax
jle 0x1542c
leaq -0x20(%rbp), %rdi
callq 0x1b900
movq (%rax), %rdi
callq 0x1b920
movl %eax, -0x14(%rbp)
jmp 0x1542e
leaq -0x20(%rbp), %rdi
callq 0x1b940
jmp 0x153e2
cmpl $0x0, -0x14(%rbp)
jg 0x15444
jmp 0x16893
movq -0x370(%rbp), %rdi
callq 0x8f00
movq %rax, %rdi
movl -0x14(%rbp), %esi
callq 0x31e40
movq -0x370(%rbp), %rax
movslq (%rax), %rcx
movq %rcx, 0x138(%rax)
movq -0x370(%rbp), %rax
cmpl $0x0, (%rax)
jle 0x164ac
movq -0x370(%rbp), %rdi
callq 0x8f00
movq %rax, %rdi
callq 0xd6c0
testb $0x1, %al
jne 0x15499
jmp 0x155c8
movq -0x10(%rbp), %rdi
callq 0x1b860
movq %rax, -0x30(%rbp)
movq -0x10(%rbp), %rdi
callq 0x1b8d0
movq %rax, -0x38(%rbp)
leaq -0x30(%rbp), %rdi
leaq -0x38(%rbp), %rsi
callq 0x1b890
testb $0x1, %al
jne 0x154c6
jmp 0x15509
leaq -0x30(%rbp), %rdi
callq 0x1b900
movq (%rax), %rax
movq %rax, -0x378(%rbp)
cmpq $0x0, %rax
je 0x154fc
movq -0x378(%rbp), %rdi
callq 0x8bd0
movq -0x378(%rbp), %rdi
movl $0x40, %esi
callq 0x7600
jmp 0x154fe
leaq -0x30(%rbp), %rdi
callq 0x1b940
jmp 0x154a6
movb $0x1, -0x6d(%rbp)
movl $0x30, %edi
callq 0x7300
movq %rax, -0x388(%rbp)
leaq -0x59(%rbp), %rdi
movq %rdi, -0x380(%rbp)
callq 0x79e0
movq -0x380(%rbp), %rdx
leaq 0x4f105(%rip), %rsi     # 0x64641
leaq -0x58(%rbp), %rdi
callq 0xd700
jmp 0x15547
movq -0x388(%rbp), %rdi
leaq -0x58(%rbp), %rsi
movl $0x7f, %edx
xorl %ecx, %ecx
callq 0xd7b0
jmp 0x15560
movq -0x388(%rbp), %rdi
movb $0x0, -0x6d(%rbp)
leaq 0x7c47e(%rip), %rsi     # 0x919f0
leaq -0x7d89(%rip), %rdx     # 0xd7f0
callq 0x7980
jmp 0x168a5
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x68(%rbp)
movl %eax, -0x6c(%rbp)
jmp 0x155a6
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x68(%rbp)
movl %eax, -0x6c(%rbp)
leaq -0x58(%rbp), %rdi
callq 0x73e0
leaq -0x59(%rbp), %rdi
callq 0x7660
testb $0x1, -0x6d(%rbp)
jne 0x155b7
jmp 0x155c3
movq -0x388(%rbp), %rdi
callq 0x74a0
jmp 0x1689c
movq -0x370(%rbp), %rdi
addq $0x8, %rdi
callq 0x8c90
movq %rax, -0x78(%rbp)
movq -0x370(%rbp), %rdi
addq $0x8, %rdi
callq 0x8cc0
movq %rax, -0x80(%rbp)
leaq -0x78(%rbp), %rdi
leaq -0x80(%rbp), %rsi
callq 0x8cf0
testb $0x1, %al
jne 0x15603
jmp 0x1561f
leaq -0x78(%rbp), %rdi
callq 0x8d30
movq (%rax), %rdi
callq 0x1b960
leaq -0x78(%rbp), %rdi
callq 0x8d70
jmp 0x155dc
movq -0x370(%rbp), %rdi
addq $0x8, %rdi
callq 0x8fd0
movl %eax, -0x84(%rbp)
movq -0x10(%rbp), %rdi
callq 0x1b860
movq %rax, -0x90(%rbp)
movq -0x10(%rbp), %rdi
callq 0x1b8d0
movq %rax, -0x98(%rbp)
leaq -0x90(%rbp), %rdi
leaq -0x98(%rbp), %rsi
callq 0x1b890
testb $0x1, %al
jne 0x1566e
jmp 0x15690
leaq -0x90(%rbp), %rdi
callq 0x1b900
movq (%rax), %rdi
callq 0x1b980
leaq -0x90(%rbp), %rdi
callq 0x1b940
jmp 0x15645
leaq -0xe8(%rbp), %rdi
callq 0x1b9a0
movq -0x370(%rbp), %rdi
addq $0x68, %rdi
callq 0x1b9c0
testb $0x1, %al
jne 0x158f0
movq -0x370(%rbp), %rdi
addq $0x68, %rdi
callq 0x1b9e0
movq %rax, -0xf0(%rbp)
movq -0xf0(%rbp), %rdi
callq 0x1ba10
movq %rax, -0xf8(%rbp)
movq -0xf0(%rbp), %rdi
callq 0x1ba40
movq %rax, -0x100(%rbp)
leaq -0xf8(%rbp), %rdi
leaq -0x100(%rbp), %rsi
callq 0x9130
testb $0x1, %al
jne 0x1570a
jmp 0x15741
leaq -0xf8(%rbp), %rdi
callq 0x9160
movq (%rax), %rdi
callq 0x8d50
jmp 0x15720
jmp 0x15722
leaq -0xf8(%rbp), %rdi
callq 0x9210
jmp 0x156de
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x68(%rbp)
movl %eax, -0x6c(%rbp)
jmp 0x1649b
movq -0xf0(%rbp), %rdi
callq 0x1ba10
movq %rax, -0x108(%rbp)
movq -0xf0(%rbp), %rdi
callq 0x1ba40
movq %rax, -0x110(%rbp)
leaq -0x108(%rbp), %rdi
leaq -0x110(%rbp), %rsi
callq 0x9130
testb $0x1, %al
jne 0x15783
jmp 0x158e0
leaq -0x108(%rbp), %rdi
callq 0x9160
movq -0x370(%rbp), %rdi
movq (%rax), %rax
movq %rax, -0x118(%rbp)
addq $0x8, %rdi
movq %rdi, -0x398(%rbp)
callq 0x8c90
movq -0x398(%rbp), %rdi
movq %rax, -0x128(%rbp)
callq 0x8cc0
movq %rax, -0x130(%rbp)
movq -0x128(%rbp), %rdi
movq -0x130(%rbp), %rsi
leaq -0x118(%rbp), %rdx
callq 0x91c0
movq %rax, -0x390(%rbp)
jmp 0x157ed
movq -0x370(%rbp), %rdi
movq -0x390(%rbp), %rax
movq %rax, -0x120(%rbp)
addq $0x8, %rdi
callq 0x8cc0
movq %rax, -0x138(%rbp)
leaq -0x120(%rbp), %rdi
leaq -0x138(%rbp), %rsi
callq 0x8cf0
testb $0x1, %al
jne 0x1582b
jmp 0x1582d
jmp 0x1584c
leaq 0x4eeb3(%rip), %rdi     # 0x646e7
leaq 0x4ee06(%rip), %rsi     # 0x64641
movl $0xa1, %edx
leaq 0x4eebc(%rip), %rcx     # 0x64703
callq 0x7450
movq -0x370(%rbp), %rdi
addq $0x8, %rdi
callq 0x8cc0
movq %rax, -0x140(%rbp)
leaq -0x120(%rbp), %rdi
leaq -0x140(%rbp), %rsi
callq 0x8cf0
testb $0x1, %al
jne 0x1587c
jmp 0x158cd
movq -0x118(%rbp), %rax
movq %rax, -0x3a8(%rbp)
leaq -0x108(%rbp), %rdi
callq 0x9160
movq -0x3a8(%rbp), %rdi
movl 0x8(%rax), %esi
leaq -0xe8(%rbp), %rdx
callq 0x2d2e0
movb %al, -0x399(%rbp)
jmp 0x158b4
movb -0x399(%rbp), %al
andb $0x1, %al
movzbl %al, %ecx
movl -0x84(%rbp), %eax
subl %ecx, %eax
movl %eax, -0x84(%rbp)
jmp 0x158cf
leaq -0x108(%rbp), %rdi
callq 0x9210
jmp 0x15754
movq -0x370(%rbp), %rdi
addq $0x68, %rdi
callq 0x1ba70
movl $0x0, -0x144(%rbp)
movl -0x144(%rbp), %eax
movl %eax, -0x3ac(%rbp)
movq -0x10(%rbp), %rdi
callq 0x1baa0
movq %rax, %rcx
movl -0x3ac(%rbp), %eax
cmpl %ecx, %eax
jge 0x15949
movq -0x10(%rbp), %rdi
movslq -0x144(%rbp), %rsi
callq 0x1bac0
movq (%rax), %rdi
callq 0x8c20
jmp 0x15936
jmp 0x15938
movl -0x144(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x144(%rbp)
jmp 0x158fa
movq -0x370(%rbp), %rax
movq 0x148(%rax), %rdi
callq 0xb310
movl %eax, -0x3b0(%rbp)
jmp 0x15964
movl -0x3b0(%rbp), %eax
cmpl $0x2, %eax
jne 0x15cf9
leaq -0x198(%rbp), %rdi
callq 0xb6c0
jmp 0x15981
movq $0x0, -0x1a0(%rbp)
movb $0x0, -0x1a1(%rbp)
jmp 0x15995
movq -0x370(%rbp), %rsi
leaq -0x1f8(%rbp), %rdi
callq 0x17490
jmp 0x159aa
leaq -0x198(%rbp), %rdi
movq %rdi, -0x3c0(%rbp)
leaq -0x1f8(%rbp), %rsi
movq %rsi, -0x3c8(%rbp)
callq 0x1bae0
movq -0x3c8(%rbp), %rdi
callq 0xbc70
movq -0x370(%rbp), %rdi
movq -0x3c0(%rbp), %rsi
callq 0x176d0
movb %al, -0x3b1(%rbp)
jmp 0x159f2
movb -0x3b1(%rbp), %al
testb $0x1, %al
jne 0x15a1d
jmp 0x159fe
jmp 0x15a72
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x68(%rbp)
movl %eax, -0x6c(%rbp)
leaq -0x198(%rbp), %rdi
callq 0xbc70
jmp 0x1649b
movq -0x370(%rbp), %rax
movq -0x1a0(%rbp), %rcx
incq %rcx
movq %rcx, -0x3d8(%rbp)
movq %rcx, -0x1a0(%rbp)
movq 0x148(%rax), %rdi
callq 0x1bb30
movq %rax, -0x3d0(%rbp)
jmp 0x15a51
movq -0x3d8(%rbp), %rax
movq -0x3d0(%rbp), %rcx
cmpq %rcx, %rax
jb 0x15a6d
movb $0x1, -0x1a1(%rbp)
jmp 0x15a72
jmp 0x15993
testb $0x1, -0x1a1(%rbp)
je 0x15a8a
movl $0x6, -0x1fc(%rbp)
jmp 0x15cd8
leaq -0x198(%rbp), %rdi
callq 0x9090
movq %rax, -0x3e0(%rbp)
jmp 0x15a9f
movq -0x3e0(%rbp), %rax
movq %rax, -0x208(%rbp)
leaq -0x198(%rbp), %rdi
callq 0x90c0
movq %rax, -0x3e8(%rbp)
jmp 0x15ac2
movq -0x3e8(%rbp), %rax
movq %rax, -0x210(%rbp)
leaq -0x208(%rbp), %rdi
leaq -0x210(%rbp), %rsi
callq 0x9130
testb $0x1, %al
jne 0x15ae9
jmp 0x15b0f
leaq -0x208(%rbp), %rdi
callq 0x9160
movq (%rax), %rdi
callq 0x8d50
jmp 0x15aff
jmp 0x15b01
leaq -0x208(%rbp), %rdi
callq 0x9210
jmp 0x15aad
leaq -0x198(%rbp), %rdi
callq 0x9090
movq %rax, -0x3f0(%rbp)
jmp 0x15b24
movq -0x3f0(%rbp), %rax
movq %rax, -0x218(%rbp)
leaq -0x198(%rbp), %rdi
callq 0x90c0
movq %rax, -0x3f8(%rbp)
jmp 0x15b47
movq -0x3f8(%rbp), %rax
movq %rax, -0x220(%rbp)
leaq -0x218(%rbp), %rdi
leaq -0x220(%rbp), %rsi
callq 0x9130
testb $0x1, %al
jne 0x15b71
jmp 0x15cce
leaq -0x218(%rbp), %rdi
callq 0x9160
movq -0x370(%rbp), %rdi
movq (%rax), %rax
movq %rax, -0x228(%rbp)
addq $0x8, %rdi
movq %rdi, -0x408(%rbp)
callq 0x8c90
movq -0x408(%rbp), %rdi
movq %rax, -0x238(%rbp)
callq 0x8cc0
movq %rax, -0x240(%rbp)
movq -0x238(%rbp), %rdi
movq -0x240(%rbp), %rsi
leaq -0x228(%rbp), %rdx
callq 0x91c0
movq %rax, -0x400(%rbp)
jmp 0x15bdb
movq -0x370(%rbp), %rdi
movq -0x400(%rbp), %rax
movq %rax, -0x230(%rbp)
addq $0x8, %rdi
callq 0x8cc0
movq %rax, -0x248(%rbp)
leaq -0x230(%rbp), %rdi
leaq -0x248(%rbp), %rsi
callq 0x8cf0
testb $0x1, %al
jne 0x15c19
jmp 0x15c1b
jmp 0x15c3a
leaq 0x4eac5(%rip), %rdi     # 0x646e7
leaq 0x4ea18(%rip), %rsi     # 0x64641
movl $0xd1, %edx
leaq 0x4eace(%rip), %rcx     # 0x64703
callq 0x7450
movq -0x370(%rbp), %rdi
addq $0x8, %rdi
callq 0x8cc0
movq %rax, -0x250(%rbp)
leaq -0x230(%rbp), %rdi
leaq -0x250(%rbp), %rsi
callq 0x8cf0
testb $0x1, %al
jne 0x15c6a
jmp 0x15cbb
movq -0x228(%rbp), %rax
movq %rax, -0x418(%rbp)
leaq -0x218(%rbp), %rdi
callq 0x9160
movq -0x418(%rbp), %rdi
movl 0x8(%rax), %esi
leaq -0xe8(%rbp), %rdx
callq 0x2d2e0
movb %al, -0x409(%rbp)
jmp 0x15ca2
movb -0x409(%rbp), %al
andb $0x1, %al
movzbl %al, %ecx
movl -0x84(%rbp), %eax
subl %ecx, %eax
movl %eax, -0x84(%rbp)
jmp 0x15cbd
leaq -0x218(%rbp), %rdi
callq 0x9210
jmp 0x15b32
movl $0x0, -0x1fc(%rbp)
leaq -0x198(%rbp), %rdi
callq 0xbc70
movl -0x1fc(%rbp), %eax
testl %eax, %eax
jne 0x1647c
jmp 0x15cf4
jmp 0x16472
jmp 0x15cfb
cmpl $0x0, -0x84(%rbp)
jle 0x16470
leaq -0xe8(%rbp), %rdi
callq 0x1bb50
movb %al, -0x419(%rbp)
jmp 0x15d1c
movb -0x419(%rbp), %al
testb $0x1, %al
jne 0x15d2b
jmp 0x163c0
movl $0x0, -0x254(%rbp)
movl $0x0, -0x258(%rbp)
movl $0x0, -0x25c(%rbp)
movl $0xffffffff, -0x260(%rbp) # imm = 0xFFFFFFFF
movl $0x0, -0x264(%rbp)
movl -0x264(%rbp), %eax
movl %eax, -0x420(%rbp)
movq -0x10(%rbp), %rdi
callq 0x1baa0
movq %rax, %rcx
movl -0x420(%rbp), %eax
cmpl %ecx, %eax
jge 0x15fac
movq -0x10(%rbp), %rdi
movslq -0x264(%rbp), %rsi
callq 0x1bac0
movq (%rax), %rdi
callq 0x1bb70
movb %al, -0x421(%rbp)
jmp 0x15da3
movb -0x421(%rbp), %al
testb $0x1, %al
jne 0x15f96
jmp 0x15db3
movl $0x0, -0x268(%rbp)
movl $0x0, -0x26c(%rbp)
movl $0x0, -0x270(%rbp)
movl -0x270(%rbp), %eax
movl %eax, -0x42c(%rbp)
movq -0x10(%rbp), %rdi
movslq -0x264(%rbp), %rsi
callq 0x1bac0
movq (%rax), %rdi
callq 0x1b920
movl %eax, -0x428(%rbp)
jmp 0x15dfd
movl -0x42c(%rbp), %eax
movl -0x428(%rbp), %ecx
cmpl %ecx, %eax
jge 0x15e92
movq -0x10(%rbp), %rdi
movslq -0x264(%rbp), %rsi
callq 0x1bac0
movq (%rax), %rdi
movl -0x270(%rbp), %esi
callq 0x8320
movl %eax, -0x430(%rbp)
jmp 0x15e37
movl -0x430(%rbp), %eax
movl %eax, -0x274(%rbp)
xorl %eax, %eax
cmpl -0x274(%rbp), %eax
jne 0x15e5e
movl -0x268(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x268(%rbp)
jmp 0x15e7c
movl $0x1, %eax
cmpl -0x274(%rbp), %eax
jne 0x15e7a
movl -0x26c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x26c(%rbp)
jmp 0x15e7c
jmp 0x15e7e
movl -0x270(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x270(%rbp)
jmp 0x15dd1
movl -0x268(%rbp), %eax
cmpl -0x254(%rbp), %eax
jle 0x15ec7
movl -0x264(%rbp), %eax
movl %eax, -0x260(%rbp)
movl $0x1, -0x25c(%rbp)
movl -0x268(%rbp), %eax
movl %eax, -0x254(%rbp)
jmp 0x15f94
movl -0x268(%rbp), %eax
cmpl -0x254(%rbp), %eax
jne 0x15f0b
cmpl $0x0, -0x254(%rbp)
jle 0x15f0b
callq 0x7170
movl -0x25c(%rbp), %ecx
addl $0x1, %ecx
movl %ecx, -0x25c(%rbp)
cltd
idivl %ecx
cmpl $0x0, %edx
jne 0x15f0b
movl -0x264(%rbp), %eax
movl %eax, -0x260(%rbp)
jmp 0x15f92
cmpl $0x0, -0x254(%rbp)
jne 0x15f46
movl -0x26c(%rbp), %eax
cmpl -0x258(%rbp), %eax
jle 0x15f46
movl -0x264(%rbp), %eax
movl %eax, -0x260(%rbp)
movl $0x1, -0x25c(%rbp)
movl -0x26c(%rbp), %eax
movl %eax, -0x258(%rbp)
jmp 0x15f90
cmpl $0x0, -0x254(%rbp)
jne 0x15f8e
cmpl $0x0, -0x26c(%rbp)
jle 0x15f8e
movl -0x26c(%rbp), %eax
cmpl -0x258(%rbp), %eax
jne 0x15f8e
callq 0x7170
movl -0x25c(%rbp), %ecx
addl $0x1, %ecx
movl %ecx, -0x25c(%rbp)
cltd
idivl %ecx
cmpl $0x0, %edx
jne 0x15f8e
movl -0x264(%rbp), %eax
movl %eax, -0x260(%rbp)
jmp 0x15f90
jmp 0x15f92
jmp 0x15f94
jmp 0x15f96
jmp 0x15f98
movl -0x264(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x264(%rbp)
jmp 0x15d5d
cmpl $-0x1, -0x260(%rbp)
je 0x15fb7
jmp 0x15fd6
leaq 0x4e772(%rip), %rdi     # 0x64730
leaq 0x4e67c(%rip), %rsi     # 0x64641
movl $0x11b, %edx            # imm = 0x11B
leaq 0x4e732(%rip), %rcx     # 0x64703
callq 0x7450
movl $0xffffffff, %eax       # imm = 0xFFFFFFFF
cmpl -0x260(%rbp), %eax
jne 0x160c1
movb $0x1, -0x29a(%rbp)
movl $0x30, %edi
callq 0x7300
movq %rax, -0x440(%rbp)
leaq -0x299(%rbp), %rdi
movq %rdi, -0x438(%rbp)
callq 0x79e0
movq -0x438(%rbp), %rdx
leaq 0x4e621(%rip), %rsi     # 0x64641
leaq -0x298(%rbp), %rdi
callq 0xd700
jmp 0x1602e
movq -0x440(%rbp), %rdi
leaq -0x298(%rbp), %rsi
movl $0x11e, %edx            # imm = 0x11E
movl $0x2, %ecx
callq 0xd7b0
jmp 0x1604d
movq -0x440(%rbp), %rdi
movb $0x0, -0x29a(%rbp)
leaq 0x7b98e(%rip), %rsi     # 0x919f0
leaq -0x8879(%rip), %rdx     # 0xd7f0
callq 0x7980
jmp 0x168a5
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x68(%rbp)
movl %eax, -0x6c(%rbp)
jmp 0x16099
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x68(%rbp)
movl %eax, -0x6c(%rbp)
leaq -0x298(%rbp), %rdi
callq 0x73e0
leaq -0x299(%rbp), %rdi
callq 0x7660
testb $0x1, -0x29a(%rbp)
jne 0x160b0
jmp 0x160bc
movq -0x440(%rbp), %rdi
callq 0x74a0
jmp 0x1649b
xorl %eax, %eax
cmpl -0x254(%rbp), %eax
jne 0x16224
movl $0x0, -0x2a0(%rbp)
movl $0xffffffff, -0x2a4(%rbp) # imm = 0xFFFFFFFF
movl $0x0, -0x2a8(%rbp)
movl -0x2a8(%rbp), %eax
movl %eax, -0x448(%rbp)
movq -0x10(%rbp), %rdi
movslq -0x260(%rbp), %rsi
callq 0x1bac0
movq (%rax), %rdi
callq 0x1b920
movl %eax, -0x444(%rbp)
jmp 0x16119
movl -0x448(%rbp), %eax
movl -0x444(%rbp), %ecx
cmpl %ecx, %eax
jge 0x161de
movq -0x10(%rbp), %rdi
movslq -0x260(%rbp), %rsi
callq 0x1bac0
movq (%rax), %rdi
movl -0x2a8(%rbp), %esi
callq 0x8320
movl %eax, -0x44c(%rbp)
jmp 0x16153
movl -0x44c(%rbp), %ecx
movl $0x2, %eax
cmpl %ecx, %eax
je 0x161c8
movq -0x10(%rbp), %rdi
movslq -0x260(%rbp), %rsi
callq 0x1bac0
movq (%rax), %rdi
movl -0x2a8(%rbp), %esi
callq 0x8450
movl %eax, -0x450(%rbp)
jmp 0x16188
movl -0x450(%rbp), %eax
movl %eax, -0x2ac(%rbp)
movl -0x2ac(%rbp), %eax
addl -0x2a0(%rbp), %eax
movl %eax, -0x2a0(%rbp)
callq 0x7170
cltd
idivl -0x2a0(%rbp)
cmpl -0x2ac(%rbp), %edx
jge 0x161c6
movl -0x2a8(%rbp), %eax
movl %eax, -0x2a4(%rbp)
jmp 0x161c8
jmp 0x161ca
movl -0x2a8(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x2a8(%rbp)
jmp 0x160ed
movq -0x10(%rbp), %rdi
movslq -0x260(%rbp), %rsi
callq 0x1bac0
movq (%rax), %rdi
movl -0x2a4(%rbp), %esi
leaq -0xe8(%rbp), %rdx
callq 0x7fe0
movl %eax, -0x454(%rbp)
jmp 0x1620b
movl -0x454(%rbp), %ecx
movl -0x84(%rbp), %eax
subl %ecx, %eax
movl %eax, -0x84(%rbp)
jmp 0x163bb
leaq -0x2c8(%rbp), %rdi
callq 0x1bbb0
movl $0x0, -0x2cc(%rbp)
movl -0x2cc(%rbp), %eax
movl %eax, -0x45c(%rbp)
movq -0x10(%rbp), %rdi
movslq -0x260(%rbp), %rsi
callq 0x1bac0
movq (%rax), %rdi
callq 0x1b920
movl %eax, -0x458(%rbp)
jmp 0x16266
movl -0x45c(%rbp), %eax
movl -0x458(%rbp), %ecx
cmpl %ecx, %eax
jge 0x162f2
movq -0x10(%rbp), %rdi
movslq -0x260(%rbp), %rsi
callq 0x1bac0
movq (%rax), %rdi
movl -0x2cc(%rbp), %esi
callq 0x8320
movl %eax, -0x460(%rbp)
jmp 0x1629c
movl -0x460(%rbp), %ecx
xorl %eax, %eax
cmpl %ecx, %eax
jne 0x162dc
leaq -0x2c8(%rbp), %rdi
leaq -0x2cc(%rbp), %rsi
callq 0x1bbd0
jmp 0x162bd
jmp 0x162dc
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x68(%rbp)
movl %eax, -0x6c(%rbp)
leaq -0x2c8(%rbp), %rdi
callq 0x1bca0
jmp 0x1649b
jmp 0x162de
movl -0x2cc(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x2cc(%rbp)
jmp 0x1623a
leaq -0x2c8(%rbp), %rdi
callq 0x1bc40
xorb $-0x1, %al
testb $0x1, %al
jne 0x16306
jmp 0x16308
jmp 0x16327
leaq 0x4e42e(%rip), %rdi     # 0x6473d
leaq 0x4e32b(%rip), %rsi     # 0x64641
movl $0x14d, %edx            # imm = 0x14D
leaq 0x4e3e1(%rip), %rcx     # 0x64703
callq 0x7450
callq 0x7170
cltq
movq %rax, -0x470(%rbp)
leaq -0x2c8(%rbp), %rdi
movq %rdi, -0x478(%rbp)
callq 0x9360
movq -0x478(%rbp), %rdi
movq %rax, %rcx
movq -0x470(%rbp), %rax
xorl %edx, %edx
divq %rcx
movq %rdx, %rsi
callq 0x1bc80
movl (%rax), %eax
movl %eax, -0x2d0(%rbp)
movq -0x10(%rbp), %rdi
movslq -0x260(%rbp), %rsi
callq 0x1bac0
movq (%rax), %rdi
movl -0x2d0(%rbp), %esi
leaq -0xe8(%rbp), %rdx
callq 0x7fe0
movl %eax, -0x464(%rbp)
jmp 0x1639b
movl -0x464(%rbp), %ecx
movl -0x84(%rbp), %eax
subl %ecx, %eax
movl %eax, -0x84(%rbp)
leaq -0x2c8(%rbp), %rdi
callq 0x1bca0
jmp 0x1646b
leaq -0xe8(%rbp), %rdi
callq 0x32720
movq %rax, -0x480(%rbp)
jmp 0x163d5
movq -0x480(%rbp), %rax
movq %rax, -0x2d8(%rbp)
movq -0x2d8(%rbp), %rdi
callq 0x8e90
movb %al, -0x481(%rbp)
jmp 0x163f7
movb -0x481(%rbp), %al
xorb $-0x1, %al
testb $0x1, %al
jne 0x16405
jmp 0x16407
jmp 0x16426
leaq 0x4e343(%rip), %rdi     # 0x64751
leaq 0x4e22c(%rip), %rsi     # 0x64641
movl $0x15a, %edx            # imm = 0x15A
leaq 0x4e2e2(%rip), %rcx     # 0x64703
callq 0x7450
movq -0x2d8(%rbp), %rdi
movq %rdi, -0x490(%rbp)
callq 0x2d480
movl %eax, -0x488(%rbp)
jmp 0x16441
movl -0x488(%rbp), %esi
movq -0x490(%rbp), %rdi
leaq -0xe8(%rbp), %rdx
callq 0x2d2e0
jmp 0x1645c
movl -0x84(%rbp), %eax
addl $-0x1, %eax
movl %eax, -0x84(%rbp)
jmp 0x15cfb
jmp 0x16472
movl $0x0, -0x1fc(%rbp)
leaq -0xe8(%rbp), %rdi
callq 0x1bd00
movl -0x1fc(%rbp), %eax
testl %eax, %eax
je 0x16496
jmp 0x16494
jmp 0x164ac
jmp 0x1546c
leaq -0xe8(%rbp), %rdi
callq 0x1bd00
jmp 0x1689c
movq -0x370(%rbp), %rax
movslq (%rax), %rcx
movq %rcx, 0x140(%rax)
movq -0x10(%rbp), %rdi
callq 0x1b860
movq %rax, -0x2e0(%rbp)
movq -0x10(%rbp), %rdi
callq 0x1b8d0
movq %rax, -0x2e8(%rbp)
leaq -0x2e0(%rbp), %rdi
leaq -0x2e8(%rbp), %rsi
callq 0x1b890
testb $0x1, %al
jne 0x164f6
jmp 0x1653f
leaq -0x2e0(%rbp), %rdi
callq 0x1b900
movq (%rax), %rax
movq %rax, -0x498(%rbp)
cmpq $0x0, %rax
je 0x1652f
movq -0x498(%rbp), %rdi
callq 0x8bd0
movq -0x498(%rbp), %rdi
movl $0x40, %esi
callq 0x7600
jmp 0x16531
leaq -0x2e0(%rbp), %rdi
callq 0x1b940
jmp 0x164cd
movq -0x370(%rbp), %rdi
callq 0x17760
movq -0x370(%rbp), %rdi
addq $0x8, %rdi
callq 0x8c90
movq -0x370(%rbp), %rdi
movq %rax, -0x2f0(%rbp)
addq $0x8, %rdi
callq 0x8cc0
movq %rax, -0x2f8(%rbp)
movq -0x2f0(%rbp), %rdi
movq -0x2f8(%rbp), %rsi
callq 0x1bd20
movq -0x370(%rbp), %rdi
movq $0x0, -0x308(%rbp)
addq $0x8, %rdi
callq 0x8c90
movq %rax, -0x310(%rbp)
movq -0x370(%rbp), %rdi
addq $0x8, %rdi
callq 0x8cc0
movq %rax, -0x318(%rbp)
leaq -0x310(%rbp), %rdi
leaq -0x318(%rbp), %rsi
callq 0x8cf0
testb $0x1, %al
jne 0x165e1
jmp 0x16671
leaq -0x310(%rbp), %rdi
callq 0x8d30
movq (%rax), %rdi
callq 0x1bd60
cmpq $0x0, -0x308(%rbp)
je 0x16641
leaq -0x310(%rbp), %rdi
callq 0x8d30
movq (%rax), %rdi
callq 0x1bda0
cltq
cmpq -0x308(%rbp), %rax
jne 0x16620
jmp 0x1663f
leaq 0x4e142(%rip), %rdi     # 0x64769
leaq 0x4e013(%rip), %rsi     # 0x64641
movl $0x177, %edx            # imm = 0x177
leaq 0x4e0c9(%rip), %rcx     # 0x64703
callq 0x7450
jmp 0x1665e
leaq -0x310(%rbp), %rdi
callq 0x8d30
movq (%rax), %rdi
callq 0x1bda0
cltq
movq %rax, -0x308(%rbp)
jmp 0x16660
leaq -0x310(%rbp), %rdi
callq 0x8d70
jmp 0x165ae
movq $0x0, -0x320(%rbp)
movq -0x320(%rbp), %rax
cmpq -0x308(%rbp), %rax
jae 0x167fe
leaq -0x338(%rbp), %rdi
callq 0x1bdd0
movq -0x370(%rbp), %rdi
addq $0x8, %rdi
callq 0x8c90
movq %rax, -0x340(%rbp)
movq -0x370(%rbp), %rdi
addq $0x8, %rdi
callq 0x8cc0
movq %rax, -0x348(%rbp)
leaq -0x340(%rbp), %rdi
leaq -0x348(%rbp), %rsi
callq 0x8cf0
testb $0x1, %al
jne 0x166e3
jmp 0x16750
leaq -0x340(%rbp), %rdi
callq 0x8d30
movq (%rax), %rdi
callq 0x1be20
movq %rax, -0x4a0(%rbp)
jmp 0x16700
movq -0x4a0(%rbp), %rax
movq %rax, -0x350(%rbp)
leaq -0x338(%rbp), %rdi
leaq -0x350(%rbp), %rsi
callq 0x1bdf0
jmp 0x16723
jmp 0x16725
leaq -0x340(%rbp), %rdi
callq 0x8d70
jmp 0x166b3
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x68(%rbp)
movl %eax, -0x6c(%rbp)
leaq -0x338(%rbp), %rdi
callq 0x1bed0
jmp 0x1689c
movq -0x370(%rbp), %rdi
movb $0x0, -0x351(%rbp)
callq 0x8f00
movq %rax, -0x4a8(%rbp)
jmp 0x1676c
movq -0x4a8(%rbp), %rdi
callq 0xb310
movl %eax, -0x4ac(%rbp)
jmp 0x16780
movl -0x4ac(%rbp), %eax
cmpl $0x1, %eax
jne 0x167b4
movq -0x370(%rbp), %rdi
leaq -0x338(%rbp), %rsi
callq 0x17a30
movb %al, -0x4ad(%rbp)
jmp 0x167a6
movb -0x4ad(%rbp), %al
andb $0x1, %al
movb %al, -0x351(%rbp)
testb $0x1, -0x351(%rbp)
jne 0x167db
movq -0x370(%rbp), %rdi
addq $0xd0, %rdi
leaq -0x338(%rbp), %rsi
callq 0x1be60
jmp 0x167d9
jmp 0x167db
leaq -0x338(%rbp), %rdi
callq 0x1bed0
movq -0x320(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x320(%rbp)
jmp 0x1667c
movq -0x370(%rbp), %rdi
addq $0x8, %rdi
callq 0x8c90
movq %rax, -0x360(%rbp)
movq -0x370(%rbp), %rdi
addq $0x8, %rdi
callq 0x8cc0
movq %rax, -0x368(%rbp)
leaq -0x360(%rbp), %rdi
leaq -0x368(%rbp), %rsi
callq 0x8cf0
testb $0x1, %al
jne 0x16845
jmp 0x16867
leaq -0x360(%rbp), %rdi
callq 0x8d30
movq (%rax), %rdi
callq 0x2d290
leaq -0x360(%rbp), %rdi
callq 0x8d70
jmp 0x16815
movq -0x370(%rbp), %rdi
callq 0x8f00
movq %rax, %rdi
callq 0x1bf30
movq -0x370(%rbp), %rcx
cmpq %rcx, %rax
jne 0x16893
movq -0x370(%rbp), %rdi
callq 0x17b40
addq $0x4b0, %rsp            # imm = 0x4B0
popq %rbp
retq
movq -0x68(%rbp), %rdi
callq 0x79d0
nopw %cs:(%rax,%rax)