#include <metal_stdlib>

using namespace metal;
struct tint_array_wrapper {
  float arr[10];
};
struct main_out {
  float4 x_GLF_color_1;
};
struct tint_symbol_1 {
  float4 x_GLF_color_1 [[color(0)]];
};

void main_1(thread float4* const tint_symbol_4, thread float4* const tint_symbol_5) {
  tint_array_wrapper data = {};
  int i = 0;
  tint_array_wrapper const tint_symbol_2 = {.arr={0.100000001f, 0.200000003f, 0.300000012f, 0.400000006f, 0.5f, 0.600000024f, 0.699999988f, 0.800000012f, 0.899999976f, 1.0f}};
  data = tint_symbol_2;
  i = 0;
  while (true) {
    int const x_7 = i;
    if ((x_7 < 10)) {
    } else {
      break;
    }
    float const x_50 = (*(tint_symbol_4)).x;
    if ((x_50 < 0.0f)) {
      discard_fragment();
    }
    int const x_8 = i;
    float const x_55 = data.arr[x_8];
    data.arr[0] = x_55;
    {
      int const x_9 = i;
      i = as_type<int>((as_type<uint>(x_9) + as_type<uint>(1)));
    }
  }
  float const x_58 = data.arr[0];
  *(tint_symbol_5) = float4(x_58, 0.0f, 0.0f, 1.0f);
  return;
}

main_out tint_symbol_inner(float4 gl_FragCoord_param, thread float4* const tint_symbol_6, thread float4* const tint_symbol_7) {
  *(tint_symbol_6) = gl_FragCoord_param;
  main_1(tint_symbol_6, tint_symbol_7);
  main_out const tint_symbol_3 = {.x_GLF_color_1=*(tint_symbol_7)};
  return tint_symbol_3;
}

fragment tint_symbol_1 tint_symbol(float4 gl_FragCoord_param [[position]]) {
  thread float4 tint_symbol_8 = 0.0f;
  thread float4 tint_symbol_9 = 0.0f;
  main_out const inner_result = tint_symbol_inner(gl_FragCoord_param, &(tint_symbol_8), &(tint_symbol_9));
  tint_symbol_1 wrapper_result = {};
  wrapper_result.x_GLF_color_1 = inner_result.x_GLF_color_1;
  return wrapper_result;
}

