// File: jBlinden[P]private-codis/ProtocolClient.cpp
// Function: RunClientProtocol(CSocket*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>)
void RunClientProtocol(CSocket *socket, string pArgsFile, string clientDataDir)
{
  ClientLog("starting client protocol");

#if !OPTIMAL
  ClientLog("Reading in protocol arguments");
#endif

  ifstream in;
  in.open(pArgsFile, ios::in | ios::binary);
  struct ProtocolArgs pArgs(in);

  in.close();

#if !OPTIMAL
  ClientLog("Reading in receiver OTs");
#endif

  ifstream rOTFile1;
  rOTFile1.open(clientDataDir + "rOT.txt", ios::in | ios::binary);

  ReceiverOTCorrelation **FSM1_RC = ReadInReceiverOTsFSM1(rOTFile1, pArgs);
  ReceiverOTCorrelation **FSM2_RC = ReadInReceiverOTsFSM2(rOTFile1, pArgs);

  rOTFile1.close();

#if !OPTIMAL
  ClientLog("Finished Reading in OTs");
#endif

  uint32_t N = pArgs.N;
  uint32_t C = pArgs.C;
  uint8_t* bits_per_component = pArgs.bits_per_component;

#if !OPTIMAL
  cout << "N: " << N << " C: " << C << endl;
#endif

  ifstream queryFile;
  queryFile.open(clientDataDir + "query.txt");
  uint32_t *query = ReadInEntry(queryFile, C);
  queryFile.close();

#if VERBOSE
  cout << "Query: ";
  for (int i = 0; i < C; i++)
  {
    cout << query[i] << " ";
  }
  cout << endl;
#endif

#if !OPTIMAL
  ClientLog("Creating clients states");
#endif

  uint8_t **client_states = new uint8_t *[N];
  for (int i = 0; i < N; i++)
  {
    client_states[i] = new uint8_t[C];
    for (int j = 0; j < C; j++)
    {
      client_states[i][j] = 0; //Default state is 0
    }
  }

#if !OPTIMAL
  ClientLog("Starting first FSM");

  cout << pArgs.FSM1_rounds << endl;
  for (int i = 0; i < pArgs.FSM1_rounds; i++)
  {
    cout << i << " : " << (uint32_t)pArgs.FSM1_steps[i] << endl;
  }
#endif

  int l = 0;
  int smallest_number_of_bits = 0;
  for (int round = 0; round < pArgs.FSM1_rounds; round++)
  {
    uint8_t concurrent_iterations = pArgs.FSM1_steps[round];
    uint8_t all_ones_string = (uint8_t)((1 << concurrent_iterations) - 1);
    uint8_t pow_iterations = (uint8_t)((1 << concurrent_iterations));
    uint8_t pos_states = 2 * pow_iterations;

    if (l >= bits_per_component[smallest_number_of_bits])
    {
      while(l >= bits_per_component[smallest_number_of_bits])
        smallest_number_of_bits ++;
    }
    uint8_t number_of_higher_bit_entries = C - smallest_number_of_bits;
    uint8_t *choices = new uint8_t[N * number_of_higher_bit_entries * concurrent_iterations];
    
    for (int i = 0; i < N; i++)
    {
      for (int j = 0; j < number_of_higher_bit_entries; j++)
      {
          
        uint8_t postImageJ = j + C - number_of_higher_bit_entries;
        uint8_t query_bits = (query[postImageJ] >> l) & all_ones_string;
        choices[number_of_higher_bit_entries * i + j] = pow_iterations * client_states[i][postImageJ] + query_bits;
      }
    }

#if !OPTIMAL
      ClientLog("Created Choice bits");
#endif
  
      
    uint8_t *rMsg = new uint8_t[N * number_of_higher_bit_entries];
    ConstructOTReceiverMsg(rMsg, *(FSM1_RC[round]), choices, N * number_of_higher_bit_entries);

      
    SendLargePacked(socket, 1 + concurrent_iterations, N * number_of_higher_bit_entries, rMsg);

   
    uint8_t *sMsg = new uint8_t[N * number_of_higher_bit_entries * pos_states];
    ReceiveLargePacked(socket, 1, N * number_of_higher_bit_entries * pos_states, sMsg);

      
    uint8_t *msgs2 = new uint8_t[N * number_of_higher_bit_entries];
    RecoverReceiverMsg(msgs2, *(FSM1_RC[round]), choices, sMsg, N * number_of_higher_bit_entries, 1, bits_FSM1);

#if !OPTIMAL
      ClientLog("Finished One Round");
#endif
    for (int i = 0; i < N; i++)
    {
      for (int j = 0; j < number_of_higher_bit_entries; j++)
      {
        client_states[i][j + C - number_of_higher_bit_entries] = msgs2[number_of_higher_bit_entries * i + j];
      }
    }
    delete[] choices;
    delete[] msgs2;
    delete[] rMsg;
    delete[] sMsg;

    l += concurrent_iterations;
  }

#if !OPTIMAL
  ClientLog("Finished first FSM");
#endif

#if VERBOSE
  for (int i = 0; i < N; i++)
  {
    cout << "Database entry: " << i << endl;
    cout << "DB   : ";
    for (int j = 0; j < C; j++)
    {
      cout << 0 << ", ";
    }
    cout << endl;
    cout << "Query: ";
    for (int j = 0; j < C; j++)
    {
      cout << query[j] << ", ";
    }
    cout << endl;
    cout << "Equal: ";
    for (int j = 0; j < C; j++)
    {
      cout << (uint32_t)client_states[i][j] << ", ";
    }
    cout << endl;
    cout << "Actual: ";
    for (int j = 0; j < C; j++)
    {
      uint32_t value = (uint32_t)client_states[i][j];
      uint8_t accept_state = 0;

      if (accept_state == 1)
      {
        cout << value << ", ";
      }
      if (accept_state == 0)
      {
        cout << !value << ", ";
      }
    }
    cout << endl;
  }
#endif
#if !OPTIMAL
  ClientLog("Starting Second FSM");

  cout << "Finished with 1st part of OT correlation calculations" << endl;
  cout << "Setting up second FSM to compute k matches" << endl;

#endif

  uint8_t *client_k_state = new uint8_t[N];
  for (int i = 0; i < N; i++)
  {
    client_k_state[i] = 2; // default state
  }
  uint32_t c = 0;
  for (int round = 0; round < pArgs.FSM2_rounds; round++)
  {
    uint8_t round_step = pArgs.FSM2_steps[round];
    uint8_t round_factor = 1 << round_step;
    uint8_t *choices = new uint8_t[N];
    for (int i = 0; i < N; i++)
    {
      // (client state, components equal)
      uint8_t client_state_value = 0;
      for (int j = 0; j < round_step; j++)
      {
        client_state_value += client_states[i][c + j] * (1 << j);
      }
      choices[i] = round_factor * client_k_state[i] + client_state_value;

    }

#if !OPTIMAL
    ClientLog("One one rounds");
#endif


    uint8_t *rMsg = new uint8_t[N];
    ConstructOTReceiverMsg(rMsg, *(FSM2_RC[round]), choices, N);

    SendLargePacked(socket, 2 + round_step, N, rMsg);
    
#if !OPTIMAL
    cout << "Sending: " << N << endl;
#endif

    uint8_t *sMsg = new uint8_t[N * 3 * round_factor];

    ReceiveLargePacked(socket, 2, N * 3 * round_factor, sMsg);
    

    uint8_t *msgs2 = new uint8_t[N];
    RecoverReceiverMsg(msgs2, *(FSM2_RC[round]), choices, sMsg, N, 2, bits_FSM2);

    for (int i = 0; i < N; i++)
    {
      client_k_state[i] = msgs2[i];
    }

    c += round_step;

    delete[] choices;
    delete[] msgs2;
    delete[] rMsg;
    delete[] sMsg;
  }
#if !OPTIMAL
  ClientLog("Finished second FSM");
#endif
  for (int i = 0; i < N; i++)
  {
    if (client_k_state[i] > 0)
      ClientLog("found a match at index " + to_string(i));
  }

#if !OPTIMAL
  cout << "Memory clean up" << endl;
#endif

  delete[] query;
  for (int i = 0; i < N; i++)
  {
    delete[] client_states[i];
  }
  delete[] client_states;
  delete[] client_k_state;

  for (int i = 0; i < pArgs.FSM1_rounds; i++)
  {
    delete FSM1_RC[i];
  }
  delete[] FSM1_RC;

  for (int i = 0; i < pArgs.FSM2_rounds; i++)
  {
    delete FSM2_RC[i];
  }
  delete[] FSM2_RC;
}

// Assembly:
subq $0x988, %rsp            # imm = 0x988
movq %rsi, 0x108(%rsp)
movq %rdx, 0x110(%rsp)
movq %rdi, 0x980(%rsp)
movq %rsi, 0x978(%rsp)
movq %rdx, 0x970(%rsp)
leaq 0x94f(%rsp), %rdi
movq %rdi, 0x118(%rsp)
callq 0x3470
movq 0x118(%rsp), %rdx
leaq 0x6905(%rip), %rsi      # 0xa008
leaq 0x950(%rsp), %rdi
callq 0x33a0
jmp 0x3712
leaq 0x950(%rsp), %rdi
callq 0x48b0
jmp 0x3721
leaq 0x950(%rsp), %rdi
callq 0x31a0
leaq 0x94f(%rsp), %rdi
callq 0x3300
leaq 0x730(%rsp), %rdi
callq 0x3320
movl $0x8, %edi
movl $0x4, %esi
callq 0x5150
movl %eax, 0x104(%rsp)
jmp 0x3760
movl 0x104(%rsp), %edx
movq 0x108(%rsp), %rsi
leaq 0x730(%rsp), %rdi
callq 0x3220
jmp 0x377e
leaq 0x700(%rsp), %rdi
leaq 0x730(%rsp), %rsi
callq 0x7220
jmp 0x3795
leaq 0x730(%rsp), %rdi
callq 0x3090
jmp 0x37a4
leaq 0x4f8(%rsp), %rdi
callq 0x3320
jmp 0x37b3
movq 0x110(%rsp), %rsi
leaq 0x685f(%rip), %rdx      # 0xa021
leaq 0x4d8(%rsp), %rdi
callq 0x5170
jmp 0x37d1
movl $0x8, %edi
movl $0x4, %esi
callq 0x5150
movl %eax, 0x100(%rsp)
jmp 0x37e9
movl 0x100(%rsp), %edx
leaq 0x4f8(%rsp), %rdi
leaq 0x4d8(%rsp), %rsi
callq 0x3220
jmp 0x3807
leaq 0x4d8(%rsp), %rdi
callq 0x31a0
vmovdqu 0x700(%rsp), %ymm0
vmovdqu 0x710(%rsp), %ymm1
vmovdqu %ymm1, 0x4b0(%rsp)
vmovdqu %ymm0, 0x4a0(%rsp)
leaq 0x4f8(%rsp), %rdi
leaq 0x4a0(%rsp), %rsi
vzeroupper
callq 0x78a0
movq %rax, 0xf8(%rsp)
jmp 0x385a
leaq 0x4a0(%rsp), %rdi
callq 0x73b0
movq 0xf8(%rsp), %rax
movq %rax, 0x4d0(%rsp)
vmovdqu 0x700(%rsp), %ymm0
vmovdqu 0x710(%rsp), %ymm1
vmovdqu %ymm1, 0x470(%rsp)
vmovdqu %ymm0, 0x460(%rsp)
leaq 0x4f8(%rsp), %rdi
leaq 0x460(%rsp), %rsi
vzeroupper
callq 0x7970
movq %rax, 0xf0(%rsp)
jmp 0x38bd
leaq 0x460(%rsp), %rdi
callq 0x73b0
movq 0xf0(%rsp), %rax
movq %rax, 0x498(%rsp)
leaq 0x4f8(%rsp), %rdi
callq 0x3090
jmp 0x38e9
movl 0x700(%rsp), %eax
movl %eax, 0x45c(%rsp)
movl 0x704(%rsp), %eax
movl %eax, 0x458(%rsp)
movq 0x720(%rsp), %rax
movq %rax, 0x450(%rsp)
leaq 0x248(%rsp), %rdi
callq 0x3320
jmp 0x3924
movq 0x110(%rsp), %rsi
leaq 0x66f6(%rip), %rdx      # 0xa029
leaq 0x228(%rsp), %rdi
callq 0x5170
jmp 0x3942
leaq 0x248(%rsp), %rdi
leaq 0x228(%rsp), %rsi
movl $0x8, %edx
callq 0x3220
jmp 0x395e
leaq 0x228(%rsp), %rdi
callq 0x31a0
movl 0x458(%rsp), %esi
leaq 0x248(%rsp), %rdi
callq 0x7a80
movq %rax, 0xe8(%rsp)
jmp 0x3989
movq 0xe8(%rsp), %rax
movq %rax, 0x220(%rsp)
leaq 0x248(%rsp), %rdi
callq 0x3090
jmp 0x39a8
movl 0x45c(%rsp), %eax
movl %eax, %edi
shlq $0x3, %rdi
callq 0x3030
movq %rax, 0xe0(%rsp)
jmp 0x39c4
movq 0xe0(%rsp), %rax
movq %rax, 0x218(%rsp)
movl $0x0, 0x214(%rsp)
movl 0x214(%rsp), %eax
cmpl 0x45c(%rsp), %eax
jae 0x3bd6
movl 0x458(%rsp), %eax
movl %eax, %edi
callq 0x3030
movq %rax, 0xd8(%rsp)
jmp 0x3a0b
movq 0xd8(%rsp), %rdx
movq 0x218(%rsp), %rax
movslq 0x214(%rsp), %rcx
movq %rdx, (%rax,%rcx,8)
movl $0x0, 0x210(%rsp)
movl 0x210(%rsp), %eax
cmpl 0x458(%rsp), %eax
jae 0x3bbe
movq 0x218(%rsp), %rax
movslq 0x214(%rsp), %rcx
movq (%rax,%rcx,8), %rax
movslq 0x210(%rsp), %rcx
movb $0x0, (%rax,%rcx)
movl 0x210(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x210(%rsp)
jmp 0x3a32
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x940(%rsp)
movl %eax, 0x93c(%rsp)
jmp 0x3ab0
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x940(%rsp)
movl %eax, 0x93c(%rsp)
leaq 0x950(%rsp), %rdi
callq 0x31a0
leaq 0x94f(%rsp), %rdi
callq 0x3300
jmp 0x48a1
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x940(%rsp)
movl %eax, 0x93c(%rsp)
jmp 0x4894
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x940(%rsp)
movl %eax, 0x93c(%rsp)
jmp 0x4887
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x940(%rsp)
movl %eax, 0x93c(%rsp)
jmp 0x487a
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x940(%rsp)
movl %eax, 0x93c(%rsp)
leaq 0x4d8(%rsp), %rdi
callq 0x31a0
jmp 0x487a
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x940(%rsp)
movl %eax, 0x93c(%rsp)
leaq 0x4a0(%rsp), %rdi
callq 0x73b0
jmp 0x487a
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x940(%rsp)
movl %eax, 0x93c(%rsp)
leaq 0x460(%rsp), %rdi
callq 0x73b0
jmp 0x487a
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x940(%rsp)
movl %eax, 0x93c(%rsp)
jmp 0x486d
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x940(%rsp)
movl %eax, 0x93c(%rsp)
leaq 0x228(%rsp), %rdi
callq 0x31a0
jmp 0x486d
jmp 0x3bc0
movl 0x214(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x214(%rsp)
jmp 0x39df
movl $0x0, 0x20c(%rsp)
movl $0x0, 0x208(%rsp)
movl $0x0, 0x204(%rsp)
movl 0x204(%rsp), %eax
cmpl 0x708(%rsp), %eax
jae 0x4146
movq 0x710(%rsp), %rax
movslq 0x204(%rsp), %rcx
movb (%rax,%rcx), %al
movb %al, 0x203(%rsp)
movzbl 0x203(%rsp), %ecx
movl $0x1, %eax
shll %cl, %eax
subl $0x1, %eax
movb %al, 0x202(%rsp)
movzbl 0x203(%rsp), %ecx
movl $0x1, %eax
shll %cl, %eax
movb %al, 0x201(%rsp)
movzbl 0x201(%rsp), %eax
shll %eax
movb %al, 0x200(%rsp)
movl 0x20c(%rsp), %eax
movq 0x450(%rsp), %rcx
movslq 0x208(%rsp), %rdx
movzbl (%rcx,%rdx), %ecx
cmpl %ecx, %eax
jl 0x3cba
jmp 0x3c86
movl 0x20c(%rsp), %eax
movq 0x450(%rsp), %rcx
movslq 0x208(%rsp), %rdx
movzbl (%rcx,%rdx), %ecx
cmpl %ecx, %eax
jl 0x3cb8
movl 0x208(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x208(%rsp)
jmp 0x3c86
jmp 0x3cba
movl 0x458(%rsp), %eax
movl 0x208(%rsp), %ecx
subl %ecx, %eax
movb %al, 0x1ff(%rsp)
movl 0x45c(%rsp), %eax
movzbl 0x1ff(%rsp), %ecx
imull %ecx, %eax
movzbl 0x203(%rsp), %ecx
imull %ecx, %eax
movl %eax, %edi
callq 0x3030
movq %rax, 0xd0(%rsp)
jmp 0x3cff
movq 0xd0(%rsp), %rax
movq %rax, 0x1f0(%rsp)
movl $0x0, 0x1ec(%rsp)
movl 0x1ec(%rsp), %eax
cmpl 0x45c(%rsp), %eax
jae 0x3e26
movl $0x0, 0x1e8(%rsp)
movl 0x1e8(%rsp), %eax
movzbl 0x1ff(%rsp), %ecx
cmpl %ecx, %eax
jge 0x3e0e
movl 0x1e8(%rsp), %eax
addl 0x458(%rsp), %eax
movzbl 0x1ff(%rsp), %ecx
subl %ecx, %eax
movb %al, 0x1e7(%rsp)
movq 0x220(%rsp), %rax
movzbl 0x1e7(%rsp), %ecx
movl (%rax,%rcx,4), %eax
movl 0x20c(%rsp), %ecx
shrl %cl, %eax
movzbl 0x202(%rsp), %ecx
andl %ecx, %eax
movb %al, 0x1e6(%rsp)
movzbl 0x201(%rsp), %eax
movq 0x218(%rsp), %rcx
movslq 0x1ec(%rsp), %rdx
movq (%rcx,%rdx,8), %rcx
movzbl 0x1e7(%rsp), %edx
movzbl (%rcx,%rdx), %ecx
imull %ecx, %eax
movzbl 0x1e6(%rsp), %ecx
addl %ecx, %eax
movb %al, %dl
movq 0x1f0(%rsp), %rax
movzbl 0x1ff(%rsp), %ecx
imull 0x1ec(%rsp), %ecx
addl 0x1e8(%rsp), %ecx
movslq %ecx, %rcx
movb %dl, (%rax,%rcx)
movl 0x1e8(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x1e8(%rsp)
jmp 0x3d39
jmp 0x3e10
movl 0x1ec(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x1ec(%rsp)
jmp 0x3d1a
movl 0x45c(%rsp), %eax
movzbl 0x1ff(%rsp), %ecx
imull %ecx, %eax
movl %eax, %edi
callq 0x3030
movq %rax, 0xc8(%rsp)
jmp 0x3e49
movq 0xc8(%rsp), %rax
movq %rax, 0x1d8(%rsp)
movq 0x1d8(%rsp), %rdi
movq 0x4d0(%rsp), %rax
movslq 0x204(%rsp), %rcx
movq (%rax,%rcx,8), %rsi
movq 0x1f0(%rsp), %rdx
movl 0x45c(%rsp), %ecx
movzbl 0x1ff(%rsp), %eax
imull %eax, %ecx
callq 0x62d0
jmp 0x3e96
movq 0x980(%rsp), %rdi
movzbl 0x203(%rsp), %eax
incl %eax
movl 0x45c(%rsp), %ecx
movzbl 0x1ff(%rsp), %edx
imull %edx, %ecx
movl %ecx, %edx
movq 0x1d8(%rsp), %rcx
movzbl %al, %esi
callq 0x7ca0
jmp 0x3ece
movl 0x45c(%rsp), %eax
movzbl 0x1ff(%rsp), %ecx
imull %ecx, %eax
movzbl 0x200(%rsp), %ecx
imull %ecx, %eax
movl %eax, %edi
callq 0x3030
movq %rax, 0xc0(%rsp)
jmp 0x3efc
movq 0xc0(%rsp), %rax
movq %rax, 0x1d0(%rsp)
movq 0x980(%rsp), %rdi
movl 0x45c(%rsp), %eax
movzbl 0x1ff(%rsp), %ecx
imull %ecx, %eax
movzbl 0x200(%rsp), %ecx
imull %ecx, %eax
movl %eax, %edx
movq 0x1d0(%rsp), %rcx
movl $0x1, %esi
callq 0x7e60
jmp 0x3f47
movl 0x45c(%rsp), %eax
movzbl 0x1ff(%rsp), %ecx
imull %ecx, %eax
movl %eax, %edi
callq 0x3030
movq %rax, 0xb8(%rsp)
jmp 0x3f6a
movq 0xb8(%rsp), %rax
movq %rax, 0x1c8(%rsp)
movq 0x1c8(%rsp), %rdi
movq 0x4d0(%rsp), %rax
movslq 0x204(%rsp), %rcx
movq (%rax,%rcx,8), %rsi
movq 0x1f0(%rsp), %rdx
movq 0x1d0(%rsp), %rcx
movl 0x45c(%rsp), %r8d
movzbl 0x1ff(%rsp), %eax
imull %eax, %r8d
movq %rsp, %rax
movl $0x4, (%rax)
movl $0x1, %r9d
callq 0x6510
jmp 0x3fd0
movl $0x0, 0x1c4(%rsp)
movl 0x1c4(%rsp), %eax
cmpl 0x45c(%rsp), %eax
jae 0x408e
movl $0x0, 0x1c0(%rsp)
movl 0x1c0(%rsp), %eax
movzbl 0x1ff(%rsp), %ecx
cmpl %ecx, %eax
jge 0x4076
movq 0x1c8(%rsp), %rax
movzbl 0x1ff(%rsp), %ecx
imull 0x1c4(%rsp), %ecx
addl 0x1c0(%rsp), %ecx
movslq %ecx, %rcx
movb (%rax,%rcx), %dl
movq 0x218(%rsp), %rax
movslq 0x1c4(%rsp), %rcx
movq (%rax,%rcx,8), %rax
movl 0x1c0(%rsp), %ecx
addl 0x458(%rsp), %ecx
movzbl 0x1ff(%rsp), %esi
subl %esi, %ecx
movl %ecx, %ecx
movb %dl, (%rax,%rcx)
movl 0x1c0(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x1c0(%rsp)
jmp 0x3ffa
jmp 0x4078
movl 0x1c4(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x1c4(%rsp)
jmp 0x3fdb
movq 0x1f0(%rsp), %rax
movq %rax, 0xb0(%rsp)
cmpq $0x0, %rax
je 0x40b1
movq 0xb0(%rsp), %rdi
callq 0x3370
movq 0x1c8(%rsp), %rax
movq %rax, 0xa8(%rsp)
cmpq $0x0, %rax
je 0x40d4
movq 0xa8(%rsp), %rdi
callq 0x3370
movq 0x1d8(%rsp), %rax
movq %rax, 0xa0(%rsp)
cmpq $0x0, %rax
je 0x40f7
movq 0xa0(%rsp), %rdi
callq 0x3370
movq 0x1d0(%rsp), %rax
movq %rax, 0x98(%rsp)
cmpq $0x0, %rax
je 0x411a
movq 0x98(%rsp), %rdi
callq 0x3370
movzbl 0x203(%rsp), %eax
addl 0x20c(%rsp), %eax
movl %eax, 0x20c(%rsp)
movl 0x204(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x204(%rsp)
jmp 0x3bf7
movl 0x45c(%rsp), %eax
movl %eax, %edi
callq 0x3030
movq %rax, 0x90(%rsp)
jmp 0x415e
movq 0x90(%rsp), %rax
movq %rax, 0x1b8(%rsp)
movl $0x0, 0x1b4(%rsp)
movl 0x1b4(%rsp), %eax
cmpl 0x45c(%rsp), %eax
jae 0x41b0
movq 0x1b8(%rsp), %rax
movslq 0x1b4(%rsp), %rcx
movb $0x2, (%rax,%rcx)
movl 0x1b4(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x1b4(%rsp)
jmp 0x4179
movl $0x0, 0x1b0(%rsp)
movl $0x0, 0x1ac(%rsp)
movl 0x1ac(%rsp), %eax
cmpl 0x70c(%rsp), %eax
jae 0x4585
movq 0x718(%rsp), %rax
movslq 0x1ac(%rsp), %rcx
movb (%rax,%rcx), %al
movb %al, 0x1ab(%rsp)
movb 0x1ab(%rsp), %al
movb %al, %cl
movl $0x1, %eax
shlxl %ecx, %eax, %eax
movb %al, 0x1aa(%rsp)
movl 0x45c(%rsp), %eax
movl %eax, %edi
callq 0x3030
movq %rax, 0x88(%rsp)
jmp 0x4226
movq 0x88(%rsp), %rax
movq %rax, 0x1a0(%rsp)
movl $0x0, 0x19c(%rsp)
movl 0x19c(%rsp), %eax
cmpl 0x45c(%rsp), %eax
jae 0x433a
movb $0x0, 0x19b(%rsp)
movl $0x0, 0x194(%rsp)
movl 0x194(%rsp), %eax
movzbl 0x1ab(%rsp), %ecx
cmpl %ecx, %eax
jge 0x42e6
movq 0x218(%rsp), %rax
movslq 0x19c(%rsp), %rcx
movq (%rax,%rcx,8), %rax
movl 0x1b0(%rsp), %ecx
addl 0x194(%rsp), %ecx
movl %ecx, %ecx
movzbl (%rax,%rcx), %eax
movl %eax, 0x84(%rsp)
movl 0x194(%rsp), %ecx
movl $0x1, %eax
shll %cl, %eax
movl 0x84(%rsp), %ecx
imull %eax, %ecx
movzbl 0x19b(%rsp), %eax
addl %ecx, %eax
movb %al, 0x19b(%rsp)
movl 0x194(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x194(%rsp)
jmp 0x4268
movzbl 0x1aa(%rsp), %eax
movq 0x1b8(%rsp), %rcx
movslq 0x19c(%rsp), %rdx
movzbl (%rcx,%rdx), %ecx
imull %ecx, %eax
movzbl 0x19b(%rsp), %ecx
addl %ecx, %eax
movb %al, %dl
movq 0x1a0(%rsp), %rax
movslq 0x19c(%rsp), %rcx
movb %dl, (%rax,%rcx)
movl 0x19c(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x19c(%rsp)
jmp 0x4241
movl 0x45c(%rsp), %eax
movl %eax, %edi
callq 0x3030
movq %rax, 0x78(%rsp)
jmp 0x434f
movq 0x78(%rsp), %rax
movq %rax, 0x188(%rsp)
movq 0x188(%rsp), %rdi
movq 0x498(%rsp), %rax
movslq 0x1ac(%rsp), %rcx
movq (%rax,%rcx,8), %rsi
movq 0x1a0(%rsp), %rdx
movl 0x45c(%rsp), %ecx
callq 0x62d0
jmp 0x438e
movq 0x980(%rsp), %rdi
movzbl 0x1ab(%rsp), %eax
addl $0x2, %eax
movl 0x45c(%rsp), %ecx
movl %ecx, %edx
movq 0x188(%rsp), %rcx
movzbl %al, %esi
callq 0x7ca0
jmp 0x43bc
movl 0x45c(%rsp), %ecx
movzbl 0x1aa(%rsp), %eax
imull %eax, %ecx
movl %ecx, %eax
leal (%rax,%rax,2), %eax
movl %eax, %edi
callq 0x3030
movq %rax, 0x70(%rsp)
jmp 0x43e1
movq 0x70(%rsp), %rax
movq %rax, 0x180(%rsp)
movq 0x980(%rsp), %rdi
movl 0x45c(%rsp), %ecx
movzbl 0x1aa(%rsp), %eax
imull %eax, %ecx
movl %ecx, %eax
leal (%rax,%rax,2), %eax
movl %eax, %edx
movq 0x180(%rsp), %rcx
movl $0x2, %esi
callq 0x7e60
jmp 0x4423
movl 0x45c(%rsp), %eax
movl %eax, %edi
callq 0x3030
movq %rax, 0x68(%rsp)
jmp 0x4438
movq 0x68(%rsp), %rax
movq %rax, 0x178(%rsp)
movq 0x178(%rsp), %rdi
movq 0x498(%rsp), %rax
movslq 0x1ac(%rsp), %rcx
movq (%rax,%rcx,8), %rsi
movq 0x1a0(%rsp), %rdx
movq 0x180(%rsp), %rcx
movl 0x45c(%rsp), %r8d
movq %rsp, %rax
movl $0x6, (%rax)
movl $0x2, %r9d
callq 0x6510
jmp 0x448f
movl $0x0, 0x174(%rsp)
movl 0x174(%rsp), %eax
cmpl 0x45c(%rsp), %eax
jae 0x44e3
movq 0x178(%rsp), %rax
movslq 0x174(%rsp), %rcx
movb (%rax,%rcx), %dl
movq 0x1b8(%rsp), %rax
movslq 0x174(%rsp), %rcx
movb %dl, (%rax,%rcx)
movl 0x174(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x174(%rsp)
jmp 0x449a
movzbl 0x1ab(%rsp), %eax
addl 0x1b0(%rsp), %eax
movl %eax, 0x1b0(%rsp)
movq 0x1a0(%rsp), %rax
movq %rax, 0x60(%rsp)
cmpq $0x0, %rax
je 0x4516
movq 0x60(%rsp), %rdi
callq 0x3370
movq 0x178(%rsp), %rax
movq %rax, 0x58(%rsp)
cmpq $0x0, %rax
je 0x4533
movq 0x58(%rsp), %rdi
callq 0x3370
movq 0x188(%rsp), %rax
movq %rax, 0x50(%rsp)
cmpq $0x0, %rax
je 0x4550
movq 0x50(%rsp), %rdi
callq 0x3370
movq 0x180(%rsp), %rax
movq %rax, 0x48(%rsp)
cmpq $0x0, %rax
je 0x456d
movq 0x48(%rsp), %rdi
callq 0x3370
jmp 0x456f
movl 0x1ac(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x1ac(%rsp)
jmp 0x41c6
movl $0x0, 0x170(%rsp)
movl 0x170(%rsp), %eax
cmpl 0x45c(%rsp), %eax
jae 0x4681
movq 0x1b8(%rsp), %rax
movslq 0x170(%rsp), %rcx
movzbl (%rax,%rcx), %eax
cmpl $0x0, %eax
jle 0x4669
movl 0x170(%rsp), %esi
leaq 0x130(%rsp), %rdi
callq 0x5250
jmp 0x45d7
leaq 0x5a55(%rip), %rsi      # 0xa033
leaq 0x150(%rsp), %rdi
leaq 0x130(%rsp), %rdx
callq 0x5200
jmp 0x45f5
leaq 0x150(%rsp), %rdi
callq 0x48b0
jmp 0x4604
leaq 0x150(%rsp), %rdi
callq 0x31a0
leaq 0x130(%rsp), %rdi
callq 0x31a0
jmp 0x4669
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x940(%rsp)
movl %eax, 0x93c(%rsp)
jmp 0x4657
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x940(%rsp)
movl %eax, 0x93c(%rsp)
leaq 0x150(%rsp), %rdi
callq 0x31a0
leaq 0x130(%rsp), %rdi
callq 0x31a0
jmp 0x486d
jmp 0x466b
movl 0x170(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x170(%rsp)
jmp 0x4590
movq 0x220(%rsp), %rax
movq %rax, 0x40(%rsp)
cmpq $0x0, %rax
je 0x469e
movq 0x40(%rsp), %rdi
callq 0x3370
movl $0x0, 0x12c(%rsp)
movl 0x12c(%rsp), %eax
cmpl 0x45c(%rsp), %eax
jae 0x46f7
movq 0x218(%rsp), %rax
movslq 0x12c(%rsp), %rcx
movq (%rax,%rcx,8), %rax
movq %rax, 0x38(%rsp)
cmpq $0x0, %rax
je 0x46e2
movq 0x38(%rsp), %rdi
callq 0x3370
jmp 0x46e4
movl 0x12c(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x12c(%rsp)
jmp 0x46a9
movq 0x218(%rsp), %rax
movq %rax, 0x30(%rsp)
cmpq $0x0, %rax
je 0x4714
movq 0x30(%rsp), %rdi
callq 0x3370
movq 0x1b8(%rsp), %rax
movq %rax, 0x28(%rsp)
cmpq $0x0, %rax
je 0x4731
movq 0x28(%rsp), %rdi
callq 0x3370
movl $0x0, 0x128(%rsp)
movl 0x128(%rsp), %eax
cmpl 0x708(%rsp), %eax
jae 0x4794
movq 0x4d0(%rsp), %rax
movslq 0x128(%rsp), %rcx
movq (%rax,%rcx,8), %rax
movq %rax, 0x20(%rsp)
cmpq $0x0, %rax
je 0x477f
movq 0x20(%rsp), %rdi
callq 0x5f60
movq 0x20(%rsp), %rdi
callq 0x3270
jmp 0x4781
movl 0x128(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x128(%rsp)
jmp 0x473c
movq 0x4d0(%rsp), %rax
movq %rax, 0x18(%rsp)
cmpq $0x0, %rax
je 0x47b1
movq 0x18(%rsp), %rdi
callq 0x3370
movl $0x0, 0x124(%rsp)
movl 0x124(%rsp), %eax
cmpl 0x70c(%rsp), %eax
jae 0x4814
movq 0x498(%rsp), %rax
movslq 0x124(%rsp), %rcx
movq (%rax,%rcx,8), %rax
movq %rax, 0x10(%rsp)
cmpq $0x0, %rax
je 0x47ff
movq 0x10(%rsp), %rdi
callq 0x5f60
movq 0x10(%rsp), %rdi
callq 0x3270
jmp 0x4801
movl 0x124(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x124(%rsp)
jmp 0x47bc
movq 0x498(%rsp), %rax
movq %rax, 0x8(%rsp)
cmpq $0x0, %rax
je 0x4831
movq 0x8(%rsp), %rdi
callq 0x3370
leaq 0x248(%rsp), %rdi
callq 0x30d0
leaq 0x4f8(%rsp), %rdi
callq 0x30d0
leaq 0x700(%rsp), %rdi
callq 0x73b0
leaq 0x730(%rsp), %rdi
callq 0x30d0
addq $0x988, %rsp            # imm = 0x988
retq
leaq 0x248(%rsp), %rdi
callq 0x30d0
leaq 0x4f8(%rsp), %rdi
callq 0x30d0
leaq 0x700(%rsp), %rdi
callq 0x73b0
leaq 0x730(%rsp), %rdi
callq 0x30d0
movq 0x940(%rsp), %rdi
callq 0x3460
nop