// File: /workspace/github_cpp_makefile_star2_O3/Luthaf[P]zeopp/psd.cc
// Function: calcPoreSizeDistr(ATOM_NETWORK*, ATOM_NETWORK*, bool, double, double, int, bool, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, bool, bool)
void calcPoreSizeDistr(ATOM_NETWORK *atmnet, ATOM_NETWORK *orgAtomnet, bool highAccuracy, double r_probe_chan, double r_probe, int numSamples, bool excludePockets, string histogramFile, string pointsFile, string nodeAndRadiiFile, string spheresDistFile, bool visualize, bool visVISIT){

    ofstream output; 
    if (!histogramFile.empty()) output.open(histogramFile.data());
    ofstream outfile;
    if (!pointsFile.empty()) outfile.open(pointsFile.data());
    ofstream nodeAndRadii;
    if (!nodeAndRadiiFile.empty()) nodeAndRadii.open(nodeAndRadiiFile.data());
    ofstream spheresDist;
  // Create an object that handles analysis of accessibility of sampled points
  AccessibilityClass accessAnalysis;
  if(highAccuracy) accessAnalysis.setupAndFindChannels(atmnet, orgAtomnet, highAccuracy, r_probe_chan, r_probe);
    else accessAnalysis.setupAndFindChannels(atmnet, atmnet, highAccuracy, r_probe_chan, r_probe);


  srand(randSeed);

//Vectors to store accessible points, inaccessible points, and accessible points which lie outside Voronoi nodes and edges. 
  vector<Point> axsPoint = vector<Point>();
  vector<Point> inaxsPoint = vector<Point>();

//List of largest sphere diameters for PSD histogram
  vector<double> diameterOfLargestSphere;

//List of sample points and radius of sphere that contains sample point for visualization in Visit
  vector <pair <Point, double> > axsPoint_and_radiiOfNodeSphere;
  vector <pair <Point, double> > axsPoint_and_radiiOfGhostSphere;
//List of node coordinates and radii for visualization
  vector <int> nodeIDs;
  vector <pair <Point, double> > coord_and_radiiOfNodeSphere;
  vector <pair <Point, double> > coord_and_radiiOfGhostSphere;
	vector <double> distanceBetweenNodeSpheres;
	vector <double> distanceBetweenGhostSpheres;

  int count = 0;
  int incount = 0;
  int outcount = 0;

//Generates random points across cell and tests accessibility.
  for(int i = 0; i < numSamples; i++){
    bool overlaps = false;
    bool inside = false;
    double aPoint = (rand()*1.0)/RAND_MAX;
    double bPoint = (rand()*1.0)/RAND_MAX;
    double cPoint = (rand()*1.0)/RAND_MAX;
    Point samplingPoint = atmnet->abc_to_xyz(aPoint, bPoint, cPoint);


    // Calling accessibility object to determine accessibility of the point (this replaced a big chunk of code by Thomas)
    double dist_var;
    pair<bool,bool> answer = (accessAnalysis.isVPointInsideAtomAndNotAccessible(samplingPoint, dist_var));
    inside = answer.first; overlaps = answer.second;
    if(accessAnalysis.needToResample() == true) i--; // the sampled point could not be analyzed in isVPointInsideAtomAndNotAccessible() function, resampling needed

    if(inside == false && excludePockets == false) overlaps = false; // if ignore inacceible pockets, treat the point as accessible (unless inside atom)




// Store sampled points that did not overlap with an atom but were inaccessible
    if(accessAnalysis.needToResample() == false && !inside && overlaps){
	Point abcCoords = Point(aPoint, bPoint, cPoint);
	Point coord = atmnet->abc_to_xyz(abcCoords);
	inaxsPoint.push_back(coord);
    }
// Store accessible points
    if(accessAnalysis.needToResample() == false &&!overlaps) {
	count++;     
	Point abcCoords = Point(aPoint, bPoint, cPoint);
	Point coords = atmnet->abc_to_xyz(abcCoords);
	axsPoint.push_back(coords); 
    }
  } // ends loop over all sampled points


  // Warn user if points were resampled
  int resampleCount =  accessAnalysis.getResampleCount();
  if(resampleCount != 0){
    cerr << "\n" << "\n"
         << "Warning: Resampled " << resampleCount << " points out of " << numSamples
         << " when analyzing " << atmnet->name << "\n"
         << "\n" << "\n";
  }


//Below are functions that go beyond accessible volume calcluation. Each accessible point is analyzed to find the largest encapsulating sphere


//Determine whether sample point is inside/outside node sphere
  for (int a=0; a<axsPoint.size(); a++){
    Point samplePt = axsPoint.at(a);
    Point maxNodeCoord = Point (0, 0, 0);
    double maxRadius = 0;
    for (int b=0; b<accessAnalysis.vornet.nodes.size(); b++)
      {
      bool access = accessAnalysis.accessInfo.at(b);
      if (access){
        Point nodePt = Point(accessAnalysis.vornet.nodes.at(b).x, accessAnalysis.vornet.nodes.at(b).y, accessAnalysis.vornet.nodes.at(b).z);
        double radius = accessAnalysis.vornet.nodes.at(b).rad_stat_sphere + r_probe;
        double sampToNode = accessAnalysis.analyzedAtomNet.calcDistanceXYZ(samplePt[0], samplePt[1], samplePt[2], nodePt[0], nodePt[1], nodePt[2]);
        bool inSphere = (sampToNode <= radius); 
        //if point is inside more than one sphere, chooses largest sphere (i.e. largest radius)
        if (inSphere){
          maxRadius = max(radius, maxRadius);
          //If query zpsd, this stores the largest node sphere and its coordinate for visualization in Visit
          if (visualize){
            if (radius==maxRadius){
               maxNodeCoord = nodePt; 
               }
            }
        } // ends if(inSphere)
      }
     }
    if (maxRadius==0) outcount++; 
    if (maxRadius!=0) incount++;





//Generate new "ghost" Voronoi cell
    double pointParticleRadius = r_probe;
//DEBUG next 4 lines
    voronoicell v(*(accessAnalysis.new_rad_con));
    accessAnalysis.new_rad_con->compute_ghost_cell(v, samplePt[0], samplePt[1], samplePt[2], pointParticleRadius);
    vector<double> vertexCoords;
    v.vertices(vertexCoords);

   //debug
   //cout << "number of ghost vertices = " << vertexCoords.size()/3 << "\n"; cout.flush();
   //for(unsigned int aa=0;aa<vertexCoords.size();aa++) cout << vertexCoords[aa] << " "; cout << "\n";

    vector <Point> pointVertexCoords;
    for (int c=0; c<vertexCoords.size(); c= c+3){
      Point vertexPoint = Point(vertexCoords.at(c), vertexCoords.at(c+1), vertexCoords.at(c+2));
      pointVertexCoords.push_back(vertexPoint);
    }

   //debug
   //cout << "vertex vector constructed \n"; cout.flush();

    double maxDistFromCtoV = 0;
    Point maxGhostCoord = Point (0, 0, 0);
//Calculate distance from center of cell to vertices
   for (int b=0; b<pointVertexCoords.size(); b++){
      Point vertexGlobalCoord = Point((samplePt[0]+pointVertexCoords.at(b)[0]), (samplePt[1]+pointVertexCoords.at(b)[1]), (samplePt[2]+pointVertexCoords.at(b)[2]));
      double calcDistFromCtoV = calcEuclideanDistance(pointVertexCoords.at(b)[0], pointVertexCoords.at(b)[1], pointVertexCoords.at(b)[2], 0.0, 0.0, 0.0) - pointParticleRadius;

      maxDistFromCtoV = max(maxDistFromCtoV, calcDistFromCtoV);
//If query zpsd, this stores the largest ghost sphere and its coordinate for visualization in Visit
      if (visualize){
        if (calcDistFromCtoV==maxDistFromCtoV){
          maxGhostCoord = vertexGlobalCoord;
        } 
      }
    }

  //debug:
  //cout << "getting ready for final comparison and assigment\n"; cout.flush();

//Compares node radius to biggest ghost radius and stores the larger of the two values accordingly
    double origNodeRadius = maxRadius;
    double ghostRadius = maxDistFromCtoV;  
    bool compareRadii = (origNodeRadius >= ghostRadius); 
    if (compareRadii) {
      diameterOfLargestSphere.push_back(2.0*origNodeRadius); 
      if (visualize){
      axsPoint_and_radiiOfNodeSphere.push_back(pair<Point, double>(samplePt, origNodeRadius));
      checkDuplicates(&(accessAnalysis.analyzedAtomNet), &(accessAnalysis.vornet), nodeIDs, coord_and_radiiOfNodeSphere, maxNodeCoord, origNodeRadius);
      }
    }
    if (!compareRadii) {
      diameterOfLargestSphere.push_back(2.0*ghostRadius);
      if (visualize){
        axsPoint_and_radiiOfGhostSphere.push_back(pair<Point, double>(samplePt, ghostRadius));
        coord_and_radiiOfGhostSphere.push_back(pair <Point, double> (maxGhostCoord, maxDistFromCtoV));
      }
    }

  //debug:
  //cout << "finishing pass in axsPoint loop\n"; cout.flush();

  }

  double volumeFraction = count*1.0/numSamples;
  double nodeVolFraction = incount*1.0/numSamples;
  double outFraction = outcount*1.0/numSamples;


  Histogram(output, BINSTEP, MAXBINS, diameterOfLargestSphere, count, nodeVolFraction, outFraction, numSamples);

  printf("Pore size distribution calculated.\n\n");

  if (visualize) {
    printFileCoords_Radii(outfile, axsPoint_and_radiiOfNodeSphere, axsPoint_and_radiiOfGhostSphere, distanceBetweenNodeSpheres, distanceBetweenGhostSpheres, false, -1, -1);
    printf("Points file generated.\n\n");
		if (!visVISIT){
                // here printing ZeoVis stuff
		}
		if (visVISIT) {
		  printFileCoords_Radii(nodeAndRadii, coord_and_radiiOfNodeSphere, coord_and_radiiOfGhostSphere, distanceBetweenNodeSpheres, distanceBetweenGhostSpheres, false, -1, -1);
		  printf("Radii file generated.\n");
		}
  }

  accessAnalysis.deconstruct();

}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x1588, %rsp           # imm = 0x1588
movq %r9, %r12
movl %r8d, 0x80(%rsp)
movl %ecx, 0x2c(%rsp)
movsd %xmm1, 0x78(%rsp)
movsd %xmm0, 0x18(%rsp)
movl %edx, %r15d
movq %rsi, %r14
movq %rdi, %rbx
leaq 0x748(%rsp), %rdi
callq 0x4720
cmpq $0x0, 0x8(%r12)
je 0x89058
movq (%r12), %rsi
leaq 0x748(%rsp), %rdi
movl $0x10, %edx
callq 0x4070
leaq 0x548(%rsp), %rdi
callq 0x4720
movq 0x15c0(%rsp), %rax
cmpq $0x0, 0x8(%rax)
je 0x89089
movq (%rax), %rsi
leaq 0x548(%rsp), %rdi
movl $0x10, %edx
callq 0x4070
leaq 0x348(%rsp), %rdi
callq 0x4720
movq 0x15c8(%rsp), %rax
cmpq $0x0, 0x8(%rax)
je 0x890ba
movq (%rax), %rsi
leaq 0x348(%rsp), %rdi
movl $0x10, %edx
callq 0x4070
leaq 0x948(%rsp), %rdi
callq 0x4720
leaq 0xb48(%rsp), %rdi
callq 0x4866a
testb %r15b, %r15b
cmoveq %rbx, %r14
movzbl %r15b, %ecx
leaq 0xb48(%rsp), %rdi
movq %rbx, %rsi
movq %r14, %rdx
movsd 0x18(%rsp), %xmm0
movsd 0x78(%rsp), %xmm1
callq 0x93b2c
movl $0x3b4ca6f5, %edi       # imm = 0x3B4CA6F5
callq 0x4410
xorl %eax, %eax
movq %rax, 0x100(%rsp)
xorpd %xmm0, %xmm0
movapd %xmm0, 0xf0(%rsp)
movq %rax, 0x180(%rsp)
movapd %xmm0, 0x170(%rsp)
movq %rax, 0xc0(%rsp)
movapd %xmm0, 0xb0(%rsp)
movq %rax, 0x160(%rsp)
movapd %xmm0, 0x150(%rsp)
movq %rax, 0x140(%rsp)
movapd %xmm0, 0x130(%rsp)
movq %rax, 0x1e0(%rsp)
movapd %xmm0, 0x1d0(%rsp)
movq %rax, 0x1c0(%rsp)
movapd %xmm0, 0x1b0(%rsp)
movq %rax, 0x120(%rsp)
movapd %xmm0, 0x110(%rsp)
movq %rax, 0x250(%rsp)
movapd %xmm0, 0x240(%rsp)
movq $0x0, 0xc8(%rsp)
movq %rax, 0x230(%rsp)
movapd %xmm0, 0x220(%rsp)
cmpl $0x0, 0x2c(%rsp)
jle 0x89423
movq $0x0, 0xc8(%rsp)
leaq 0xb48(%rsp), %r15
xorl %r12d, %r12d
callq 0x4150
xorps %xmm1, %xmm1
cvtsi2sd %eax, %xmm1
movsd 0xc83f6(%rip), %xmm0    # 0x1515f0
divsd %xmm0, %xmm1
movsd %xmm1, 0x18(%rsp)
callq 0x4150
xorps %xmm0, %xmm0
cvtsi2sd %eax, %xmm0
divsd 0xc83d8(%rip), %xmm0    # 0x1515f0
movsd %xmm0, 0x20(%rsp)
callq 0x4150
xorps %xmm2, %xmm2
cvtsi2sd %eax, %xmm2
divsd 0xc83be(%rip), %xmm2    # 0x1515f0
leaq 0x260(%rsp), %rdi
movq %rbx, %rsi
movsd 0x18(%rsp), %xmm0
movsd 0x20(%rsp), %xmm1
movsd %xmm2, 0x70(%rsp)
callq 0x52d94
movq 0x270(%rsp), %rax
movq %rax, 0x10(%rsp)
movupd 0x260(%rsp), %xmm0
movupd %xmm0, (%rsp)
movq %r15, %rdi
leaq 0x1f0(%rsp), %rsi
callq 0x93f76
movl %eax, %r14d
movq %r15, %rdi
callq 0x487fa
movl %eax, %r13d
movzwl %r14w, %eax
shrl $0x8, %eax
cmpb $0x0, 0x80(%rsp)
movl $0x0, %ebp
cmovnel %eax, %ebp
testb $0x1, %r14b
cmovnel %eax, %ebp
movq %r15, %rdi
callq 0x487fa
orb %r14b, %al
testb $0x1, %al
jne 0x89354
testb $0x1, %bpl
je 0x89354
leaq 0x50(%rsp), %rdi
movsd 0x18(%rsp), %xmm0
movsd 0x20(%rsp), %xmm1
movsd 0x70(%rsp), %xmm2
callq 0x83f68
movq 0x60(%rsp), %rax
movq %rax, 0x10(%rsp)
movupd 0x50(%rsp), %xmm0
movupd %xmm0, (%rsp)
leaq 0x90(%rsp), %rdi
movq %rbx, %rsi
callq 0x51d04
movq 0x178(%rsp), %rsi
cmpq 0x180(%rsp), %rsi
je 0x8933f
movq 0xa0(%rsp), %rax
movq %rax, 0x10(%rsi)
movupd 0x90(%rsp), %xmm0
movupd %xmm0, (%rsi)
addq $0x18, 0x178(%rsp)
jmp 0x89354
leaq 0x170(%rsp), %rdi
leaq 0x90(%rsp), %rdx
callq 0x2fec4
movq %r15, %rdi
callq 0x487fa
testb %al, %al
jne 0x8940c
testb $0x1, %bpl
jne 0x8940c
leaq 0x50(%rsp), %rdi
movsd 0x18(%rsp), %xmm0
movsd 0x20(%rsp), %xmm1
movsd 0x70(%rsp), %xmm2
callq 0x83f68
movq 0x60(%rsp), %rax
movq %rax, 0x10(%rsp)
movupd 0x50(%rsp), %xmm0
movupd %xmm0, (%rsp)
leaq 0x90(%rsp), %rdi
movq %rbx, %rsi
callq 0x51d04
movq 0xf8(%rsp), %rsi
cmpq 0x100(%rsp), %rsi
je 0x893e5
movq 0xa0(%rsp), %rax
movq %rax, 0x10(%rsi)
movupd 0x90(%rsp), %xmm0
movupd %xmm0, (%rsi)
addq $0x18, 0xf8(%rsp)
jmp 0x893fa
leaq 0xf0(%rsp), %rdi
leaq 0x90(%rsp), %rdx
callq 0x2fec4
movq 0xc8(%rsp), %rax
incl %eax
movq %rax, 0xc8(%rsp)
movzbl %r13b, %eax
negl %eax
addl %eax, %r12d
incl %r12d
cmpl 0x2c(%rsp), %r12d
jl 0x891e6
movl 0x1580(%rsp), %ebp
testl %ebp, %ebp
je 0x89517
movq 0x10bbb7(%rip), %rdi    # 0x194ff0
leaq 0xca1de(%rip), %rsi     # 0x15361e
movl $0x1, %edx
callq 0x44e0
movq 0x10bb9f(%rip), %rdi    # 0x194ff0
leaq 0xca1c6(%rip), %rsi     # 0x15361e
movl $0x1, %edx
callq 0x44e0
movq 0x10bb87(%rip), %rdi    # 0x194ff0
leaq 0xc835e(%rip), %rsi     # 0x1517ce
movl $0x13, %edx
callq 0x44e0
movq 0x10bb6f(%rip), %rdi    # 0x194ff0
movl %ebp, %esi
callq 0x4750
movq %rax, %r14
leaq 0xc8350(%rip), %rsi     # 0x1517e2
movl $0xf, %edx
movq %rax, %rdi
callq 0x44e0
movq %r14, %rdi
movl 0x2c(%rsp), %esi
callq 0x4750
movq %rax, %r14
leaq 0xd3eb1(%rip), %rsi     # 0x15d366
movl $0x10, %edx
movq %rax, %rdi
callq 0x44e0
movq 0x320(%rbx), %rsi
movq 0x328(%rbx), %rdx
movq %r14, %rdi
callq 0x44e0
movq %rax, %rbx
leaq 0xca13c(%rip), %rsi     # 0x15361e
movl $0x1, %edx
movq %rax, %rdi
callq 0x44e0
leaq 0xca128(%rip), %rsi     # 0x15361e
movl $0x1, %edx
movq %rbx, %rdi
callq 0x44e0
leaq 0xca114(%rip), %rsi     # 0x15361e
movl $0x1, %edx
movq %rbx, %rdi
callq 0x44e0
movq 0xf0(%rsp), %rax
cmpq %rax, 0xf8(%rsp)
je 0x89f93
xorl %ebx, %ebx
leaq 0x260(%rsp), %r15
leaq 0x90(%rsp), %r14
leaq 0x50(%rsp), %rbp
movabsq $-0x5555555555555555, %r13 # imm = 0xAAAAAAAAAAAAAAAB
xorl %r12d, %r12d
movl $0x0, 0x88(%rsp)
leaq (%rbx,%rbx,2), %rcx
movq 0x10(%rax,%rcx,8), %rdx
movq %rdx, 0xa0(%rsp)
movupd (%rax,%rcx,8), %xmm0
movapd %xmm0, 0x90(%rsp)
xorpd %xmm0, %xmm0
xorpd %xmm1, %xmm1
xorpd %xmm2, %xmm2
leaq 0x1f0(%rsp), %rdi
callq 0x83f68
movl %r12d, 0x8c(%rsp)
movq %rbx, 0x1a8(%rsp)
movq 0x1460(%rsp), %rax
cmpq 0x1458(%rsp), %rax
je 0x8977e
xorpd %xmm0, %xmm0
movsd %xmm0, 0x48(%rsp)
xorl %ebx, %ebx
xorl %r12d, %r12d
leaq 0x14d8(%rsp), %rdi
movq %r12, %rsi
callq 0xee36
testq %rdx, (%rax)
je 0x89758
movq 0x1458(%rsp), %rax
movq 0x1460(%rsp), %rdx
subq %rax, %rdx
sarq $0x6, %rdx
cmpq %r12, %rdx
jbe 0x8a2ad
movsd (%rax,%rbx), %xmm0
movsd 0x8(%rax,%rbx), %xmm1
movsd 0x10(%rax,%rbx), %xmm2
movq %r15, %rdi
callq 0x83f68
movq 0x1458(%rsp), %rax
movq 0x1460(%rsp), %rdx
subq %rax, %rdx
sarq $0x6, %rdx
cmpq %r12, %rdx
jbe 0x8a29c
movsd 0x18(%rax,%rbx), %xmm0
addsd 0x78(%rsp), %xmm0
movsd %xmm0, 0x18(%rsp)
movq %r14, %rdi
xorl %esi, %esi
callq 0x83f9a
movsd (%rax), %xmm0
movsd %xmm0, 0x20(%rsp)
movq %r14, %rdi
movl $0x1, %esi
callq 0x83f9a
movsd (%rax), %xmm0
movsd %xmm0, 0x70(%rsp)
movq %r14, %rdi
movl $0x2, %esi
callq 0x83f9a
movsd (%rax), %xmm0
movsd %xmm0, 0x80(%rsp)
movq %r15, %rdi
xorl %esi, %esi
callq 0x83f9a
movsd (%rax), %xmm0
movsd %xmm0, 0x218(%rsp)
movq %r15, %rdi
movl $0x1, %esi
callq 0x83f9a
movsd (%rax), %xmm0
movsd %xmm0, 0x210(%rsp)
movq %r15, %rdi
movl $0x2, %esi
callq 0x83f9a
movsd (%rax), %xmm5
leaq 0xfa8(%rsp), %rdi
movsd 0x20(%rsp), %xmm0
movsd 0x70(%rsp), %xmm1
movsd 0x80(%rsp), %xmm2
movsd 0x218(%rsp), %xmm3
movsd 0x210(%rsp), %xmm4
callq 0x5364c
movsd 0x18(%rsp), %xmm1
ucomisd %xmm0, %xmm1
jb 0x89758
movsd 0x48(%rsp), %xmm0
maxsd %xmm1, %xmm0
cmpb $0x0, 0x15d8(%rsp)
movsd %xmm0, 0x48(%rsp)
je 0x89758
ucomisd %xmm0, %xmm1
jne 0x89758
jp 0x89758
movq 0x270(%rsp), %rax
movq %rax, 0x200(%rsp)
movupd 0x260(%rsp), %xmm0
movapd %xmm0, 0x1f0(%rsp)
movq 0x1460(%rsp), %rax
subq 0x1458(%rsp), %rax
incq %r12
sarq $0x6, %rax
addq $0x40, %rbx
cmpq %r12, %rax
ja 0x895c9
jmp 0x89788
xorpd %xmm0, %xmm0
movsd %xmm0, 0x48(%rsp)
movq 0x1538(%rsp), %rax
movsd 0x178(%rax), %xmm0
movq %r15, %rdi
callq 0x1214ac
leaq 0x10b519(%rip), %rax    # 0x194cc0
movq %rax, 0x260(%rsp)
movq 0x1538(%rsp), %r12
movq %r14, %rdi
xorl %esi, %esi
callq 0x83f9a
movsd (%rax), %xmm0
movsd %xmm0, 0x18(%rsp)
movq %r14, %rdi
movl $0x1, %esi
callq 0x83f9a
movsd (%rax), %xmm0
movsd %xmm0, 0x20(%rsp)
movq %r14, %rdi
movl $0x2, %esi
callq 0x83f9a
movsd (%rax), %xmm0
movsd 0x18(%rsp), %xmm1
movsd %xmm1, 0x50(%rsp)
movsd 0x20(%rsp), %xmm1
movsd %xmm1, 0xd0(%rsp)
movsd %xmm0, 0x30(%rsp)
movq %r12, %rdi
leaq 0x190(%rsp), %rsi
movq %rbp, %rdx
leaq 0xd0(%rsp), %rcx
leaq 0x30(%rsp), %r8
callq 0x148c0a
movslq 0x190(%rsp), %rcx
movq 0x1a8(%r12), %rdx
movq 0x1b0(%r12), %rax
movq (%rdx,%rcx,8), %rdx
movslq (%rax,%rcx,4), %rsi
leal 0x1(%rsi), %edi
movl %edi, (%rax,%rcx,4)
shlq $0x5, %rsi
movsd 0x1d8(%r12), %xmm0
movsd %xmm0, 0x18(%rsp)
movsd 0x50(%rsp), %xmm0
movsd %xmm0, (%rdx,%rsi)
movsd 0xd0(%rsp), %xmm0
movsd %xmm0, 0x8(%rdx,%rsi)
movsd 0x30(%rsp), %xmm0
movsd %xmm0, 0x10(%rdx,%rsi)
movsd 0x78(%rsp), %xmm0
movsd %xmm0, 0x18(%rdx,%rsi)
ucomisd 0x1d8(%r12), %xmm0
jbe 0x898bc
movsd 0x78(%rsp), %xmm0
movsd %xmm0, 0x1d8(%r12)
movslq 0x190(%rsp), %r8
movl (%rax,%r8,4), %ecx
movl 0x128(%r12), %edi
movl 0x190(%r12), %esi
imull %edi, %esi
movl %r8d, %eax
cltd
idivl %esi
movl %eax, %esi
movl %edx, %eax
cltd
idivl %edi
movl %edx, %r9d
decl %ecx
leaq 0x1f8(%r12), %rdi
movl %esi, (%rsp)
movq %r15, %rsi
movl %r8d, %edx
movl %r9d, %r8d
movl %eax, %r9d
callq 0x1418d0
movq 0x1b0(%r12), %rax
movslq 0x190(%rsp), %rcx
decl (%rax,%rcx,4)
movsd 0x18(%rsp), %xmm0
movsd %xmm0, 0x1d8(%r12)
xorpd %xmm0, %xmm0
movapd %xmm0, 0xd0(%rsp)
movq $0x0, 0xe0(%rsp)
movq %r15, %rdi
leaq 0xd0(%rsp), %rsi
callq 0x124df0
xorpd %xmm0, %xmm0
movapd %xmm0, 0x30(%rsp)
movq $0x0, 0x40(%rsp)
movq 0xd0(%rsp), %rax
movq 0xd8(%rsp), %rdx
subq %rax, %rdx
leaq 0x30(%rsp), %r12
je 0x89a1b
sarq $0x3, %rdx
movl $0x1, %ebx
cmpq %rbx, %rdx
jbe 0x8a28b
leaq 0x1(%rbx), %rsi
cmpq %rsi, %rdx
jbe 0x8a28e
movsd -0x8(%rax,%rbx,8), %xmm0
movsd (%rax,%rbx,8), %xmm1
movsd 0x8(%rax,%rbx,8), %xmm2
movq %rbp, %rdi
callq 0x83f68
movq 0x38(%rsp), %rsi
cmpq 0x40(%rsp), %rsi
je 0x899e5
movq 0x60(%rsp), %rax
movq %rax, 0x10(%rsi)
movupd 0x50(%rsp), %xmm0
movupd %xmm0, (%rsi)
addq $0x18, 0x38(%rsp)
jmp 0x899f0
movq %r12, %rdi
movq %rbp, %rdx
callq 0x2fec4
movq 0xd0(%rsp), %rax
movq 0xd8(%rsp), %rdx
subq %rax, %rdx
sarq $0x3, %rdx
leaq 0x3(%rbx), %rcx
addq $0x2, %rbx
cmpq %rbx, %rdx
movq %rcx, %rbx
ja 0x8998f
xorpd %xmm0, %xmm0
xorpd %xmm1, %xmm1
xorpd %xmm2, %xmm2
leaq 0x190(%rsp), %rdi
callq 0x83f68
movq 0x38(%rsp), %rax
cmpq 0x30(%rsp), %rax
je 0x89c7d
xorpd %xmm0, %xmm0
movsd %xmm0, 0x18(%rsp)
xorl %ebx, %ebx
xorl %r12d, %r12d
movsd 0x18(%rsp), %xmm0
movsd %xmm0, 0x70(%rsp)
movq %r14, %rdi
xorl %esi, %esi
callq 0x83f9a
movq 0x30(%rsp), %rdi
movq 0x38(%rsp), %rdx
subq %rdi, %rdx
sarq $0x3, %rdx
imulq %r13, %rdx
cmpq %r12, %rdx
jbe 0x8a269
movsd (%rax), %xmm0
movsd %xmm0, 0x18(%rsp)
addq %rbx, %rdi
xorl %esi, %esi
callq 0x83f9a
movsd 0x18(%rsp), %xmm0
addsd (%rax), %xmm0
movsd %xmm0, 0x18(%rsp)
movq %r14, %rdi
movl $0x1, %esi
callq 0x83f9a
movq 0x30(%rsp), %rdi
movq 0x38(%rsp), %rdx
subq %rdi, %rdx
sarq $0x3, %rdx
imulq %r13, %rdx
cmpq %r12, %rdx
jbe 0x8a269
movsd (%rax), %xmm0
movsd %xmm0, 0x20(%rsp)
addq %rbx, %rdi
movl $0x1, %esi
callq 0x83f9a
movsd 0x20(%rsp), %xmm0
addsd (%rax), %xmm0
movsd %xmm0, 0x20(%rsp)
movq %r14, %rdi
movl $0x2, %esi
callq 0x83f9a
movq 0x30(%rsp), %rdi
movq 0x38(%rsp), %rdx
subq %rdi, %rdx
sarq $0x3, %rdx
imulq %r13, %rdx
cmpq %r12, %rdx
jbe 0x8a269
movsd (%rax), %xmm0
movsd %xmm0, 0x80(%rsp)
addq %rbx, %rdi
movl $0x2, %esi
callq 0x83f9a
movsd 0x20(%rsp), %xmm1
movsd 0x80(%rsp), %xmm2
addsd (%rax), %xmm2
movq %rbp, %rdi
movsd 0x18(%rsp), %xmm0
callq 0x83f68
movq 0x30(%rsp), %rdi
movq 0x38(%rsp), %rdx
subq %rdi, %rdx
sarq $0x3, %rdx
imulq %r13, %rdx
cmpq %r12, %rdx
jbe 0x8a27a
addq %rbx, %rdi
xorl %esi, %esi
callq 0x83f9a
movq 0x30(%rsp), %rdi
movq 0x38(%rsp), %rdx
subq %rdi, %rdx
sarq $0x3, %rdx
imulq %r13, %rdx
cmpq %r12, %rdx
jbe 0x8a27a
movsd (%rax), %xmm0
movsd %xmm0, 0x18(%rsp)
addq %rbx, %rdi
movl $0x1, %esi
callq 0x83f9a
movq 0x30(%rsp), %rdi
movq 0x38(%rsp), %rdx
subq %rdi, %rdx
sarq $0x3, %rdx
imulq %r13, %rdx
cmpq %r12, %rdx
jbe 0x8a27a
movsd (%rax), %xmm0
movsd %xmm0, 0x20(%rsp)
addq %rbx, %rdi
movl $0x2, %esi
callq 0x83f9a
movsd (%rax), %xmm2
xorps %xmm3, %xmm3
xorps %xmm4, %xmm4
xorps %xmm5, %xmm5
movsd 0x18(%rsp), %xmm0
movsd 0x20(%rsp), %xmm1
callq 0x84cbb
subsd 0x78(%rsp), %xmm0
movapd %xmm0, %xmm1
maxsd 0x70(%rsp), %xmm1
movsd %xmm1, 0x18(%rsp)
cmpb $0x0, 0x15d8(%rsp)
je 0x89c59
ucomisd 0x18(%rsp), %xmm0
jne 0x89c59
jp 0x89c59
movq 0x60(%rsp), %rax
movq %rax, 0x1a0(%rsp)
movupd 0x50(%rsp), %xmm0
movapd %xmm0, 0x190(%rsp)
incq %r12
movq 0x38(%rsp), %rax
subq 0x30(%rsp), %rax
sarq $0x3, %rax
imulq %r13, %rax
addq $0x18, %rbx
cmpq %r12, %rax
ja 0x89a53
jmp 0x89c87
xorpd %xmm0, %xmm0
movsd %xmm0, 0x18(%rsp)
movsd 0x48(%rsp), %xmm0
movsd 0x18(%rsp), %xmm1
ucomisd %xmm1, %xmm0
jae 0x89cdb
movapd %xmm1, %xmm0
addsd %xmm1, %xmm0
movsd %xmm0, 0x50(%rsp)
movq 0xb8(%rsp), %rsi
cmpq 0xc0(%rsp), %rsi
movq 0x1a8(%rsp), %rbx
movl 0x8c(%rsp), %r12d
je 0x89d20
movsd %xmm0, (%rsi)
addq $0x8, %rsi
movq %rsi, 0xb8(%rsp)
jmp 0x89d30
addsd %xmm0, %xmm0
movsd %xmm0, 0x50(%rsp)
movq 0xb8(%rsp), %rsi
cmpq 0xc0(%rsp), %rsi
movq 0x1a8(%rsp), %rbx
movl 0x8c(%rsp), %r12d
je 0x89da0
movsd %xmm0, (%rsi)
addq $0x8, %rsi
movq %rsi, 0xb8(%rsp)
jmp 0x89db0
leaq 0xb0(%rsp), %rdi
movq %rbp, %rdx
callq 0x1391c
cmpb $0x0, 0x15d8(%rsp)
je 0x89eee
movq 0xa0(%rsp), %rax
movq %rax, 0x60(%rsp)
movaps 0x90(%rsp), %xmm0
movaps %xmm0, 0x50(%rsp)
movsd 0x18(%rsp), %xmm0
movsd %xmm0, 0x68(%rsp)
movq 0x138(%rsp), %rsi
cmpq 0x140(%rsp), %rsi
je 0x89e1d
movapd 0x50(%rsp), %xmm0
movapd 0x60(%rsp), %xmm1
movupd %xmm1, 0x10(%rsi)
movupd %xmm0, (%rsi)
addq $0x20, %rsi
movq %rsi, 0x138(%rsp)
jmp 0x89e2d
leaq 0xb0(%rsp), %rdi
movq %rbp, %rdx
callq 0x1391c
cmpb $0x0, 0x15d8(%rsp)
je 0x89eee
movq 0xa0(%rsp), %rax
movq %rax, 0x60(%rsp)
movaps 0x90(%rsp), %xmm0
movaps %xmm0, 0x50(%rsp)
movsd 0x48(%rsp), %xmm0
movsd %xmm0, 0x68(%rsp)
movq 0x158(%rsp), %rsi
cmpq 0x160(%rsp), %rsi
je 0x89e88
movapd 0x50(%rsp), %xmm0
movapd 0x60(%rsp), %xmm1
movupd %xmm1, 0x10(%rsi)
movupd %xmm0, (%rsi)
addq $0x20, %rsi
movq %rsi, 0x158(%rsp)
jmp 0x89e98
leaq 0x130(%rsp), %rdi
movq %rbp, %rdx
callq 0x8c25c
movq 0x1a0(%rsp), %rax
movq %rax, 0x60(%rsp)
movaps 0x190(%rsp), %xmm0
movaps %xmm0, 0x50(%rsp)
movsd 0x18(%rsp), %xmm0
movsd %xmm0, 0x68(%rsp)
movq 0x118(%rsp), %rsi
cmpq 0x120(%rsp), %rsi
je 0x89ede
movapd 0x50(%rsp), %xmm0
movapd 0x60(%rsp), %xmm1
movupd %xmm1, 0x10(%rsi)
movupd %xmm0, (%rsi)
addq $0x20, %rsi
movq %rsi, 0x118(%rsp)
jmp 0x89eee
leaq 0x150(%rsp), %rdi
movq %rbp, %rdx
callq 0x8c25c
movq 0x200(%rsp), %rax
movq %rax, 0x10(%rsp)
movaps 0x1f0(%rsp), %xmm0
movups %xmm0, (%rsp)
leaq 0xfa8(%rsp), %rdi
leaq 0x1410(%rsp), %rsi
leaq 0x1d0(%rsp), %rdx
leaq 0x1b0(%rsp), %rcx
movsd 0x48(%rsp), %xmm0
callq 0x8a550
jmp 0x89eee
leaq 0x110(%rsp), %rdi
movq %rbp, %rdx
callq 0x8c25c
movq 0x30(%rsp), %rdi
testq %rdi, %rdi
je 0x89f05
movq 0x40(%rsp), %rsi
subq %rdi, %rsi
callq 0x4470
movq 0xd0(%rsp), %rdi
testq %rdi, %rdi
je 0x89f22
movq 0xe0(%rsp), %rsi
subq %rdi, %rsi
callq 0x4470
movsd 0x48(%rsp), %xmm2
movapd %xmm2, %xmm0
xorpd %xmm1, %xmm1
cmpeqsd %xmm1, %xmm0
movq %xmm0, %rax
subl %eax, 0x88(%rsp)
cmpneqsd %xmm1, %xmm2
movq %xmm2, %rax
subl %eax, %r12d
movq %r15, %rdi
callq 0x121724
incq %rbx
movq 0xf0(%rsp), %rax
movq 0xf8(%rsp), %rcx
subq %rax, %rcx
sarq $0x3, %rcx
imulq %r13, %rcx
cmpq %rbx, %rcx
ja 0x8955c
xorps %xmm1, %xmm1
cvtsi2sd %r12d, %xmm1
xorps %xmm2, %xmm2
cvtsi2sdl 0x88(%rsp), %xmm2
jmp 0x89f9b
xorpd %xmm2, %xmm2
xorpd %xmm1, %xmm1
movl 0x2c(%rsp), %r8d
xorps %xmm0, %xmm0
cvtsi2sd %r8d, %xmm0
divsd %xmm0, %xmm1
divsd %xmm0, %xmm2
leaq 0x748(%rsp), %r14
movsd 0xc82c8(%rip), %xmm0    # 0x152288
leaq 0xb0(%rsp), %rdx
movq %r14, %rdi
movl $0x3e8, %esi            # imm = 0x3E8
movq 0xc8(%rsp), %rcx
callq 0x8a669
leaq 0xcbcae(%rip), %rdi     # 0x155c92
callq 0x4660
cmpb $0x0, 0x15d8(%rsp)
je 0x8a092
leaq 0x548(%rsp), %rdi
leaq 0x150(%rsp), %rsi
leaq 0x130(%rsp), %rdx
leaq 0x240(%rsp), %rcx
leaq 0x220(%rsp), %r8
movsd 0xc7339(%rip), %xmm0    # 0x151360
xorl %r9d, %r9d
movapd %xmm0, %xmm1
callq 0x8aa47
movb 0x15e0(%rsp), %bl
leaq 0xcbc23(%rip), %rdi     # 0x155c64
callq 0x4660
testb %bl, %bl
je 0x8a092
leaq 0x348(%rsp), %rdi
leaq 0x1b0(%rsp), %rsi
leaq 0x110(%rsp), %rdx
leaq 0x240(%rsp), %rcx
leaq 0x220(%rsp), %r8
movsd 0xc72e6(%rip), %xmm0    # 0x151360
xorl %r9d, %r9d
movapd %xmm0, %xmm1
callq 0x8aa47
leaq 0xcbbef(%rip), %rdi     # 0x155c7c
callq 0x4660
leaq 0xb48(%rsp), %rdi
callq 0x48944
movq 0x110(%rsp), %rdi
testq %rdi, %rdi
je 0x8a0bc
movq 0x120(%rsp), %rsi
subq %rdi, %rsi
callq 0x4470
movq 0x1b0(%rsp), %rdi
testq %rdi, %rdi
je 0x8a0d9
movq 0x1c0(%rsp), %rsi
subq %rdi, %rsi
callq 0x4470
movq 0x1d0(%rsp), %rdi
testq %rdi, %rdi
je 0x8a0f6
movq 0x1e0(%rsp), %rsi
subq %rdi, %rsi
callq 0x4470
movq 0x130(%rsp), %rdi
testq %rdi, %rdi
je 0x8a113
movq 0x140(%rsp), %rsi
subq %rdi, %rsi
callq 0x4470
movq 0x150(%rsp), %rdi
testq %rdi, %rdi
je 0x8a130
movq 0x160(%rsp), %rsi
subq %rdi, %rsi
callq 0x4470
movq 0xb0(%rsp), %rdi
testq %rdi, %rdi
je 0x8a14d
movq 0xc0(%rsp), %rsi
subq %rdi, %rsi
callq 0x4470
movq 0x170(%rsp), %rdi
testq %rdi, %rdi
je 0x8a16a
movq 0x180(%rsp), %rsi
subq %rdi, %rsi
callq 0x4470
movq 0xf0(%rsp), %rdi
testq %rdi, %rdi
je 0x8a187
movq 0x100(%rsp), %rsi
subq %rdi, %rsi
callq 0x4470
leaq 0xb48(%rsp), %rdi
callq 0x48974
movq 0x10ae05(%rip), %rax    # 0x194fa0
movq (%rax), %rbx
movq 0x18(%rax), %r15
leaq 0x950(%rsp), %rdi
movq %rbx, -0x8(%rdi)
movq -0x18(%rbx), %rax
movq %r15, 0x948(%rsp,%rax)
callq 0x4390
movl $0xf8, %r12d
leaq 0x948(%rsp), %rdi
addq %r12, %rdi
callq 0x41a0
leaq 0x350(%rsp), %rdi
movq %rbx, -0x8(%rdi)
movq -0x18(%rbx), %rax
movq %r15, 0x348(%rsp,%rax)
callq 0x4390
leaq 0x348(%rsp), %rdi
addq %r12, %rdi
callq 0x41a0
leaq 0x550(%rsp), %rdi
movq %rbx, -0x8(%rdi)
movq -0x18(%rbx), %rax
movq %r15, 0x548(%rsp,%rax)
callq 0x4390
leaq 0x548(%rsp), %rdi
addq %r12, %rdi
callq 0x41a0
leaq 0x750(%rsp), %rdi
movq %rbx, -0x8(%rdi)
movq -0x18(%rbx), %rax
movq %r15, 0x748(%rsp,%rax)
callq 0x4390
addq %r12, %r14
movq %r14, %rdi
callq 0x41a0
addq $0x1588, %rsp           # imm = 0x1588
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
leaq 0xc3485(%rip), %rdi     # 0x14d6f5
movq %r12, %rsi
xorl %eax, %eax
callq 0x4630
leaq 0xc3474(%rip), %rdi     # 0x14d6f5
movq %r12, %rsi
xorl %eax, %eax
callq 0x4630
movq %rbx, %rsi
leaq 0xc3460(%rip), %rdi     # 0x14d6f5
xorl %eax, %eax
callq 0x4630
leaq 0xc3452(%rip), %rdi     # 0x14d6f5
movq %r12, %rsi
xorl %eax, %eax
callq 0x4630
leaq 0xc3441(%rip), %rdi     # 0x14d6f5
movq %r12, %rsi
xorl %eax, %eax
callq 0x4630
jmp 0x8a2d4
jmp 0x8a2dc
jmp 0x8a2e4
movq %rax, %rbx
jmp 0x8a45b
movq %rax, %rbx
jmp 0x8a468
movq %rax, %rbx
jmp 0x8a4a0
movq %rax, %rbx
jmp 0x8a4d8
movq %rax, %rbx
jmp 0x8a510
jmp 0x8a32a
jmp 0x8a32f
jmp 0x8a32f
jmp 0x8a32f
jmp 0x8a32f
jmp 0x8a32f
jmp 0x8a32f
jmp 0x8a32a
jmp 0x8a32a
jmp 0x8a32a
jmp 0x8a32a
jmp 0x8a32a
jmp 0x8a32f
movq %rax, %rbx
jmp 0x8a349
jmp 0x8a32a
jmp 0x8a32a
jmp 0x8a32a
jmp 0x8a32a
movq %rax, %rbx
jmp 0x8a366
jmp 0x8a32a
jmp 0x8a32a
jmp 0x8a32a
jmp 0x8a32a
jmp 0x8a32f
jmp 0x8a32f
jmp 0x8a32f
jmp 0x8a32f
jmp 0x8a32f
movq %rax, %rbx
jmp 0x8a373
movq %rax, %rbx
movq 0x30(%rsp), %rdi
testq %rdi, %rdi
je 0x8a349
movq 0x40(%rsp), %rsi
subq %rdi, %rsi
callq 0x4470
movq 0xd0(%rsp), %rdi
testq %rdi, %rdi
je 0x8a366
movq 0xe0(%rsp), %rsi
subq %rdi, %rsi
callq 0x4470
leaq 0x260(%rsp), %rdi
callq 0x121724
movq 0x110(%rsp), %rdi
testq %rdi, %rdi
je 0x8a390
movq 0x120(%rsp), %rsi
subq %rdi, %rsi
callq 0x4470
movq 0x1b0(%rsp), %rdi
testq %rdi, %rdi
je 0x8a3ad
movq 0x1c0(%rsp), %rsi
subq %rdi, %rsi
callq 0x4470
movq 0x1d0(%rsp), %rdi
testq %rdi, %rdi
je 0x8a3ca
movq 0x1e0(%rsp), %rsi
subq %rdi, %rsi
callq 0x4470
movq 0x130(%rsp), %rdi
testq %rdi, %rdi
je 0x8a3e7
movq 0x140(%rsp), %rsi
subq %rdi, %rsi
callq 0x4470
movq 0x150(%rsp), %rdi
testq %rdi, %rdi
je 0x8a404
movq 0x160(%rsp), %rsi
subq %rdi, %rsi
callq 0x4470
movq 0xb0(%rsp), %rdi
testq %rdi, %rdi
je 0x8a421
movq 0xc0(%rsp), %rsi
subq %rdi, %rsi
callq 0x4470
movq 0x170(%rsp), %rdi
testq %rdi, %rdi
je 0x8a43e
movq 0x180(%rsp), %rsi
subq %rdi, %rsi
callq 0x4470
movq 0xf0(%rsp), %rdi
testq %rdi, %rdi
je 0x8a45b
movq 0x100(%rsp), %rsi
subq %rdi, %rsi
callq 0x4470
leaq 0xb48(%rsp), %rdi
callq 0x48974
movq 0x10ab31(%rip), %rax    # 0x194fa0
movq (%rax), %rcx
movq 0x18(%rax), %rax
leaq 0x950(%rsp), %rdi
movq %rcx, -0x8(%rdi)
movq -0x18(%rcx), %rcx
movq %rax, 0x948(%rsp,%rcx)
callq 0x4390
leaq 0xa40(%rsp), %rdi
callq 0x41a0
movq 0x10aaf9(%rip), %rax    # 0x194fa0
movq (%rax), %rcx
movq 0x18(%rax), %rax
leaq 0x350(%rsp), %rdi
movq %rcx, -0x8(%rdi)
movq -0x18(%rcx), %rcx
movq %rax, 0x348(%rsp,%rcx)
callq 0x4390
leaq 0x440(%rsp), %rdi
callq 0x41a0
movq 0x10aac1(%rip), %rax    # 0x194fa0
movq (%rax), %rcx
movq 0x18(%rax), %rax
leaq 0x550(%rsp), %rdi
movq %rcx, -0x8(%rdi)
movq -0x18(%rcx), %rcx
movq %rax, 0x548(%rsp,%rcx)
callq 0x4390
leaq 0x640(%rsp), %rdi
callq 0x41a0
movq 0x10aa89(%rip), %rax    # 0x194fa0
movq (%rax), %rcx
movq 0x18(%rax), %rax
leaq 0x750(%rsp), %rdi
movq %rcx, -0x8(%rdi)
movq -0x18(%rcx), %rcx
movq %rax, 0x748(%rsp,%rcx)
callq 0x4390
leaq 0x840(%rsp), %rdi
callq 0x41a0
movq %rbx, %rdi
callq 0x4780