// File: /workspace/github_cpp_makefile_star2_O3/tomfunkhouser[P]gaps/pkgs/R3Shapes/R3Mesh.cpp
// Function: gaps::R3Mesh::ReadPlyStream(_IO_FILE*)
int R3Mesh::
ReadPlyStream(FILE *fp)
{
  int i,j;
  PlyFile *ply;
  int nelems;
  PlyProperty **plist;
  char **elist;
  int file_type;
  int nprops;
  int num_elems;
  char *elem_name;
  float version;
  int num_rows = 0;
  int num_cols = 0;

  typedef struct PlyVertex {
    float x, y, z;
    float nx, ny, nz;
    float tx, ty;
    unsigned char red, green, blue;
  } PlyVertex;

  typedef struct PlyFace {
    unsigned char nverts;
    int *verts;
    int material;
    int segment;
    int category;
  } PlyFace;

  typedef struct PlyRangeGrid {
    unsigned char nverts;
    int *verts;
  } PlyRangeGrid;

  // List of property information for a vertex 
  static PlyProperty vert_props[] = { 
    {(char *) "x", PLY_FLOAT, PLY_FLOAT, offsetof(PlyVertex,x), 0, 0, 0, 0},
    {(char *) "y", PLY_FLOAT, PLY_FLOAT, offsetof(PlyVertex,y), 0, 0, 0, 0},
    {(char *) "z", PLY_FLOAT, PLY_FLOAT, offsetof(PlyVertex,z), 0, 0, 0, 0},
    {(char *) "nx", PLY_FLOAT, PLY_FLOAT, offsetof(PlyVertex,nx), 0, 0, 0, 0},
    {(char *) "ny", PLY_FLOAT, PLY_FLOAT, offsetof(PlyVertex,ny), 0, 0, 0, 0},
    {(char *) "nz", PLY_FLOAT, PLY_FLOAT, offsetof(PlyVertex,nz), 0, 0, 0, 0},
    {(char *) "tx", PLY_FLOAT, PLY_FLOAT, offsetof(PlyVertex,tx), 0, 0, 0, 0},
    {(char *) "ty", PLY_FLOAT, PLY_FLOAT, offsetof(PlyVertex,ty), 0, 0, 0, 0},
    {(char *) "red", PLY_UCHAR, PLY_UCHAR, offsetof(PlyVertex,red), 0, 0, 0, 0},
    {(char *) "green", PLY_UCHAR, PLY_UCHAR, offsetof(PlyVertex,green), 0, 0, 0, 0},
    {(char *) "blue", PLY_UCHAR, PLY_UCHAR, offsetof(PlyVertex,blue), 0, 0, 0, 0}
  };

  // List of property information for a face 
  static PlyProperty face_props[] = { 
    {(char *) "vertex_indices", PLY_INT, PLY_INT, offsetof(PlyFace,verts), 1, PLY_UCHAR, PLY_UCHAR, offsetof(PlyFace,nverts)},
    {(char *) "vertex_index", PLY_INT, PLY_INT, offsetof(PlyFace,verts), 1, PLY_UCHAR, PLY_UCHAR, offsetof(PlyFace,nverts)},
    {(char *) "material_id", PLY_INT, PLY_INT, offsetof(PlyFace,material), 0, 0, 0, 0},
    {(char *) "segment_id", PLY_INT, PLY_INT, offsetof(PlyFace,segment), 0, 0, 0, 0},
    {(char *) "category_id", PLY_INT, PLY_INT, offsetof(PlyFace,category), 0, 0, 0, 0}
  };

  // List of property information for a range_grid
  static PlyProperty range_grid_props[] = { 
    {(char *) "vertex_indices", PLY_INT, PLY_INT, offsetof(PlyFace,verts), 1, PLY_UCHAR, PLY_UCHAR, offsetof(PlyFace,nverts)},
  };

  // Read PLY header
  ply = ply_read (fp, &nelems, &elist);
  if (!ply) {
    RNFail("Unable to read ply file header");
    fclose(fp);
    return 0;
  }
  
  // Get header info
  ply_get_info (ply, &version, &file_type);

  // Read all elements
  for (i = 0; i < nelems; i++) {
    // Get the description of the element 
    elem_name = elist[i];
    plist = ply_get_element_description (ply, elem_name, &num_elems, &nprops);

    // Check element type
    if (equal_strings ("vertex", elem_name)) {
      // Allocate block of vertices
      vertex_block = new R3MeshVertex [num_elems];

      // Resize array of vertices
      vertices.Resize(num_elems);

      // set up for getting vertex elements 
      RNBoolean has_normals = 0;
      RNBoolean has_texcoords = 0;
      RNBoolean has_colors = 0;
      for (j = 0; j < nprops; j++) {
	if (equal_strings("x", plist[j]->name)) ply_get_property (ply, elem_name, &vert_props[0]);
	else if (equal_strings("y", plist[j]->name)) ply_get_property (ply, elem_name, &vert_props[1]);
	else if (equal_strings("z", plist[j]->name)) ply_get_property (ply, elem_name, &vert_props[2]);
	else if (equal_strings("nx", plist[j]->name)) ply_get_property (ply, elem_name, &vert_props[3]); 
	else if (equal_strings("ny", plist[j]->name)) ply_get_property (ply, elem_name, &vert_props[4]); 
	else if (equal_strings("nz", plist[j]->name)) ply_get_property (ply, elem_name, &vert_props[5]);
	else if (equal_strings("tx", plist[j]->name)) ply_get_property (ply, elem_name, &vert_props[6]); 
	else if (equal_strings("ty", plist[j]->name)) ply_get_property (ply, elem_name, &vert_props[7]); 
	else if (equal_strings("red", plist[j]->name)) ply_get_property (ply, elem_name, &vert_props[8]); 
	else if (equal_strings("green", plist[j]->name)) ply_get_property (ply, elem_name, &vert_props[9]); 
	else if (equal_strings("blue", plist[j]->name)) ply_get_property (ply, elem_name, &vert_props[10]);
	if (equal_strings("nx", plist[j]->name)) has_normals = 1;
	else if (equal_strings("tx", plist[j]->name)) has_texcoords = 1;
	else if (equal_strings("red", plist[j]->name)) has_colors = 1;
      }

      // grab all the vertex elements 
      for (j = 0; j < num_elems; j++) {
        // Read vertex into local struct
        PlyVertex plyvertex;
        ply_get_element(ply, (void *) &plyvertex);

        // Create mesh vertex
        R3Point position(plyvertex.x, plyvertex.y, plyvertex.z);
        R3MeshVertex *v = CreateVertex(position, &vertex_block[j]);
        if (has_normals) {
          R3Vector normal(plyvertex.nx, plyvertex.ny, plyvertex.nz);
          SetVertexNormal(v, normal);
        }
        if (has_texcoords) {
          R2Point texcoords(plyvertex.tx, plyvertex.ty);
          SetVertexTextureCoords(v, texcoords);
        }
        if (has_colors) {
          RNRgb color(plyvertex.red/255.0, plyvertex.green/255.0, plyvertex.blue/255.0);
          SetVertexColor(v, color);
        }
      }
    }
    else if (equal_strings ("face", elem_name)) {
      // Resize array of faces
      faces.Resize(num_elems);

      // set up for getting face elements 
      for (j = 0; j < nprops; j++) {
	if (equal_strings("vertex_indices", plist[j]->name)) ply_get_property (ply, elem_name, &face_props[0]);
	else if (equal_strings("vertex_index", plist[j]->name)) ply_get_property (ply, elem_name, &face_props[1]);
	else if (equal_strings("material_id", plist[j]->name)) ply_get_property (ply, elem_name, &face_props[2]);
	else if (equal_strings("segment_id", plist[j]->name)) ply_get_property (ply, elem_name, &face_props[3]);
	else if (equal_strings("category_id", plist[j]->name)) ply_get_property (ply, elem_name, &face_props[4]);
      }

      // Create stuff for degenerate triangles
      RNArray<R3MeshVertex *> degenerate_triangle_vertices;
      int *degenerate_triangle_materials = new int [ num_elems ];
      int *degenerate_triangle_segments = new int [ num_elems ];
      int *degenerate_triangle_categories = new int [ num_elems ];
      int num_degenerate_triangles = 0;

      // grab all the face elements 
      for (j = 0; j < num_elems; j++) {
        // Read face into local struct
        PlyFace plyface;
        plyface.nverts = 0;
        plyface.verts = NULL;
        plyface.material = -1;
        plyface.segment = -1;
        plyface.category = -1;
        ply_get_element(ply, (void *) &plyface);

        // Create mesh face(s)
        R3MeshVertex *v1 = vertices[plyface.verts[0]];
        for (int k = 2; k < plyface.nverts; k++) {
          // Get vertices
          R3MeshVertex *v2 = vertices[plyface.verts[k-1]];
          R3MeshVertex *v3 = vertices[plyface.verts[k]];

          // Check plyface
          assert(plyface.verts[0] >= 0);
          assert(plyface.verts[k-1] >= 0);
          assert(plyface.verts[k] >= 0);
          assert(plyface.verts[0] < vertices.NEntries());
          assert(plyface.verts[k-1] < vertices.NEntries());
          assert(plyface.verts[k] < vertices.NEntries());

          // Check vertices
          if ((v1 == v2) || (v2 == v3) || (v1 == v3)) continue;

          // Create face
          R3MeshFace *f = CreateFace(v1, v2, v3);
          if (f) {
            // Set material/segment/category
            SetFaceMaterial(f, plyface.material);
            SetFaceSegment(f, plyface.segment);
            SetFaceCategory(f, plyface.category);
          }
          else {
            // Must have been degeneracy (e.g., three faces sharing an edge)
            // Remember for later processing (to preserve vertex indices)
            degenerate_triangle_vertices.Insert(v1);
            degenerate_triangle_vertices.Insert(v2);
            degenerate_triangle_vertices.Insert(v3);
            degenerate_triangle_materials[num_degenerate_triangles] = plyface.material;
            degenerate_triangle_segments[num_degenerate_triangles] = plyface.segment;
            degenerate_triangle_categories[num_degenerate_triangles] = plyface.category;
            num_degenerate_triangles++;
          }
        }

        // Free face data allocated by ply
        if (plyface.verts) free(plyface.verts);
      }
      
      // Create degenerate triangles (do this at end to preserve face ordering)
      for (int i = 0; i < num_degenerate_triangles; i++) {
        R3MeshVertex *v1 = degenerate_triangle_vertices.Kth(3*i + 0);
        R3MeshVertex *v2 = degenerate_triangle_vertices.Kth(3*i + 1);
        R3MeshVertex *v3 = degenerate_triangle_vertices.Kth(3*i + 2);
        R3MeshFace *f = CreateFace(v1, v2, v3);
        if (!f) {
          f = CreateFace(v1, v3, v2);
          if (!f) {
            // Note: these vertices are allocated separately, and so they will not be deleted (memory leak)
            R3MeshVertex *v1a = CreateVertex(VertexPosition(v1));
            R3MeshVertex *v2a = CreateVertex(VertexPosition(v2));
            R3MeshVertex *v3a = CreateVertex(VertexPosition(v3));
            f = CreateFace(v1a, v2a, v3a);
          }
        }
        if (f) {
          SetFaceMaterial(f, degenerate_triangle_materials[i]);
          SetFaceSegment(f, degenerate_triangle_segments[i]);
          SetFaceCategory(f, degenerate_triangle_categories[i]);
        }
      }

      // Delete memory for degenerate triangles
      delete [] degenerate_triangle_materials;
      delete [] degenerate_triangle_segments;
      delete [] degenerate_triangle_categories;
    }
    else if (equal_strings ("range_grid", elem_name)) {
      // Get num_cols and num_rows for range_grid
      int ninfo = 0;
      char **info = ply_get_obj_info(ply, &ninfo);
      for (int i = 0; i < ninfo; i++) {
        char *str = RNStrdup(info[i]);
        char *strp = strtok(str, " \n\t");
        if (strp) {
          if (!strcmp(strp, "num_rows")) {
            strp = strtok(NULL, " \n\t");
            if (strp) num_rows = atoi(strp);
          }
          else if (!strcmp(strp, "num_cols")) {
            strp = strtok(NULL, " \n\t");
            if (strp) num_cols = atoi(strp);
          }
        }
        free(str);
      }

      // check num_cols and num_rows
      if ((num_cols > 0) && (num_rows > 0) && (num_cols * num_rows == num_elems)) {
        // Allocate vertex grid
        R3MeshVertex **vertex_grid = new R3MeshVertex * [num_elems];
        for (j = 0; j < num_elems; j++) vertex_grid[j] = NULL;

        // set up for getting range grid elements 
        for (j = 0; j < nprops; j++) {
          if (equal_strings("vertex_indices", plist[j]->name)) ply_get_property (ply, elem_name, &range_grid_props[0]);
        }

        // grab all the range grid vertices
        for (j = 0; j < num_elems; j++) {
          // Read face into local struct
          PlyRangeGrid ply_range_grid;
          ply_range_grid.nverts = 0;
          ply_range_grid.verts = NULL;
          ply_get_element(ply, (void *) &ply_range_grid);
          if (!ply_range_grid.verts) continue;
          if (ply_range_grid.nverts == 0) continue;
          vertex_grid[j] = vertices[ply_range_grid.verts[0]];
          free(ply_range_grid.verts);
        }

        // create faces
        for (int row = 0; row < num_rows-1; row++) {
          for (int col = 0; col < num_cols-1; col++) {
            R3MeshVertex *v00 = vertex_grid[(row)*num_cols + (col)];
            R3MeshVertex *v01 = vertex_grid[(row+1)*num_cols + (col)];
            R3MeshVertex *v10 = vertex_grid[(row)*num_cols + (col+1)];
            R3MeshVertex *v11 = vertex_grid[(row+1)*num_cols + (col+1)];
            if (v00) {
              if (v01) {
                if (v10) {
                  if (v11) {
                    CreatePlyRangeGridFace(this, v00, v10, v11);
                    CreatePlyRangeGridFace(this, v00, v11, v01);
                  }
                  else {
                    CreatePlyRangeGridFace(this, v00, v10, v01);
                  }
                }
                else {
                  if (v11) {
                    CreatePlyRangeGridFace(this, v00, v11, v01);
                  }
                }
              }
              else {
                if (v10) {
                  if (v11) {
                    CreatePlyRangeGridFace(this, v00, v10, v11);
                  }
                }
              }
            }
            else {
              if (v01) {
                if (v10) {
                  if (v11) {
                    CreatePlyRangeGridFace(this, v10, v11, v01);
                  }
                }
              }
            }
          }
        }

        // Delete vertex grid
        delete [] vertex_grid;
      }
    }
    else {
      ply_get_other_element (ply, elem_name, num_elems);
    }
  }

  // Free the memory
  free(ply);

  // Return success
  return 1;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0xe8, %rsp
movq %rsi, %r14
movq %rdi, %rbx
leaq 0x74(%rsp), %rsi
leaq 0xc0(%rsp), %rdx
movq %r14, %rdi
callq 0x3eb93
testq %rax, %rax
je 0x209ea
movq %rax, %r15
movq %rbx, 0x8(%rsp)
leaq 0xc8(%rsp), %rsi
leaq 0xcc(%rsp), %rdx
movq %rax, %rdi
callq 0x3ffb4
cmpl $0x0, 0x74(%rsp)
movq %r15, 0x28(%rsp)
jle 0x209d9
movq 0x8(%rsp), %rax
leaq 0x8(%rax), %rcx
movq %rcx, 0x78(%rsp)
addq $0x28, %rax
movq %rax, 0xb0(%rsp)
xorl %ecx, %ecx
leaq 0x827c7(%rip), %r15     # 0xa25e1
movq $0x0, 0x60(%rsp)
movq $0x0, 0x68(%rsp)
movq 0xc0(%rsp), %rax
movq %rcx, 0xb8(%rsp)
movq (%rax,%rcx,8), %rbx
movq 0x28(%rsp), %rdi
movq %rbx, %rsi
leaq 0x4(%rsp), %rdx
leaq 0x14(%rsp), %rcx
callq 0x3f3b2
movq %rax, %r12
leaq 0x827de(%rip), %rdi     # 0xa263f
movq %rbx, %rsi
callq 0x3f121
testl %eax, %eax
je 0x1fefc
movslq 0x4(%rsp), %rbp
movq %rbp, %rax
movl $0x98, %ecx
mulq %rcx
movq %rax, %r14
seto %al
addq $0x8, %r14
movq $-0x1, %rcx
cmovbq %rcx, %r14
testb %al, %al
cmovneq %rcx, %r14
movq %r14, %rdi
callq 0xe030
leaq 0x8(%rax), %rcx
movq %rbp, (%rax)
testq %rbp, %rbp
je 0x202e0
movq %rax, %r13
movq %rbx, 0x20(%rsp)
imulq $-0x98, %rbp, %rbx
movq %rcx, 0x18(%rsp)
movq %rcx, %rbp
xorl %r15d, %r15d
movq %rbp, %rdi
callq 0x239aa
addq $-0x98, %r15
addq $0x98, %rbp
cmpq %r15, %rbx
jne 0x1fece
movl 0x4(%rsp), %esi
movq 0x20(%rsp), %rbx
movq 0x18(%rsp), %rcx
jmp 0x202e2
leaq 0x82743(%rip), %rdi     # 0xa2646
movq %rbx, %rsi
callq 0x3f121
testl %eax, %eax
je 0x20691
movq %rbx, %r14
movl 0x4(%rsp), %esi
movq 0xb0(%rsp), %rdi
callq 0x6f906
cmpl $0x0, 0x14(%rsp)
jle 0x1ffe4
xorl %ebx, %ebx
movq (%r12,%rbx,8), %rax
movq (%rax), %rsi
movq %r15, %rdi
callq 0x3f121
leaq 0xc5736(%rip), %rdx     # 0xe5680
testl %eax, %eax
jne 0x1ffc6
movq (%r12,%rbx,8), %rax
movq (%rax), %rsi
leaq 0x82694(%rip), %rdi     # 0xa25f0
callq 0x3f121
leaq 0xc5740(%rip), %rdx     # 0xe56a8
testl %eax, %eax
jne 0x1ffc6
movq (%r12,%rbx,8), %rax
movq (%rax), %rsi
leaq 0x82683(%rip), %rdi     # 0xa25fd
callq 0x3f121
leaq 0xc574a(%rip), %rdx     # 0xe56d0
testl %eax, %eax
jne 0x1ffc6
movq (%r12,%rbx,8), %rax
movq (%rax), %rsi
leaq 0x82671(%rip), %rdi     # 0xa2609
callq 0x3f121
leaq 0xc5754(%rip), %rdx     # 0xe56f8
testl %eax, %eax
jne 0x1ffc6
movq (%r12,%rbx,8), %rax
movq (%rax), %rsi
leaq 0x8265e(%rip), %rdi     # 0xa2614
callq 0x3f121
leaq 0xc575e(%rip), %rdx     # 0xe5720
testl %eax, %eax
je 0x1ffd3
movq 0x28(%rsp), %rdi
movq %r14, %rsi
callq 0x3f551
incq %rbx
movslq 0x14(%rsp), %rax
cmpq %rax, %rbx
jl 0x1ff34
leaq 0x80(%rsp), %rdi
callq 0x6f80c
movslq 0x4(%rsp), %rbx
leaq (,%rbx,4), %r14
testq %rbx, %rbx
movq $-0x1, %rax
cmovsq %rax, %r14
movq %r14, %rdi
callq 0xe030
movq %rax, 0x20(%rsp)
movq %r14, %rdi
callq 0xe030
movq %rax, 0x18(%rsp)
movq %r14, %rdi
callq 0xe030
movq %rax, 0x30(%rsp)
testl %ebx, %ebx
jle 0x202b0
xorl %r15d, %r15d
xorl %r13d, %r13d
movb $0x0, 0x38(%rsp)
movq $0x0, 0x40(%rsp)
movq $-0x1, 0x48(%rsp)
movl $0xffffffff, 0x50(%rsp) # imm = 0xFFFFFFFF
movq 0x28(%rsp), %rdi
leaq 0x38(%rsp), %rsi
callq 0x3f5d9
movq 0x40(%rsp), %rdi
cmpb $0x3, 0x38(%rsp)
jb 0x2018d
movslq (%rdi), %rax
movq 0x78(%rsp), %rcx
movq (%rcx), %rcx
movq (%rcx,%rax,8), %r14
movl $0x2, %ebx
movq 0x40(%rsp), %rax
movslq -0x4(%rax,%rbx,4), %rdx
movq 0x78(%rsp), %rcx
movq (%rcx), %rcx
movq (%rcx,%rdx,8), %rbp
cmpq %rbp, %r14
je 0x20172
movslq (%rax,%rbx,4), %rax
movq (%rcx,%rax,8), %r12
cmpq %r12, %rbp
je 0x20172
cmpq %r12, %r14
je 0x20172
movq 0x8(%rsp), %rdi
movq (%rdi), %rax
movq %r14, %rsi
movq %rbp, %rdx
movq %r12, %rcx
xorl %r8d, %r8d
callq *0x48(%rax)
testq %rax, %rax
je 0x20100
movq 0x48(%rsp), %rcx
movq %rcx, 0x98(%rax)
movl 0x50(%rsp), %ecx
movl %ecx, 0xa0(%rax)
jmp 0x20172
movl 0x8c(%rsp), %edx
leaq 0x80(%rsp), %rdi
movq %r14, %rsi
callq 0x6f8a2
movl 0x8c(%rsp), %edx
leaq 0x80(%rsp), %rdi
movq %rbp, %rsi
callq 0x6f8a2
movl 0x8c(%rsp), %edx
leaq 0x80(%rsp), %rdi
movq %r12, %rsi
callq 0x6f8a2
movl 0x48(%rsp), %eax
movslq %r13d, %r13
movq 0x20(%rsp), %rcx
movl %eax, (%rcx,%r13,4)
movl 0x4c(%rsp), %eax
movq 0x18(%rsp), %rcx
movl %eax, (%rcx,%r13,4)
movl 0x50(%rsp), %eax
movq 0x30(%rsp), %rcx
movl %eax, (%rcx,%r13,4)
incl %r13d
incq %rbx
movzbl 0x38(%rsp), %eax
cmpq %rax, %rbx
jb 0x20093
movq 0x40(%rsp), %rdi
testq %rdi, %rdi
je 0x20192
callq 0xe540
incl %r15d
cmpl 0x4(%rsp), %r15d
jl 0x20041
testl %r13d, %r13d
jle 0x202b0
movl %r13d, %ebx
movl $0x10, %r13d
xorl %r15d, %r15d
movq %rbx, 0x98(%rsp)
movq 0x80(%rsp), %rax
movq -0x10(%rax,%r13), %rbp
movq -0x8(%rax,%r13), %r12
movq (%rax,%r13), %r14
movq 0x8(%rsp), %rdi
movq (%rdi), %rax
movq %rbp, %rsi
movq %r12, %rdx
movq %r14, %rcx
xorl %r8d, %r8d
callq *0x48(%rax)
testq %rax, %rax
jne 0x20273
movq 0x8(%rsp), %rdi
movq (%rdi), %rax
movq %rbp, %rsi
movq %r14, %rdx
movq %r12, %rcx
xorl %r8d, %r8d
callq *0x48(%rax)
testq %rax, %rax
jne 0x20273
addq $0x18, %rbp
movq 0x8(%rsp), %rbx
movq (%rbx), %rax
movq %rbx, %rdi
movq %rbp, %rsi
xorl %edx, %edx
callq *0x20(%rax)
movq %rax, %rbp
addq $0x18, %r12
movq (%rbx), %rax
movq %rbx, %rdi
movq %r12, %rsi
xorl %edx, %edx
callq *0x20(%rax)
movq %rax, %r12
addq $0x18, %r14
movq (%rbx), %rax
movq %rbx, %rdi
movq %r14, %rsi
xorl %edx, %edx
callq *0x20(%rax)
movq (%rbx), %r9
movq %rbx, %rdi
movq %rbp, %rsi
movq %r12, %rdx
movq %rax, %rcx
xorl %r8d, %r8d
callq *0x48(%r9)
testq %rax, %rax
movq 0x98(%rsp), %rbx
je 0x202a0
movq 0x20(%rsp), %rcx
movl (%rcx,%r15,4), %ecx
movl %ecx, 0x98(%rax)
movq 0x18(%rsp), %rcx
movl (%rcx,%r15,4), %ecx
movl %ecx, 0x9c(%rax)
movq 0x30(%rsp), %rcx
movl (%rcx,%r15,4), %ecx
movl %ecx, 0xa0(%rax)
incq %r15
addq $0x18, %r13
cmpq %r15, %rbx
jne 0x201bd
movq 0x20(%rsp), %rdi
callq 0xe5b0
movq 0x18(%rsp), %rdi
callq 0xe5b0
movq 0x30(%rsp), %rdi
callq 0xe5b0
leaq 0x80(%rsp), %rdi
callq 0x6f876
jmp 0x2066c
xorl %esi, %esi
movq 0x8(%rsp), %rax
movq %rcx, 0x38(%rax)
movq 0x78(%rsp), %rdi
callq 0x6f906
cmpl $0x0, 0x14(%rsp)
jle 0x2050d
xorl %r14d, %r14d
xorl %r13d, %r13d
movl $0x0, 0x18(%rsp)
xorl %ebp, %ebp
leaq 0x822ca(%rip), %r15     # 0xa25e1
movq (%r12,%r14,8), %rax
movq (%rax), %rsi
leaq 0x8af0d(%rip), %rdi     # 0xab232
callq 0x3f121
leaq 0xc518f(%rip), %rdx     # 0xe54c0
testl %eax, %eax
jne 0x20479
movq (%r12,%r14,8), %rax
movq (%rax), %rsi
leaq 0x82023(%rip), %rdi     # 0xa236a
callq 0x3f121
leaq 0xc5195(%rip), %rdx     # 0xe54e8
testl %eax, %eax
jne 0x20479
movq (%r12,%r14,8), %rax
movq (%rax), %rsi
leaq 0x82264(%rip), %rdi     # 0xa25cd
callq 0x3f121
leaq 0xc519b(%rip), %rdx     # 0xe5510
testl %eax, %eax
jne 0x20479
movq (%r12,%r14,8), %rax
movq (%rax), %rsi
leaq 0x8223b(%rip), %rdi     # 0xa25c6
callq 0x3f121
leaq 0xc51a1(%rip), %rdx     # 0xe5538
testl %eax, %eax
jne 0x20479
movq (%r12,%r14,8), %rax
movq (%rax), %rsi
leaq 0x8221c(%rip), %rdi     # 0xa25c9
callq 0x3f121
leaq 0xc51a7(%rip), %rdx     # 0xe5560
testl %eax, %eax
jne 0x20479
movq (%r12,%r14,8), %rax
movq (%rax), %rsi
leaq 0x821fd(%rip), %rdi     # 0xa25cc
callq 0x3f121
leaq 0xc51ad(%rip), %rdx     # 0xe5588
testl %eax, %eax
jne 0x20479
movq (%r12,%r14,8), %rax
movq (%rax), %rsi
leaq 0x821de(%rip), %rdi     # 0xa25cf
callq 0x3f121
leaq 0xc51b3(%rip), %rdx     # 0xe55b0
testl %eax, %eax
jne 0x20479
movq (%r12,%r14,8), %rax
movq (%rax), %rsi
leaq 0x88783(%rip), %rdi     # 0xa8b92
callq 0x3f121
leaq 0xc51bd(%rip), %rdx     # 0xe55d8
testl %eax, %eax
jne 0x20479
movq (%r12,%r14,8), %rax
movq (%rax), %rsi
leaq 0x821a5(%rip), %rdi     # 0xa25d2
callq 0x3f121
leaq 0xc51c7(%rip), %rdx     # 0xe5600
testl %eax, %eax
jne 0x20479
movq (%r12,%r14,8), %rax
movq (%rax), %rsi
leaq 0x8218b(%rip), %rdi     # 0xa25d6
callq 0x3f121
leaq 0xc51d1(%rip), %rdx     # 0xe5628
testl %eax, %eax
jne 0x20479
movq (%r12,%r14,8), %rax
movq (%rax), %rsi
leaq 0x82173(%rip), %rdi     # 0xa25dc
callq 0x3f121
leaq 0xc51db(%rip), %rdx     # 0xe5650
testl %eax, %eax
je 0x20486
movq 0x28(%rsp), %rdi
movq %rbx, %rsi
callq 0x3f551
movq (%r12,%r14,8), %rax
movq (%rax), %rsi
leaq 0x82132(%rip), %rdi     # 0xa25c6
callq 0x3f121
testl %eax, %eax
je 0x204a5
movl $0x1, %r13d
jmp 0x204e3
movq (%r12,%r14,8), %rax
movq (%rax), %rsi
leaq 0x8211c(%rip), %rdi     # 0xa25cf
callq 0x3f121
testl %eax, %eax
je 0x204c6
movl $0x1, 0x18(%rsp)
jmp 0x204e3
movq (%r12,%r14,8), %rax
movq (%rax), %rsi
leaq 0x820fe(%rip), %rdi     # 0xa25d2
callq 0x3f121
testl %eax, %eax
movl $0x1, %eax
cmovnel %eax, %ebp
incq %r14
movslq 0x14(%rsp), %rax
cmpq %rax, %r14
jl 0x20317
testl %r13d, %r13d
sete 0x20(%rsp)
cmpl $0x0, 0x18(%rsp)
sete %r12b
testl %ebp, %ebp
sete %bpl
jmp 0x2051f
movb $0x1, %bpl
movb $0x1, %r12b
movb $0x1, 0x20(%rsp)
leaq 0x820c2(%rip), %r15     # 0xa25e1
cmpl $0x0, 0x4(%rsp)
jle 0x20673
xorl %r13d, %r13d
xorl %r15d, %r15d
movq 0x28(%rsp), %rdi
leaq 0x38(%rsp), %rsi
callq 0x3f5d9
xorps %xmm0, %xmm0
cvtss2sd 0x38(%rsp), %xmm0
xorps %xmm1, %xmm1
cvtss2sd 0x3c(%rsp), %xmm1
xorps %xmm2, %xmm2
cvtss2sd 0x40(%rsp), %xmm2
leaq 0x80(%rsp), %r14
movq %r14, %rdi
callq 0x3c532
movq 0x8(%rsp), %rdi
movq 0x38(%rdi), %rdx
addq %r13, %rdx
movq (%rdi), %rax
movq %r14, %rsi
callq *0x20(%rax)
movq %rax, %r14
cmpb $0x0, 0x20(%rsp)
jne 0x205c5
xorps %xmm0, %xmm0
cvtss2sd 0x44(%rsp), %xmm0
xorps %xmm1, %xmm1
cvtss2sd 0x48(%rsp), %xmm1
xorps %xmm2, %xmm2
cvtss2sd 0x4c(%rsp), %xmm2
leaq 0xd0(%rsp), %rbx
movq %rbx, %rdi
callq 0x3cfc6
leaq 0x30(%r14), %rdi
movq %rbx, %rsi
callq 0x3d752
orb $0x2, 0x78(%r14)
testb %r12b, %r12b
jne 0x205f8
xorps %xmm0, %xmm0
cvtss2sd 0x50(%rsp), %xmm0
xorps %xmm1, %xmm1
cvtss2sd 0x54(%rsp), %xmm1
leaq 0xd0(%rsp), %rbx
movq %rbx, %rdi
callq 0x680a6
leaq 0x48(%r14), %rdi
movq %rbx, %rsi
callq 0x681de
testb %bpl, %bpl
jne 0x20654
movzbl 0x58(%rsp), %eax
xorps %xmm0, %xmm0
cvtsi2sd %eax, %xmm0
movsd 0x81c07(%rip), %xmm3    # 0xa2218
divsd %xmm3, %xmm0
movzbl 0x59(%rsp), %eax
xorps %xmm1, %xmm1
cvtsi2sd %eax, %xmm1
divsd %xmm3, %xmm1
movzbl 0x5a(%rsp), %eax
xorps %xmm2, %xmm2
cvtsi2sd %eax, %xmm2
divsd %xmm3, %xmm2
leaq 0xd0(%rsp), %rbx
movq %rbx, %rdi
callq 0x6f680
addq $0x58, %r14
movq %r14, %rdi
movq %rbx, %rsi
callq 0x6f712
incq %r15
movslq 0x4(%rsp), %rax
addq $0x98, %r13
cmpq %rax, %r15
jl 0x20530
leaq 0x81f6e(%rip), %r15     # 0xa25e1
movq 0xb8(%rsp), %rcx
incq %rcx
movslq 0x74(%rsp), %rax
cmpq %rax, %rcx
jl 0x1fe2c
jmp 0x209d9
leaq 0x81fb3(%rip), %rdi     # 0xa264b
movq %rbx, %rsi
callq 0x3f121
testl %eax, %eax
je 0x209c3
movl $0x0, 0x80(%rsp)
movq 0x28(%rsp), %rdi
leaq 0x80(%rsp), %rsi
callq 0x3fb11
cmpl $0x0, 0x80(%rsp)
jle 0x20781
movq %rax, %r13
xorl %r15d, %r15d
movq (%r13,%r15,8), %rdi
callq 0x71833
movq %rax, %r14
movq %rax, %rdi
leaq 0x81f66(%rip), %rsi     # 0xa2656
callq 0xe710
testq %rax, %rax
je 0x20765
movq %rax, %rbp
movq %rax, %rdi
leaq 0x81f53(%rip), %rsi     # 0xa265a
callq 0xe640
testl %eax, %eax
je 0x20745
movq %rbp, %rdi
leaq 0x81f49(%rip), %rsi     # 0xa2663
callq 0xe640
testl %eax, %eax
jne 0x20765
xorl %edi, %edi
leaq 0x81f2a(%rip), %rsi     # 0xa2656
callq 0xe710
testq %rax, %rax
je 0x20765
movq %rax, %rdi
callq 0xe700
movq %rax, 0x68(%rsp)
jmp 0x20765
xorl %edi, %edi
leaq 0x81f08(%rip), %rsi     # 0xa2656
callq 0xe710
testq %rax, %rax
je 0x20765
movq %rax, %rdi
callq 0xe700
movq %rax, 0x60(%rsp)
movq %r14, %rdi
callq 0xe540
incq %r15
movslq 0x80(%rsp), %rax
cmpq %rax, %r15
jl 0x206d9
cmpl $0x0, 0x68(%rsp)
jle 0x2066c
cmpl $0x0, 0x60(%rsp)
jle 0x2066c
movq 0x60(%rsp), %rax
imull 0x68(%rsp), %eax
cmpl 0x4(%rsp), %eax
jne 0x2066c
movl %eax, %r14d
shlq $0x3, %r14
movq %r14, %rdi
callq 0xe030
movq %rax, 0x30(%rsp)
movq %rax, %rdi
xorl %esi, %esi
movq %r14, %rdx
callq 0xe260
cmpl $0x0, 0x14(%rsp)
leaq 0x81e09(%rip), %r14     # 0xa25e1
leaq 0xc4f71(%rip), %r15     # 0xe5750
jle 0x2081d
movq %rbx, %r13
xorl %ebx, %ebx
movq (%r12,%rbx,8), %rax
movq (%rax), %rsi
movq %r14, %rdi
callq 0x3f121
testl %eax, %eax
je 0x20809
movq 0x28(%rsp), %rdi
movq %r13, %rsi
movq %r15, %rdx
callq 0x3f551
incq %rbx
movslq 0x14(%rsp), %rax
cmpq %rax, %rbx
jl 0x207e6
cmpl $0x0, 0x4(%rsp)
jle 0x20877
xorl %ebx, %ebx
movb $0x0, 0x38(%rsp)
movq $0x0, 0x40(%rsp)
movq 0x28(%rsp), %rdi
leaq 0x38(%rsp), %rsi
callq 0x3f5d9
movq 0x40(%rsp), %rdi
testq %rdi, %rdi
je 0x2086a
cmpb $0x0, 0x38(%rsp)
je 0x2086a
movslq (%rdi), %rax
movq 0x78(%rsp), %rcx
movq (%rcx), %rcx
movq (%rcx,%rax,8), %rax
movq 0x30(%rsp), %rcx
movq %rax, (%rcx,%rbx,8)
callq 0xe540
incq %rbx
movslq 0x4(%rsp), %rax
cmpq %rax, %rbx
jl 0x2081f
cmpl $0x2, 0x60(%rsp)
jl 0x209b4
movq 0x60(%rsp), %rax
leal -0x1(%rax), %ecx
movq 0x68(%rsp), %rax
leal -0x1(%rax), %edx
movq %rdx, 0x20(%rsp)
movl %eax, %eax
movq 0x30(%rsp), %rdx
addq $0x8, %rdx
movq %rdx, 0xa0(%rsp)
shlq $0x3, %rax
movq %rax, 0xa8(%rsp)
xorl %r15d, %r15d
movq %rcx, 0x98(%rsp)
cmpl $0x1, 0x68(%rsp)
jle 0x20993
leaq 0x1(%r15), %rcx
movq 0xa8(%rsp), %rax
movq %rax, %r13
movq %rcx, 0x18(%rsp)
imulq %rcx, %r13
movq 0xa0(%rsp), %rcx
addq %rcx, %r13
imulq %rax, %r15
addq %rcx, %r15
xorl %ebx, %ebx
movq -0x8(%r15,%rbx,8), %rbp
movq (%r15,%rbx,8), %rdx
movq -0x8(%r13,%rbx,8), %r12
movq (%r13,%rbx,8), %r14
testq %rbp, %rbp
je 0x20931
testq %r12, %r12
je 0x2094a
testq %rdx, %rdx
je 0x20961
testq %r14, %r14
je 0x20989
movq 0x8(%rsp), %rdi
movq %rbp, %rsi
movq %r14, %rcx
callq 0x20a81
jmp 0x20966
testq %r12, %r12
je 0x20979
testq %rdx, %rdx
je 0x20979
testq %r14, %r14
je 0x20979
movq 0x8(%rsp), %rdi
movq %rdx, %rsi
jmp 0x2096e
testq %rdx, %rdx
je 0x20979
testq %r14, %r14
je 0x20979
movq 0x8(%rsp), %rdi
movq %rbp, %rsi
movq %r14, %rcx
jmp 0x20974
testq %r14, %r14
je 0x20979
movq 0x8(%rsp), %rdi
movq %rbp, %rsi
movq %r14, %rdx
movq %r12, %rcx
callq 0x20a81
incq %rbx
cmpq %rbx, 0x20(%rsp)
jne 0x208f8
jmp 0x2099b
movq 0x8(%rsp), %rdi
movq %rbp, %rsi
jmp 0x20971
incq %r15
movq %r15, %rax
jmp 0x209ab
movq 0x18(%rsp), %rax
movq %rax, %r15
movq 0x98(%rsp), %rcx
cmpq %rcx, %rax
jne 0x208c1
movq 0x30(%rsp), %rdi
callq 0xe5b0
jmp 0x2066c
movl 0x4(%rsp), %edx
movq 0x28(%rsp), %rdi
movq %rbx, %rsi
callq 0x3fcd8
jmp 0x20673
movq 0x28(%rsp), %rdi
callq 0xe540
movl $0x1, %ebx
jmp 0x20a02
leaq 0x81c2f(%rip), %rdi     # 0xa2620
xorl %ebx, %ebx
xorl %eax, %eax
callq 0x719d2
movq %r14, %rdi
callq 0xe430
movl %ebx, %eax
addq $0xe8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
jmp 0x20a69
jmp 0x20a69
jmp 0x20a69
jmp 0x20a69
jmp 0x20a69
jmp 0x20a69
jmp 0x20a69
jmp 0x20a69
movq %rax, %rbx
testq %r15, %r15
je 0x20a5c
negq %r15
movq %r13, %r12
addq $-0x88, %r12
leaq 0xc0cbe(%rip), %rbp     # 0xe1700
movq %rbp, -0x90(%r13,%r15)
leaq (%r12,%r15), %rdi
callq 0x6f876
addq $-0x98, %r15
jne 0x20a42
movq %r13, %rdi
movq %r14, %rsi
callq 0xe8c0
jmp 0x20a79
movq %rax, %rbx
leaq 0x80(%rsp), %rdi
callq 0x6f876
movq %rbx, %rdi
callq 0xe7e0