#include <metal_stdlib>
using namespace metal;

struct VertexOutput {
  float4 vtxFragColor;
  float4 Position;
};

struct VertexInput {
  float4 cur_position;
  float4 color;
};

struct Uniforms {
  float4x4 modelViewProjectionMatrix;
};

struct tint_module_vars_struct {
  const constant Uniforms* uniforms;
};

struct vtx_main_outputs {
  float4 VertexOutput_vtxFragColor [[user(locn0)]];
  float4 VertexOutput_Position [[position]];
};

struct vtx_main_inputs {
  float4 VertexInput_cur_position [[attribute(0)]];
  float4 VertexInput_color [[attribute(1)]];
};

struct frag_main_outputs {
  float4 tint_symbol [[color(0)]];
};

struct frag_main_inputs {
  float4 fragColor [[user(locn0)]];
};

VertexOutput vtx_main_inner(VertexInput input, tint_module_vars_struct tint_module_vars) {
  VertexOutput output = {};
  output.Position = ((*tint_module_vars.uniforms).modelViewProjectionMatrix * input.cur_position);
  output.vtxFragColor = input.color;
  return output;
}

float4 frag_main_inner(float4 fragColor) {
  return fragColor;
}

vertex vtx_main_outputs vtx_main(vtx_main_inputs inputs [[stage_in]], const constant Uniforms* uniforms [[buffer(0)]]) {
  tint_module_vars_struct const tint_module_vars = tint_module_vars_struct{.uniforms=uniforms};
  VertexOutput const v = vtx_main_inner(VertexInput{.cur_position=inputs.VertexInput_cur_position, .color=inputs.VertexInput_color}, tint_module_vars);
  return vtx_main_outputs{.VertexOutput_vtxFragColor=v.vtxFragColor, .VertexOutput_Position=v.Position};
}

fragment frag_main_outputs frag_main(frag_main_inputs inputs [[stage_in]]) {
  return frag_main_outputs{.tint_symbol=frag_main_inner(inputs.fragColor)};
}
