// File: nikolausmayer[P]SimplePlot/./Sparkline.h
// Function: std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> Sparkline::Sparkline<float>(float const*, unsigned long, unsigned long, unsigned long, bool, bool, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, float, float)
std::string Sparkline( const T* const data,
                         size_t number_of_data_points,
                         size_t this_many_lines_high=1,
                         size_t this_many_characters_wide=0,
                         bool enclose_in_box=false,
                         bool print_colored=true,
                         std::string title="",
                         T minv=std::numeric_limits<T>::max(),
                         T maxv=std::numeric_limits<T>::min()
                       ) 
  {
    /// Use provided min/max values or adapt to data range
    minv = std::min(minv, std::numeric_limits<T>::max());
    maxv = std::max(maxv, std::numeric_limits<T>::min());
    if ( minv == std::numeric_limits<T>::max() and
         maxv == std::numeric_limits<T>::min() ) {
      for ( size_t i = 0; i < number_of_data_points; ++i ) {
        minv = std::min(minv, data[i]);
        maxv = std::max(maxv, data[i]);
      }
    }

    /// If the plot could spill over the terminal boundaries,
    /// then limit its width
    float w_scale = 1.f;
    {
      size_t max_width = (size_t)SparklineHelpers::TerminalWidth();
      if ( enclose_in_box ) 
        max_width -= ENCLOSURE_WIDTH;

      if ( this_many_characters_wide == 0 )
        this_many_characters_wide = number_of_data_points;

      if ( max_width < this_many_characters_wide )
        this_many_characters_wide = max_width;

      w_scale = (float)this_many_characters_wide/number_of_data_points;
    }

    /// TODO 
    if ( this_many_characters_wide > number_of_data_points ) {
      throw std::runtime_error("Woops! Not implemented..");
    }

    /// Interpolate data points
    T bins[this_many_characters_wide];
    {
      float bin_slices_indices[this_many_characters_wide+1];
      for ( size_t i = 0; i <= this_many_characters_wide; ++i ) {
        bin_slices_indices[i] = i/w_scale;
      }

      const float mass_per_bin = 1/w_scale;

      for ( size_t i = 0; i < this_many_characters_wide; ++i ) {
        bins[i] = 0;

        const float lower = bin_slices_indices[i];
        const float upper = bin_slices_indices[i+1];
        bins[i] += (1.f-(lower-(size_t)lower)) * data[(size_t)lower];
        for (size_t j = (size_t)lower+1; j < (size_t)upper; ++j) {
          bins[i] += data[j];
        }
        if ((size_t)upper < number_of_data_points) {
          bins[i] += (upper-(size_t)upper) * data[(size_t)upper];
        }

        bins[i] /= mass_per_bin;
      }
    }
         

    #ifdef WITH_TEXTDECORATOR
      TextDecorator::TextDecorator TD(print_colored);
    #endif

    /// Assemble the output in a stringstream
    std::ostringstream oss;

    /// Begin box (upper border)
    if ( enclose_in_box ) {
      if ( title.compare("") == 0 ) {
        oss << GREEN(BOX_NW_CORNER);
        for ( size_t i = 0; i < this_many_characters_wide; ++i )
          oss << GREEN(BOX_H_BORDER);
        oss << GREEN(BOX_NE_CORNER) << '\n';
      } else if ( title.size() > this_many_characters_wide ) {
        oss << GREEN(title) << '\n';
      } else {
        size_t filler = this_many_characters_wide-title.size();
        oss << GREEN(BOX_NW_CORNER);
        size_t i = 0;
        /// Ticks left of the title
        while ( i < filler/2 ) {
          oss << GREEN(BOX_H_BORDER);
          ++i;
        }
        oss << GREEN(title);
        /// Skip ticks covered by title
        i += title.length();
        /// Ticks right of the title
        while ( i < this_many_characters_wide ) {
          oss << GREEN(BOX_H_BORDER);
          ++i;
        }
        oss << GREEN(BOX_NE_CORNER) << '\n';
      }
    }


    /// A higher line count means we can display the data more
    /// finely grained!
    size_t levels = this_many_lines_high*TICKS-1;
    /// Stretch plot over multiple lines if requested
    for ( int line = (int)this_many_lines_high-1; line >= 0; --line ) {
      int this_line_min_index = line*TICKS;
      int this_line_max_index = this_line_min_index+(TICKS-1);

      /// Left box border
      if ( enclose_in_box )
        oss << GREEN(BOX_V_BORDER);

      /// Go through all data points
      for ( size_t i = 0; i < this_many_characters_wide; ++i ) {
        const T _data = std::min(maxv, std::max(minv, bins[i]));
        float fraction = (float)(_data-minv)/(float)(maxv-minv);
        int index = std::floor(fraction*levels);
        if ( index < this_line_min_index ) {
          /// Current cell is above the data line -> empty
          oss << ' '; 
        } else if ( index > this_line_max_index ) {
          /// Current cell is below the data line -> solid
          oss << BLUE(ticks[TICKS-1]);
        } else {
          oss << BLUE(ticks[index-this_line_min_index]);
        }
      }

      /// Right box border and min/max value marks
      if ( enclose_in_box ) {
        if ( this_many_lines_high == 1 )
          oss << GREEN(BOX_V_BORDER_TICK) 
              << GREEN(" min: ")
              << std::left << std::setw(PREC) << GREEN(minv) 
              << GREEN(", max: ") 
              << std::left << std::setw(PREC) << GREEN(maxv);
        else if ( line == (int)this_many_lines_high-1 )
          oss << GREEN(BOX_V_BORDER_TICK) << GREEN(" max: ") << GREEN(maxv);
        else if ( line == 0 )
          oss << GREEN(BOX_V_BORDER_TICK) << GREEN(" min: ") << GREEN(minv);
        else
          /// Show "middle" level of this line
          oss << GREEN(BOX_V_BORDER_TICK) << GREEN("      ") 
              << GREEN((line*TICKS+4) * 
                  (maxv-minv)/(this_many_lines_high*TICKS) + minv);
          //oss << GREEN(BOX_V_BORDER);
      }

      if ( line > 0 )
        oss << '\n';
    }

    /// Finish box (lower border and sample index marks)
    if ( enclose_in_box ) {
      /// Compute tick marks positions
      const size_t sep = 2;
      const size_t x_ticks_separation = 2*sep + std::ceil(log10(number_of_data_points+1));
      const size_t x_ticks_number = this_many_characters_wide / x_ticks_separation + 1;
      size_t x_ticks[x_ticks_number];
      size_t x_ticks_values[x_ticks_number];
      for ( size_t i = 0; i < x_ticks_number-1; ++i ) {
        x_ticks[i]        = i*x_ticks_separation;
        x_ticks_values[i] = i*number_of_data_points/x_ticks_number;
      }
      x_ticks[x_ticks_number-1]        = this_many_characters_wide-1;
      x_ticks_values[x_ticks_number-1] = number_of_data_points;

      size_t next_tick = 0;
      oss << '\n';

      oss << GREEN(BOX_SW_CORNER);
      for ( size_t i = 0; i < this_many_characters_wide; ++i )
        if ( i == x_ticks[next_tick] ) {
          oss << GREEN(BOX_H_BORDER_TICK);
          ++next_tick;
        } else {
          oss << GREEN(BOX_H_BORDER);
        }
      oss << GREEN(BOX_SE_CORNER);


      /// X-ticks values
      {
        oss << "\n " << GREEN(x_ticks_values[0]);

        /// Keep track of the line length
        size_t current_col = 1;
        for ( size_t i = 1; i < x_ticks_number-1; ++i ) {
          /// We somehow have to distribute the string representations
          /// of the tick numbers over the length of one line.
          /// 
          ///           x_ticks_separation
          ///      vvvvvvv       >      vvvvvvv   
          ///                    > 
          ///       tofill       >       tofill
          ///        vvvv        >        vvv
          /// ...──┬──────┬──... > ...──┬──────┬──...
          ///     998    999     >     999   1000
          ///       ^    ^^      >       ^   ^^
          ///      lw    rw      >      lw   rw

          /// Width of the current tick's number
          size_t tmp = SparklineHelpers::CharLength(x_ticks_values[i]);
          current_col += tmp;
          /// This iteration takes tmp-tmp/2 characters of the total
          /// width of the next entry. The remaining tmp-2 characters
          /// will by covered by "lw" in the next iteration.
          const size_t rw = tmp-tmp/2;
          /// Width of the previous tick's number
          tmp = SparklineHelpers::CharLength(x_ticks_values[i-1]);
          const size_t lw = tmp/2;

          /// The remaining sepration space is filled with blanks
          size_t tofill = x_ticks_separation - rw - lw;
          oss << std::setw(tofill) << std::setfill(' ') << ' ';
          oss << GREEN(x_ticks_values[i]);

          current_col += tofill;
        }

        oss << std::setw(x_ticks[x_ticks_number-1]
               - current_col
               - SparklineHelpers::CharLength(number_of_data_points)+2)
            << ' ';
        oss << GREEN(x_ticks_values[x_ticks_number-1]) 
            << std::endl;
      }
    }

    return oss.str();
  }

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x4c0, %rsp            # imm = 0x4C0
movl %r9d, %eax
movq %rcx, -0x330(%rbp)
movq %rdx, %rcx
movq -0x330(%rbp), %rdx
movq %rcx, -0x328(%rbp)
movq %rsi, %rcx
movq -0x328(%rbp), %rsi
movq %rcx, -0x320(%rbp)
movq %rdi, %r9
movq -0x320(%rbp), %rdi
movq %r9, -0x318(%rbp)
movb %al, %cl
movq %r9, %rax
movq %rax, -0x310(%rbp)
movq 0x18(%rbp), %rax
movq %rax, -0x308(%rbp)
movb 0x10(%rbp), %al
movq %r9, -0x8(%rbp)
movq %rdi, -0x10(%rbp)
movq %rsi, -0x18(%rbp)
movq %rdx, -0x20(%rbp)
movq %r8, -0x28(%rbp)
andb $0x1, %cl
movb %cl, -0x29(%rbp)
andb $0x1, %al
movb %al, -0x2a(%rbp)
movss %xmm0, -0x30(%rbp)
movss %xmm1, -0x34(%rbp)
callq 0x60a0
movss %xmm0, -0x38(%rbp)
leaq -0x30(%rbp), %rdi
leaq -0x38(%rbp), %rsi
callq 0x67d0
movss (%rax), %xmm0
movss %xmm0, -0x30(%rbp)
callq 0x60b0
movss %xmm0, -0x3c(%rbp)
leaq -0x34(%rbp), %rdi
leaq -0x3c(%rbp), %rsi
callq 0x6810
movss (%rax), %xmm0
movss %xmm0, -0x34(%rbp)
movss -0x30(%rbp), %xmm0
movss %xmm0, -0x300(%rbp)
callq 0x60a0
movaps %xmm0, %xmm1
movss -0x300(%rbp), %xmm0
ucomiss %xmm1, %xmm0
jne 0x4bef
jp 0x4bef
movss -0x34(%rbp), %xmm0
movss %xmm0, -0x334(%rbp)
callq 0x60b0
movaps %xmm0, %xmm1
movss -0x334(%rbp), %xmm0
ucomiss %xmm1, %xmm0
jne 0x4bef
jp 0x4bef
movq $0x0, -0x48(%rbp)
movq -0x48(%rbp), %rax
cmpq -0x18(%rbp), %rax
jae 0x4bed
movq -0x10(%rbp), %rsi
movq -0x48(%rbp), %rax
shlq $0x2, %rax
addq %rax, %rsi
leaq -0x30(%rbp), %rdi
callq 0x67d0
movss (%rax), %xmm0
movss %xmm0, -0x30(%rbp)
movq -0x10(%rbp), %rsi
movq -0x48(%rbp), %rax
shlq $0x2, %rax
addq %rax, %rsi
leaq -0x34(%rbp), %rdi
callq 0x6810
movss (%rax), %xmm0
movss %xmm0, -0x34(%rbp)
movq -0x48(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x48(%rbp)
jmp 0x4b93
jmp 0x4bef
movss 0x3461(%rip), %xmm0     # 0x8058
movss %xmm0, -0x4c(%rbp)
callq 0x2d00
movzwl %ax, %eax
movq %rax, -0x58(%rbp)
testb $0x1, -0x29(%rbp)
je 0x4c1a
movq -0x58(%rbp), %rax
subq $0x14, %rax
movq %rax, -0x58(%rbp)
cmpq $0x0, -0x28(%rbp)
jne 0x4c29
movq -0x18(%rbp), %rax
movq %rax, -0x28(%rbp)
movq -0x58(%rbp), %rax
cmpq -0x28(%rbp), %rax
jae 0x4c3b
movq -0x58(%rbp), %rax
movq %rax, -0x28(%rbp)
movq -0x28(%rbp), %rax
movq %rax, %rdx
shrq %rdx
movl %eax, %ecx
andl $0x1, %ecx
orq %rdx, %rcx
cvtsi2ss %rcx, %xmm0
addss %xmm0, %xmm0
cvtsi2ss %rax, %xmm1
movss %xmm1, -0x33c(%rbp)
testq %rax, %rax
movss %xmm0, -0x338(%rbp)
js 0x4c80
movss -0x33c(%rbp), %xmm0
movss %xmm0, -0x338(%rbp)
movss -0x338(%rbp), %xmm0
movss %xmm0, -0x348(%rbp)
movq -0x18(%rbp), %rax
movq %rax, %rdx
shrq %rdx
movl %eax, %ecx
andl $0x1, %ecx
orq %rdx, %rcx
cvtsi2ss %rcx, %xmm0
addss %xmm0, %xmm0
cvtsi2ss %rax, %xmm1
movss %xmm1, -0x344(%rbp)
testq %rax, %rax
movss %xmm0, -0x340(%rbp)
js 0x4cd5
movss -0x344(%rbp), %xmm0
movss %xmm0, -0x340(%rbp)
movss -0x348(%rbp), %xmm0
movss -0x340(%rbp), %xmm1
divss %xmm1, %xmm0
movss %xmm0, -0x4c(%rbp)
movq -0x28(%rbp), %rax
cmpq -0x18(%rbp), %rax
jbe 0x4d54
movl $0x10, %edi
callq 0x2140
movq %rax, %rdi
movq %rdi, %rax
movq %rax, -0x350(%rbp)
leaq 0x374f(%rip), %rsi      # 0x8465
callq 0x2100
jmp 0x4d1d
movq -0x350(%rbp), %rdi
movq 0x72c5(%rip), %rsi      # 0xbff0
movq 0x7286(%rip), %rdx      # 0xbfb8
callq 0x2390
movq -0x350(%rbp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x60(%rbp)
movl %eax, -0x64(%rbp)
callq 0x21a0
jmp 0x5e49
movq -0x28(%rbp), %rax
movq %rsp, %rcx
movq %rcx, -0x70(%rbp)
leaq 0xf(,%rax,4), %rdx
andq $-0x10, %rdx
movq %rsp, %rcx
subq %rdx, %rcx
movq %rcx, -0x360(%rbp)
movq %rcx, %rsp
movq %rax, -0x78(%rbp)
movq -0x28(%rbp), %rcx
movq %rcx, %rax
incq %rax
movq %rsp, %rdx
movq %rdx, -0x80(%rbp)
leaq 0x13(,%rcx,4), %rdx
andq $-0x10, %rdx
movq %rsp, %rcx
subq %rdx, %rcx
movq %rcx, -0x358(%rbp)
movq %rcx, %rsp
movq %rax, -0x88(%rbp)
movq $0x0, -0x90(%rbp)
movq -0x90(%rbp), %rax
cmpq -0x28(%rbp), %rax
ja 0x4e4a
movq -0x90(%rbp), %rax
movq %rax, %rdx
shrq %rdx
movl %eax, %ecx
andl $0x1, %ecx
orq %rdx, %rcx
cvtsi2ss %rcx, %xmm0
addss %xmm0, %xmm0
cvtsi2ss %rax, %xmm1
movss %xmm1, -0x368(%rbp)
testq %rax, %rax
movss %xmm0, -0x364(%rbp)
js 0x4e13
movss -0x368(%rbp), %xmm0
movss %xmm0, -0x364(%rbp)
movq -0x358(%rbp), %rax
movss -0x364(%rbp), %xmm0
divss -0x4c(%rbp), %xmm0
movq -0x90(%rbp), %rcx
movss %xmm0, (%rax,%rcx,4)
movq -0x90(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x90(%rbp)
jmp 0x4dbe
movss 0x3206(%rip), %xmm0     # 0x8058
divss -0x4c(%rbp), %xmm0
movss %xmm0, -0x94(%rbp)
movq $0x0, -0xa0(%rbp)
movq -0xa0(%rbp), %rax
cmpq -0x28(%rbp), %rax
jae 0x517a
movq -0x358(%rbp), %rax
movq -0x360(%rbp), %rcx
movq -0xa0(%rbp), %rdx
movl $0x0, (%rcx,%rdx,4)
movq -0xa0(%rbp), %rcx
movss (%rax,%rcx,4), %xmm0
movss %xmm0, -0xa4(%rbp)
movq -0xa0(%rbp), %rcx
movss 0x4(%rax,%rcx,4), %xmm0
movss %xmm0, -0xa8(%rbp)
movss -0xa4(%rbp), %xmm0
movss %xmm0, -0x380(%rbp)
movss 0x3184(%rip), %xmm2     # 0x805c
movss %xmm2, -0x37c(%rbp)
movaps %xmm0, %xmm1
subss %xmm2, %xmm1
cvttss2si %xmm1, %rcx
cvttss2si %xmm0, %rax
movq %rax, %rdx
sarq $0x3f, %rdx
andq %rdx, %rcx
orq %rcx, %rax
movq %rax, -0x378(%rbp)
movq %rax, %rdx
shrq %rdx
movl %eax, %ecx
andl $0x1, %ecx
orq %rdx, %rcx
cvtsi2ss %rcx, %xmm0
addss %xmm0, %xmm0
cvtsi2ss %rax, %xmm1
movss %xmm1, -0x370(%rbp)
testq %rax, %rax
movss %xmm0, -0x36c(%rbp)
js 0x4f46
movss -0x370(%rbp), %xmm0
movss %xmm0, -0x36c(%rbp)
movss -0x37c(%rbp), %xmm2
movq -0x360(%rbp), %rax
movq -0x378(%rbp), %rdx
movss -0x380(%rbp), %xmm1
movss -0x36c(%rbp), %xmm0
subss %xmm0, %xmm1
movss 0x30e0(%rip), %xmm0     # 0x8058
subss %xmm1, %xmm0
movq -0x10(%rbp), %rcx
movss (%rcx,%rdx,4), %xmm3
movq -0xa0(%rbp), %rcx
movss (%rax,%rcx,4), %xmm1
mulss %xmm3, %xmm0
addss %xmm1, %xmm0
movss %xmm0, (%rax,%rcx,4)
movss -0xa4(%rbp), %xmm0
movaps %xmm0, %xmm1
subss %xmm2, %xmm1
cvttss2si %xmm1, %rcx
cvttss2si %xmm0, %rax
movq %rax, %rdx
sarq $0x3f, %rdx
andq %rdx, %rcx
orq %rcx, %rax
addq $0x1, %rax
movq %rax, -0xb0(%rbp)
movq -0xb0(%rbp), %rax
movss -0xa8(%rbp), %xmm0
movss 0x3076(%rip), %xmm2     # 0x805c
movaps %xmm0, %xmm1
subss %xmm2, %xmm1
cvttss2si %xmm1, %rdx
cvttss2si %xmm0, %rcx
movq %rcx, %rsi
sarq $0x3f, %rsi
andq %rsi, %rdx
orq %rdx, %rcx
cmpq %rcx, %rax
jae 0x5045
movq -0x360(%rbp), %rax
movq -0x10(%rbp), %rcx
movq -0xb0(%rbp), %rdx
movss (%rcx,%rdx,4), %xmm0
movq -0xa0(%rbp), %rcx
addss (%rax,%rcx,4), %xmm0
movss %xmm0, (%rax,%rcx,4)
movq -0xb0(%rbp), %rax
addq $0x1, %rax
movq %rax, -0xb0(%rbp)
jmp 0x4fcf
movss -0xa8(%rbp), %xmm0
movss 0x3007(%rip), %xmm2     # 0x805c
movaps %xmm0, %xmm1
subss %xmm2, %xmm1
cvttss2si %xmm1, %rcx
cvttss2si %xmm0, %rax
movq %rax, %rdx
sarq $0x3f, %rdx
andq %rdx, %rcx
orq %rcx, %rax
cmpq -0x18(%rbp), %rax
jae 0x513f
movss -0xa8(%rbp), %xmm0
movss %xmm0, -0x394(%rbp)
movss 0x2fc7(%rip), %xmm2     # 0x805c
movaps %xmm0, %xmm1
subss %xmm2, %xmm1
cvttss2si %xmm1, %rcx
cvttss2si %xmm0, %rax
movq %rax, %rdx
sarq $0x3f, %rdx
andq %rdx, %rcx
orq %rcx, %rax
movq %rax, -0x390(%rbp)
movq %rax, %rdx
shrq %rdx
movl %eax, %ecx
andl $0x1, %ecx
orq %rdx, %rcx
cvtsi2ss %rcx, %xmm0
addss %xmm0, %xmm0
cvtsi2ss %rax, %xmm1
movss %xmm1, -0x388(%rbp)
testq %rax, %rax
movss %xmm0, -0x384(%rbp)
js 0x50fb
movss -0x388(%rbp), %xmm0
movss %xmm0, -0x384(%rbp)
movq -0x360(%rbp), %rax
movq -0x390(%rbp), %rdx
movss -0x394(%rbp), %xmm0
movss -0x384(%rbp), %xmm1
subss %xmm1, %xmm0
movq -0x10(%rbp), %rcx
movss (%rcx,%rdx,4), %xmm2
movq -0xa0(%rbp), %rcx
movss (%rax,%rcx,4), %xmm1
mulss %xmm2, %xmm0
addss %xmm1, %xmm0
movss %xmm0, (%rax,%rcx,4)
movq -0x360(%rbp), %rax
movss -0x94(%rbp), %xmm1
movq -0xa0(%rbp), %rcx
movss (%rax,%rcx,4), %xmm0
divss %xmm1, %xmm0
movss %xmm0, (%rax,%rcx,4)
movq -0xa0(%rbp), %rax
addq $0x1, %rax
movq %rax, -0xa0(%rbp)
jmp 0x4e6a
movq -0x80(%rbp), %rax
movq %rax, %rsp
leaq -0x228(%rbp), %rdi
callq 0x22e0
testb $0x1, -0x29(%rbp)
je 0x53c6
movq -0x308(%rbp), %rdi
leaq 0x2f9e(%rip), %rsi      # 0x8143
callq 0x20c0
cmpl $0x0, %eax
jne 0x525c
leaq 0x7176(%rip), %rsi      # 0xc330
leaq -0x228(%rbp), %rdi
callq 0x2200
jmp 0x51c8
movq $0x0, -0x230(%rbp)
movq -0x230(%rbp), %rax
cmpq -0x28(%rbp), %rax
jae 0x5228
leaq 0x71c9(%rip), %rsi      # 0xc3b0
leaq -0x228(%rbp), %rdi
callq 0x2200
jmp 0x51f5
jmp 0x51f7
movq -0x230(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x230(%rbp)
jmp 0x51d3
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x60(%rbp)
movl %eax, -0x64(%rbp)
leaq -0x228(%rbp), %rdi
callq 0x20a0
jmp 0x5e49
leaq 0x7121(%rip), %rsi      # 0xc350
leaq -0x228(%rbp), %rdi
callq 0x2200
movq %rax, -0x3a0(%rbp)
jmp 0x5244
movq -0x3a0(%rbp), %rdi
movl $0xa, %esi
callq 0x22b0
jmp 0x5257
jmp 0x53c4
movq -0x308(%rbp), %rdi
callq 0x2180
cmpq -0x28(%rbp), %rax
jbe 0x52a2
movq -0x308(%rbp), %rsi
leaq -0x228(%rbp), %rdi
callq 0x2200
movq %rax, -0x3a8(%rbp)
jmp 0x528a
movq -0x3a8(%rbp), %rdi
movl $0xa, %esi
callq 0x22b0
jmp 0x529d
jmp 0x53c2
movq -0x308(%rbp), %rdi
movq -0x28(%rbp), %rax
movq %rax, -0x3b0(%rbp)
callq 0x2180
movq %rax, %rcx
movq -0x3b0(%rbp), %rax
subq %rcx, %rax
movq %rax, -0x238(%rbp)
leaq 0x705c(%rip), %rsi      # 0xc330
leaq -0x228(%rbp), %rdi
callq 0x2200
jmp 0x52e2
movq $0x0, -0x240(%rbp)
movq -0x240(%rbp), %rax
movq -0x238(%rbp), %rcx
shrq %rcx
cmpq %rcx, %rax
jae 0x532c
leaq 0x70a6(%rip), %rsi      # 0xc3b0
leaq -0x228(%rbp), %rdi
callq 0x2200
jmp 0x5318
movq -0x240(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x240(%rbp)
jmp 0x52ed
movq -0x308(%rbp), %rsi
leaq -0x228(%rbp), %rdi
callq 0x2200
jmp 0x5341
movq -0x308(%rbp), %rdi
callq 0x2330
addq -0x240(%rbp), %rax
movq %rax, -0x240(%rbp)
movq -0x240(%rbp), %rax
cmpq -0x28(%rbp), %rax
jae 0x5391
leaq 0x7041(%rip), %rsi      # 0xc3b0
leaq -0x228(%rbp), %rdi
callq 0x2200
jmp 0x537d
movq -0x240(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x240(%rbp)
jmp 0x535b
leaq 0x6fb8(%rip), %rsi      # 0xc350
leaq -0x228(%rbp), %rdi
callq 0x2200
movq %rax, -0x3b8(%rbp)
jmp 0x53ad
movq -0x3b8(%rbp), %rdi
movl $0xa, %esi
callq 0x22b0
jmp 0x53c0
jmp 0x53c2
jmp 0x53c4
jmp 0x53c6
movq -0x20(%rbp), %rax
shlq $0x3, %rax
subq $0x1, %rax
movq %rax, -0x248(%rbp)
movq -0x20(%rbp), %rax
subl $0x1, %eax
movl %eax, -0x24c(%rbp)
cmpl $0x0, -0x24c(%rbp)
jl 0x58f6
movl -0x24c(%rbp), %eax
shll $0x3, %eax
movl %eax, -0x250(%rbp)
movl -0x250(%rbp), %eax
addl $0x7, %eax
movl %eax, -0x254(%rbp)
testb $0x1, -0x29(%rbp)
je 0x542e
leaq 0x6fd2(%rip), %rsi      # 0xc3f0
leaq -0x228(%rbp), %rdi
callq 0x2200
jmp 0x542c
jmp 0x542e
movq $0x0, -0x260(%rbp)
movq -0x260(%rbp), %rax
cmpq -0x28(%rbp), %rax
jae 0x55de
movq -0x360(%rbp), %rax
movq -0x260(%rbp), %rcx
leaq (%rax,%rcx,4), %rsi
leaq -0x30(%rbp), %rdi
callq 0x6810
movq %rax, -0x3c0(%rbp)
jmp 0x546e
movq -0x3c0(%rbp), %rsi
leaq -0x34(%rbp), %rdi
callq 0x67d0
movq %rax, -0x3c8(%rbp)
jmp 0x5487
movq -0x3c8(%rbp), %rax
movss (%rax), %xmm0
movss %xmm0, -0x264(%rbp)
movss -0x264(%rbp), %xmm0
movss -0x30(%rbp), %xmm2
subss %xmm2, %xmm0
movss -0x34(%rbp), %xmm1
subss %xmm2, %xmm1
divss %xmm1, %xmm0
movss %xmm0, -0x268(%rbp)
movss -0x268(%rbp), %xmm0
movss %xmm0, -0x3d4(%rbp)
movq -0x248(%rbp), %rax
movq %rax, %rdx
shrq %rdx
movl %eax, %ecx
andl $0x1, %ecx
orq %rdx, %rcx
cvtsi2ss %rcx, %xmm0
addss %xmm0, %xmm0
cvtsi2ss %rax, %xmm1
movss %xmm1, -0x3d0(%rbp)
testq %rax, %rax
movss %xmm0, -0x3cc(%rbp)
js 0x5518
movss -0x3d0(%rbp), %xmm0
movss %xmm0, -0x3cc(%rbp)
movss -0x3d4(%rbp), %xmm0
movss -0x3cc(%rbp), %xmm1
mulss %xmm1, %xmm0
callq 0x6850
movss %xmm0, -0x3d8(%rbp)
jmp 0x553b
movss -0x3d8(%rbp), %xmm0
cvttss2si %xmm0, %eax
movl %eax, -0x26c(%rbp)
movl -0x26c(%rbp), %eax
cmpl -0x250(%rbp), %eax
jge 0x5570
leaq -0x228(%rbp), %rdi
movl $0x20, %esi
callq 0x22b0
jmp 0x556e
jmp 0x55c5
movl -0x26c(%rbp), %eax
cmpl -0x254(%rbp), %eax
jle 0x5595
leaq 0x6d8b(%rip), %rsi      # 0xc310
leaq -0x228(%rbp), %rdi
callq 0x2200
jmp 0x5593
jmp 0x55c3
movl -0x26c(%rbp), %eax
movl -0x250(%rbp), %ecx
subl %ecx, %eax
cltq
shlq $0x5, %rax
leaq 0x6c80(%rip), %rsi      # 0xc230
addq %rax, %rsi
leaq -0x228(%rbp), %rdi
callq 0x2200
jmp 0x55c1
jmp 0x55c3
jmp 0x55c5
jmp 0x55c7
movq -0x260(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x260(%rbp)
jmp 0x5439
testb $0x1, -0x29(%rbp)
je 0x58c2
cmpq $0x1, -0x20(%rbp)
jne 0x5723
leaq 0x6e16(%rip), %rsi      # 0xc410
leaq -0x228(%rbp), %rdi
callq 0x2200
movq %rax, -0x3e0(%rbp)
jmp 0x560f
movq -0x3e0(%rbp), %rdi
leaq 0x2e61(%rip), %rsi      # 0x847e
callq 0x2210
movq %rax, -0x3e8(%rbp)
jmp 0x562b
movq -0x3e8(%rbp), %rdi
leaq 0x1237(%rip), %rsi      # 0x6870
callq 0x20d0
movq %rax, -0x3f0(%rbp)
jmp 0x5647
movl $0xc, %edi
callq 0x68a0
movl %eax, -0x3f4(%rbp)
jmp 0x5659
movq -0x3f0(%rbp), %rdi
movl -0x3f4(%rbp), %eax
movl %eax, -0x270(%rbp)
movl -0x270(%rbp), %esi
callq 0x22a0
movq %rax, -0x400(%rbp)
jmp 0x5680
movq -0x400(%rbp), %rdi
movss -0x30(%rbp), %xmm0
callq 0x21b0
movq %rax, -0x408(%rbp)
jmp 0x569a
movq -0x408(%rbp), %rdi
leaq 0x2ddd(%rip), %rsi      # 0x8485
callq 0x2210
movq %rax, -0x410(%rbp)
jmp 0x56b6
movq -0x410(%rbp), %rdi
leaq 0x11ac(%rip), %rsi      # 0x6870
callq 0x20d0
movq %rax, -0x418(%rbp)
jmp 0x56d2
movl $0xc, %edi
callq 0x68a0
movl %eax, -0x41c(%rbp)
jmp 0x56e4
movq -0x418(%rbp), %rdi
movl -0x41c(%rbp), %eax
movl %eax, -0x274(%rbp)
movl -0x274(%rbp), %esi
callq 0x22a0
movq %rax, -0x428(%rbp)
jmp 0x570b
movq -0x428(%rbp), %rdi
movss -0x34(%rbp), %xmm0
callq 0x21b0
jmp 0x571e
jmp 0x58c0
movl -0x24c(%rbp), %eax
movq -0x20(%rbp), %rcx
subl $0x1, %ecx
cmpl %ecx, %eax
jne 0x5784
leaq 0x6cd5(%rip), %rsi      # 0xc410
leaq -0x228(%rbp), %rdi
callq 0x2200
movq %rax, -0x430(%rbp)
jmp 0x5750
movq -0x430(%rbp), %rdi
leaq 0x2d28(%rip), %rsi      # 0x8486
callq 0x2210
movq %rax, -0x438(%rbp)
jmp 0x576c
movq -0x438(%rbp), %rdi
movss -0x34(%rbp), %xmm0
callq 0x21b0
jmp 0x577f
jmp 0x58be
cmpl $0x0, -0x24c(%rbp)
jne 0x57dd
leaq 0x6c7c(%rip), %rsi      # 0xc410
leaq -0x228(%rbp), %rdi
callq 0x2200
movq %rax, -0x440(%rbp)
jmp 0x57a9
movq -0x440(%rbp), %rdi
leaq 0x2cc7(%rip), %rsi      # 0x847e
callq 0x2210
movq %rax, -0x448(%rbp)
jmp 0x57c5
movq -0x448(%rbp), %rdi
movss -0x30(%rbp), %xmm0
callq 0x21b0
jmp 0x57d8
jmp 0x58bc
leaq 0x6c2c(%rip), %rsi      # 0xc410
leaq -0x228(%rbp), %rdi
callq 0x2200
movq %rax, -0x450(%rbp)
jmp 0x57f9
movq -0x450(%rbp), %rdi
leaq 0x2b20(%rip), %rsi      # 0x8327
callq 0x2210
movq %rax, -0x458(%rbp)
jmp 0x5815
movl -0x24c(%rbp), %ecx
movl %ecx, %eax
leal 0x4(,%rax,8), %eax
cvtsi2ss %rax, %xmm0
movss -0x34(%rbp), %xmm1
movss -0x30(%rbp), %xmm2
movss %xmm2, -0x468(%rbp)
subss %xmm2, %xmm1
mulss %xmm1, %xmm0
movss %xmm0, -0x464(%rbp)
movq -0x20(%rbp), %rax
shlq $0x3, %rax
cvtsi2ss %rax, %xmm0
movss %xmm0, -0x460(%rbp)
movq %rax, %rcx
shrq %rcx
cvtsi2ss %rcx, %xmm0
addss %xmm0, %xmm0
testq %rax, %rax
movss %xmm0, -0x45c(%rbp)
js 0x588c
movss -0x460(%rbp), %xmm0
movss %xmm0, -0x45c(%rbp)
movq -0x458(%rbp), %rdi
movss -0x468(%rbp), %xmm1
movss -0x464(%rbp), %xmm0
movss -0x45c(%rbp), %xmm2
divss %xmm2, %xmm0
addss %xmm1, %xmm0
callq 0x21b0
jmp 0x58ba
jmp 0x58bc
jmp 0x58be
jmp 0x58c0
jmp 0x58c2
cmpl $0x0, -0x24c(%rbp)
jle 0x58e0
leaq -0x228(%rbp), %rdi
movl $0xa, %esi
callq 0x22b0
jmp 0x58de
jmp 0x58e0
jmp 0x58e2
movl -0x24c(%rbp), %eax
addl $-0x1, %eax
movl %eax, -0x24c(%rbp)
jmp 0x53e6
testb $0x1, -0x29(%rbp)
je 0x5e15
movq $0x2, -0x280(%rbp)
movq -0x18(%rbp), %rax
incq %rax
movq %rax, %xmm0
movaps 0x26f2(%rip), %xmm1     # 0x8010
punpckldq %xmm1, %xmm0    # xmm0 = xmm0[0],xmm1[0],xmm0[1],xmm1[1]
movapd 0x26f6(%rip), %xmm1     # 0x8020
subpd %xmm1, %xmm0
movaps %xmm0, %xmm1
unpckhpd %xmm0, %xmm0            # xmm0 = xmm0[1,1]
addsd %xmm1, %xmm0
callq 0x2150
callq 0x2050
movsd 0x26ed(%rip), %xmm1     # 0x8038
addsd %xmm1, %xmm0
movaps %xmm0, %xmm1
cvttsd2si %xmm1, %rax
movq %rax, %rdx
sarq $0x3f, %rdx
movsd 0x26ca(%rip), %xmm1     # 0x8030
subsd %xmm1, %xmm0
cvttsd2si %xmm0, %rcx
andq %rdx, %rcx
orq %rcx, %rax
movq %rax, -0x288(%rbp)
movq -0x28(%rbp), %rax
movq -0x288(%rbp), %rcx
xorl %edx, %edx
divq %rcx
incq %rax
movq %rax, -0x290(%rbp)
movq -0x290(%rbp), %rax
movq %rsp, %rcx
movq %rcx, -0x298(%rbp)
leaq 0xf(,%rax,8), %rdx
andq $-0x10, %rdx
movq %rsp, %rcx
subq %rdx, %rcx
movq %rcx, -0x478(%rbp)
movq %rcx, %rsp
movq %rax, -0x2a0(%rbp)
movq -0x290(%rbp), %rax
leaq 0xf(,%rax,8), %rdx
andq $-0x10, %rdx
movq %rsp, %rcx
subq %rdx, %rcx
movq %rcx, -0x470(%rbp)
movq %rcx, %rsp
movq %rax, -0x2a8(%rbp)
movq $0x0, -0x2b0(%rbp)
movq -0x2b0(%rbp), %rax
movq -0x290(%rbp), %rcx
subq $0x1, %rcx
cmpq %rcx, %rax
jae 0x5a77
movq -0x478(%rbp), %rax
movq -0x2b0(%rbp), %rdx
imulq -0x288(%rbp), %rdx
movq -0x2b0(%rbp), %rcx
movq %rdx, (%rax,%rcx,8)
movq -0x2b0(%rbp), %rax
imulq -0x18(%rbp), %rax
xorl %ecx, %ecx
movl %ecx, %edx
divq -0x290(%rbp)
movq %rax, %rdx
movq -0x470(%rbp), %rax
movq -0x2b0(%rbp), %rcx
movq %rdx, (%rax,%rcx,8)
movq -0x2b0(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x2b0(%rbp)
jmp 0x59ff
movq -0x470(%rbp), %rax
movq -0x478(%rbp), %rcx
movq -0x28(%rbp), %rsi
decq %rsi
movq -0x290(%rbp), %rdx
movq %rsi, -0x8(%rcx,%rdx,8)
movq -0x18(%rbp), %rdx
movq -0x290(%rbp), %rcx
movq %rdx, -0x8(%rax,%rcx,8)
movq $0x0, -0x2b8(%rbp)
leaq -0x228(%rbp), %rdi
movl $0xa, %esi
callq 0x22b0
jmp 0x5ac6
leaq 0x68a3(%rip), %rsi      # 0xc370
leaq -0x228(%rbp), %rdi
callq 0x2200
jmp 0x5adb
movq $0x0, -0x2c0(%rbp)
movq -0x2c0(%rbp), %rax
cmpq -0x28(%rbp), %rax
jae 0x5b64
movq -0x478(%rbp), %rcx
movq -0x2c0(%rbp), %rax
movq -0x2b8(%rbp), %rdx
cmpq (%rcx,%rdx,8), %rax
jne 0x5b37
leaq 0x68bb(%rip), %rsi      # 0xc3d0
leaq -0x228(%rbp), %rdi
callq 0x2200
jmp 0x5b23
movq -0x2b8(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x2b8(%rbp)
jmp 0x5b4e
leaq 0x6872(%rip), %rsi      # 0xc3b0
leaq -0x228(%rbp), %rdi
callq 0x2200
jmp 0x5b4c
jmp 0x5b4e
jmp 0x5b50
movq -0x2c0(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x2c0(%rbp)
jmp 0x5ae6
leaq 0x6825(%rip), %rsi      # 0xc390
leaq -0x228(%rbp), %rdi
callq 0x2200
jmp 0x5b79
leaq 0x290d(%rip), %rsi      # 0x848d
leaq -0x228(%rbp), %rdi
callq 0x2210
movq %rax, -0x480(%rbp)
jmp 0x5b95
movq -0x480(%rbp), %rdi
movq -0x470(%rbp), %rax
movq (%rax), %rsi
callq 0x2090
jmp 0x5bad
movq $0x1, -0x2c8(%rbp)
movq $0x1, -0x2d0(%rbp)
movq -0x2d0(%rbp), %rax
movq -0x290(%rbp), %rcx
subq $0x1, %rcx
cmpq %rcx, %rax
jae 0x5d53
movq -0x470(%rbp), %rax
movq -0x2d0(%rbp), %rcx
movq (%rax,%rcx,8), %rdi
callq 0x2d30
movq %rax, %rcx
movq -0x470(%rbp), %rax
movq %rcx, -0x2d8(%rbp)
movq -0x2d8(%rbp), %rdx
movq -0x2c8(%rbp), %rcx
addq %rdx, %rcx
movq %rcx, -0x2c8(%rbp)
movq -0x2d8(%rbp), %rcx
movq %rcx, %rdx
shrq %rdx
subq %rdx, %rcx
movq %rcx, -0x2e0(%rbp)
movq -0x2d0(%rbp), %rcx
movq -0x8(%rax,%rcx,8), %rdi
callq 0x2d30
movq %rax, -0x2d8(%rbp)
movq -0x2d8(%rbp), %rax
shrq %rax
movq %rax, -0x2e8(%rbp)
movq -0x288(%rbp), %rax
movq -0x2e0(%rbp), %rcx
subq %rcx, %rax
movq -0x2e8(%rbp), %rcx
subq %rcx, %rax
movq %rax, -0x2f0(%rbp)
movl -0x2f0(%rbp), %edi
callq 0x68a0
movl %eax, -0x484(%rbp)
jmp 0x5c93
movl -0x484(%rbp), %eax
movl %eax, -0x2f4(%rbp)
movl -0x2f4(%rbp), %esi
leaq -0x228(%rbp), %rdi
callq 0x22a0
movq %rax, -0x490(%rbp)
jmp 0x5cba
movl $0x20, %edi
callq 0x68c0
movb %al, -0x491(%rbp)
jmp 0x5ccc
movq -0x490(%rbp), %rdi
movb -0x491(%rbp), %al
movb %al, -0x2f5(%rbp)
movzbl -0x2f5(%rbp), %esi
callq 0x2360
movq %rax, -0x4a0(%rbp)
jmp 0x5cf4
movq -0x4a0(%rbp), %rdi
movl $0x20, %esi
callq 0x22b0
jmp 0x5d07
movq -0x470(%rbp), %rax
movq -0x2d0(%rbp), %rcx
movq (%rax,%rcx,8), %rsi
leaq -0x228(%rbp), %rdi
callq 0x2090
jmp 0x5d27
movq -0x2f0(%rbp), %rax
addq -0x2c8(%rbp), %rax
movq %rax, -0x2c8(%rbp)
movq -0x2d0(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x2d0(%rbp)
jmp 0x5bc3
movq -0x478(%rbp), %rax
movq -0x290(%rbp), %rcx
movl -0x8(%rax,%rcx,8), %eax
movl -0x2c8(%rbp), %ecx
subl %ecx, %eax
movl %eax, -0x4a8(%rbp)
movq -0x18(%rbp), %rdi
callq 0x2d30
movl -0x4a8(%rbp), %edi
subl %eax, %edi
addl $0x2, %edi
callq 0x68a0
movl %eax, -0x4a4(%rbp)
jmp 0x5d94
movl -0x4a4(%rbp), %eax
movl %eax, -0x2fc(%rbp)
movl -0x2fc(%rbp), %esi
leaq -0x228(%rbp), %rdi
callq 0x22a0
movq %rax, -0x4b0(%rbp)
jmp 0x5dbb
movq -0x4b0(%rbp), %rdi
movl $0x20, %esi
callq 0x22b0
jmp 0x5dce
movq -0x470(%rbp), %rax
movq -0x290(%rbp), %rcx
movq -0x8(%rax,%rcx,8), %rsi
leaq -0x228(%rbp), %rdi
callq 0x2090
movq %rax, -0x4b8(%rbp)
jmp 0x5df6
movq -0x4b8(%rbp), %rdi
movq 0x619c(%rip), %rsi      # 0xbfa0
callq 0x2250
jmp 0x5e0b
movq -0x298(%rbp), %rax
movq %rax, %rsp
movq -0x318(%rbp), %rdi
leaq -0x228(%rbp), %rsi
callq 0x2240
jmp 0x5e2a
leaq -0x228(%rbp), %rdi
callq 0x20a0
movq -0x310(%rbp), %rax
movq -0x70(%rbp), %rcx
movq %rcx, %rsp
movq %rbp, %rsp
popq %rbp
retq
movq -0x60(%rbp), %rdi
callq 0x23a0
nopw %cs:(%rax,%rax)
nopl (%rax)