#include <metal_stdlib>

using namespace metal;

template<typename T, size_t N>
struct tint_array {
    const constant T& operator[](size_t i) const constant { return elements[i]; }
    device T& operator[](size_t i) device { return elements[i]; }
    const device T& operator[](size_t i) const device { return elements[i]; }
    thread T& operator[](size_t i) thread { return elements[i]; }
    const thread T& operator[](size_t i) const thread { return elements[i]; }
    threadgroup T& operator[](size_t i) threadgroup { return elements[i]; }
    const threadgroup T& operator[](size_t i) const threadgroup { return elements[i]; }
    T elements[N];
};

struct tint_private_vars_struct {
  float4 sk_FragColor;
  bool sk_Clockwise;
  float4 vcolor_S0;
};

struct tint_packed_vec3_f32_array_element {
  /* 0x0000 */ packed_float3 elements;
  /* 0x000c */ tint_array<int8_t, 4> tint_pad;
};

struct UniformBuffer_tint_packed_vec3 {
  /* 0x0000 */ tint_array<int8_t, 16> tint_pad_1;
  /* 0x0010 */ float unknownInput_S1_c0;
  /* 0x0014 */ tint_array<int8_t, 12> tint_pad_2;
  /* 0x0020 */ float4 ucolorRed_S1_c0;
  /* 0x0030 */ float4 ucolorGreen_S1_c0;
  /* 0x0040 */ tint_array<tint_packed_vec3_f32_array_element, 3> umatrix_S1;
};

int tint_ftoi(float v) {
  return select(2147483647, select(int(v), (-2147483647 - 1), (v < -2147483648.0f)), (v < 2147483520.0f));
}

struct UniformBuffer {
  float unknownInput_S1_c0;
  float4 ucolorRed_S1_c0;
  float4 ucolorGreen_S1_c0;
  float3x3 umatrix_S1;
};

int4 tint_div(int4 lhs, int4 rhs) {
  return (lhs / select(rhs, int4(1), ((rhs == int4(0)) | ((lhs == int4((-2147483647 - 1))) & (rhs == int4(-1))))));
}

bool test_int_S1_c0_b(const constant UniformBuffer_tint_packed_vec3* const tint_symbol_5) {
  int unknown = 0;
  bool ok = false;
  int4 val = 0;
  bool x_40 = false;
  bool x_41 = false;
  bool x_54 = false;
  bool x_55 = false;
  bool x_65 = false;
  bool x_66 = false;
  float const x_26 = (*(tint_symbol_5)).unknownInput_S1_c0;
  int const x_27 = tint_ftoi(x_26);
  unknown = x_27;
  ok = true;
  x_41 = false;
  if (true) {
    x_40 = all((tint_div(int4(0), int4(x_27, x_27, x_27, x_27)) == int4(0)));
    x_41 = x_40;
  }
  ok = x_41;
  int4 const x_44 = int4(x_27, x_27, x_27, x_27);
  val = x_44;
  int4 const x_47 = as_type<int4>((as_type<uint4>(x_44) + as_type<uint4>(int4(1))));
  val = x_47;
  int4 const x_48 = as_type<int4>((as_type<uint4>(x_47) - as_type<uint4>(int4(1))));
  val = x_48;
  int4 const x_49 = as_type<int4>((as_type<uint4>(x_48) + as_type<uint4>(int4(1))));
  val = x_49;
  int4 const x_50 = as_type<int4>((as_type<uint4>(x_49) - as_type<uint4>(int4(1))));
  val = x_50;
  x_55 = false;
  if (x_41) {
    x_54 = all((x_50 == x_44));
    x_55 = x_54;
  }
  ok = x_55;
  int4 const x_58 = as_type<int4>((as_type<uint4>(x_50) * as_type<uint4>(int4(2))));
  val = x_58;
  int4 const x_59 = tint_div(x_58, int4(2));
  val = x_59;
  int4 const x_60 = as_type<int4>((as_type<uint4>(x_59) * as_type<uint4>(int4(2))));
  val = x_60;
  int4 const x_61 = tint_div(x_60, int4(2));
  val = x_61;
  x_66 = false;
  if (x_55) {
    x_65 = all((x_61 == x_44));
    x_66 = x_65;
  }
  ok = x_66;
  return x_66;
}

void main_1(thread tint_private_vars_struct* const tint_private_vars, const constant UniformBuffer_tint_packed_vec3* const tint_symbol_6) {
  float4 outputColor_S0 = 0.0f;
  float4 output_S1 = 0.0f;
  float x_8_unknown = 0.0f;
  bool x_9_ok = false;
  float4 x_10_val = 0.0f;
  float4 x_116 = 0.0f;
  bool x_86 = false;
  bool x_87 = false;
  bool x_99 = false;
  bool x_100 = false;
  bool x_110 = false;
  bool x_111 = false;
  bool x_114 = false;
  bool x_115 = false;
  float4 const x_72 = (*(tint_private_vars)).vcolor_S0;
  outputColor_S0 = x_72;
  float const x_77 = (*(tint_symbol_6)).unknownInput_S1_c0;
  x_8_unknown = x_77;
  x_9_ok = true;
  x_87 = false;
  if (true) {
    x_86 = all(((float4(0.0f) / float4(x_77, x_77, x_77, x_77)) == float4(0.0f)));
    x_87 = x_86;
  }
  x_9_ok = x_87;
  float4 const x_89 = float4(x_77, x_77, x_77, x_77);
  x_10_val = x_89;
  float4 const x_92 = (x_89 + float4(1.0f));
  x_10_val = x_92;
  float4 const x_93 = (x_92 - float4(1.0f));
  x_10_val = x_93;
  float4 const x_94 = (x_93 + float4(1.0f));
  x_10_val = x_94;
  float4 const x_95 = (x_94 - float4(1.0f));
  x_10_val = x_95;
  x_100 = false;
  if (x_87) {
    x_99 = all((x_95 == x_89));
    x_100 = x_99;
  }
  x_9_ok = x_100;
  float4 const x_103 = (x_95 * float4(2.0f));
  x_10_val = x_103;
  float4 const x_104 = (x_103 / float4(2.0f));
  x_10_val = x_104;
  float4 const x_105 = (x_104 * float4(2.0f));
  x_10_val = x_105;
  float4 const x_106 = (x_105 / float4(2.0f));
  x_10_val = x_106;
  x_111 = false;
  if (x_100) {
    x_110 = all((x_106 == x_89));
    x_111 = x_110;
  }
  x_9_ok = x_111;
  x_115 = false;
  if (x_111) {
    x_114 = test_int_S1_c0_b(tint_symbol_6);
    x_115 = x_114;
  }
  if (x_115) {
    float4 const x_122 = (*(tint_symbol_6)).ucolorGreen_S1_c0;
    x_116 = x_122;
  } else {
    float4 const x_124 = (*(tint_symbol_6)).ucolorRed_S1_c0;
    x_116 = x_124;
  }
  float4 const x_125 = x_116;
  output_S1 = x_125;
  (*(tint_private_vars)).sk_FragColor = x_125;
  return;
}

struct main_out {
  float4 sk_FragColor_1;
};

struct tint_symbol_2 {
  float4 vcolor_S0_param [[user(locn0)]];
};

struct tint_symbol_3 {
  float4 sk_FragColor_1 [[color(0)]];
};

main_out tint_symbol_inner(bool sk_Clockwise_param, float4 vcolor_S0_param, thread tint_private_vars_struct* const tint_private_vars, const constant UniformBuffer_tint_packed_vec3* const tint_symbol_7) {
  (*(tint_private_vars)).sk_Clockwise = sk_Clockwise_param;
  (*(tint_private_vars)).vcolor_S0 = vcolor_S0_param;
  main_1(tint_private_vars, tint_symbol_7);
  main_out const tint_symbol_4 = {.sk_FragColor_1=(*(tint_private_vars)).sk_FragColor};
  return tint_symbol_4;
}

fragment tint_symbol_3 tint_symbol(const constant UniformBuffer_tint_packed_vec3* tint_symbol_8 [[buffer(0)]], bool sk_Clockwise_param [[front_facing]], tint_symbol_2 tint_symbol_1 [[stage_in]]) {
  thread tint_private_vars_struct tint_private_vars = {};
  main_out const inner_result = tint_symbol_inner(sk_Clockwise_param, tint_symbol_1.vcolor_S0_param, &(tint_private_vars), tint_symbol_8);
  tint_symbol_3 wrapper_result = {};
  wrapper_result.sk_FragColor_1 = inner_result.sk_FragColor_1;
  return wrapper_result;
}

