<?xml version="1.0" encoding="ISO-8859-1" standalone="yes"?>

<glsl_hacker>

  <window name="win3d01" title="" width="1000" height="400"
          gl_version_major="2" gl_version_minor="1" />
  
  
	<script name="init_scene" run_mode="INIT" >
		<raw_data><![CDATA[	
    
--local demo_dir = gh_utils.get_demo_dir()
    
    
winW, winH = gh_window.getsize(0)




app_version = {major=0, minor=0, patch=0, build=0}
app_version.major, app_version.minor, app_version.patch, app_version.build = gh_utils.get_app_version()
geexlab_version = string.format("%d.%d.%d.%d", app_version.major, app_version.minor, app_version.patch, app_version.build)

is_x64 = gh_utils.is_64bit()
if (is_x64 == 1) then
  geexlab_version = geexlab_version .. " (64-bit)"
else  
  geexlab_version = geexlab_version .. " (32-bit)"
end


local aspect = 1.333
if (winH > 0) then
  aspect = winW / winH
end  
camera = gh_camera.create_persp(50, aspect, 1.0, 1000.0)
gh_camera.set_viewport(camera, 0, 0, winW, winH)
gh_camera.setpos(camera, 0, 0, 30)
gh_camera.setlookat(camera, 0, 0, 0, 1)
gh_camera.setupvec(camera, 0, 1, 0, 0)




camera_ortho = gh_camera.create_ortho(-winW/2, winW/2, -winH/2, winH/2, 1.0, 10.0)
gh_camera.set_viewport(camera_ortho, 0, 0, winW, winH)
gh_camera.set_position(camera_ortho, 0, 0, 4)




show_nanovg = true
if (gh_utils.get_platform() == 2) then -- macOS
  -- On macOS nanovg require OpenGL 3.2+. This demo is OpenGL 2.1.
  -- I should add the OpenGL 3.2 support to this demo (shaders) but I'm too lazy.
  show_nanovg = false
end

if (gh_utils.get_platform() == 4) then -- RPi
  -- There are some issues with nanovg on RPi+GL2.1
  show_nanovg = false
end




----------------------------------------------------------------------
----------------------------------------------------------------------
-- OpenGL 2.1 shaders
----------------------------------------------------------------------
----------------------------------------------------------------------

-- vertex color program ------------------------------
--
local vertex_color_vs_gl2=[[
void main() 
{ 
  gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex; 
  gl_FrontColor = gl_Color; 
}
]]
  

local vertex_color_ps_gl2=[[
void main (void) 
{ 
  gl_FragColor = gl_Color; 
}
]]
  


-- font program ------------------------------
--
local font_vs_gl2=[[
uniform mat4 gxl3d_ViewProjectionMatrix; 
uniform mat4 gxl3d_ModelMatrix;
uniform vec4 gxl3d_Viewport; 
varying vec4 Vertex_UV;
varying vec4 Vertex_Color; 
void main()
{
  vec4 P = gl_Vertex; 
  vec4 Pw = gxl3d_ModelMatrix * P;
  Pw.x = Pw.x - gxl3d_Viewport.z/2.0;
  Pw.y = Pw.y + gxl3d_Viewport.w/2.0;
  gl_Position = gxl3d_ViewProjectionMatrix * Pw; 
  Vertex_UV = gl_MultiTexCoord0; 
  Vertex_Color = gl_Color; 
}
]]
  

local font_ps_gl2=[[
uniform sampler2D tex0;
varying vec4 Vertex_UV;
varying vec4 Vertex_Color;
void main (void)
{ 
  vec2 uv = Vertex_UV.xy; 
  float t = texture2D(tex0,uv).r;
  gl_FragColor = vec4(t * Vertex_Color.rgb, 1.0);
}
]]
  

-- FX program ------------------------------
--
local kool_effect_vs_gl2=[[
void main()
{	
  gl_FrontColor = gl_Color; 
	gl_TexCoord[0] = gl_MultiTexCoord0; 
  gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;	
}
]]
  

local kool_effect_ps_gl2=[[
uniform float time;
uniform vec2 resolution;
uniform vec2 mouse;
void main(void)
{ 
  vec2 uv = 2.0 * (gl_FragCoord.xy / resolution.xy) - 1.0; 
  uv *= 2.0;
  float col=0.0; 
  float i=0.73; 
  vec2 spec = vec2(0.1, 0.1);
  uv.x += -((mouse.x/resolution.x*4.0)-2.0) + sin(i*20.0 + spec.x*5.0*time*6.0 + uv.y*1.5) * spec.y; 
  col += abs(0.066/uv.x) * spec.y;
  gl_FragColor = vec4(col+gl_Color.x, col+gl_Color.y, col+gl_Color.z, 1.0); 
}
]]




----------------------------------------------------------------------
----------------------------------------------------------------------
-- OpenGL ES 2.0 shaders
----------------------------------------------------------------------
----------------------------------------------------------------------

-- Vertex color program ------------------------------
--
local vertex_color_vs_gles2=[[
attribute vec4 gxl3d_Position;
attribute vec4 gxl3d_Color; \
uniform mat4 gxl3d_ModelViewProjectionMatrix; \
varying vec4 Vertex_Color; 
void main() 
{ 
  gl_Position = gxl3d_ModelViewProjectionMatrix * gxl3d_Position;
  Vertex_Color = gxl3d_Color;
}
]]
  

local vertex_color_ps_gles2=[[
varying highp vec4 Vertex_Color;
void main() 
{ 
  gl_FragColor = Vertex_Color;
}
]]
  



-- Font program ------------------------------
--
local font_vs_gles2=[[
attribute vec4 gxl3d_Position;
attribute vec4 gxl3d_TexCoord0;
attribute vec4 gxl3d_Color;
uniform mat4 gxl3d_ViewProjectionMatrix; 
uniform mat4 gxl3d_ModelMatrix;
uniform vec4 gxl3d_Viewport;
varying vec4 Vertex_Color; 
varying vec4 Vertex_UV;
void main() 
{ \
  vec4 P = gxl3d_Position;
  vec4 Pw = gxl3d_ModelMatrix * P;
  Pw.x = Pw.x - gxl3d_Viewport.z/2.0;
  Pw.y = Pw.y + gxl3d_Viewport.w/2.0;
  gl_Position = gxl3d_ViewProjectionMatrix * Pw;
  Vertex_Color = gxl3d_Color;
  Vertex_UV = gxl3d_TexCoord0;
}
]]
  

local font_ps_gles2=[[
uniform sampler2D tex0;
varying highp vec4 Vertex_UV; 
varying highp vec4 Vertex_Color;
void main() 
{ 
  highp vec2 uv = Vertex_UV.xy;
  highp float t = texture2D(tex0,uv).r;
  gl_FragColor = vec4(t * Vertex_Color.rgb, 1.0);
}
]]
  


-- FX program ------------------------------
--
local kool_effect_vs_gles2=[[
attribute vec4 gxl3d_Position;
attribute vec4 gxl3d_TexCoord0;
attribute vec4 gxl3d_Color;
uniform mat4 gxl3d_ModelViewProjectionMatrix; 
varying vec4 Vertex_Color; 
void main() 
{
  Vertex_Color = gxl3d_Color;
  gl_Position = gxl3d_ModelViewProjectionMatrix * gxl3d_Position; 
}
]]
  

local kool_effect_ps_gles2=[[
uniform sampler2D tex0; 
varying highp vec4 Vertex_Color;
uniform highp float time;
uniform highp vec2 resolution;
uniform highp vec2 mouse;
void main()
{
  highp vec2 uv = 2.0 * (gl_FragCoord.xy / resolution.xy) - 1.0;
  uv *= 2.0;
  highp float col=0.0;
  highp float i=0.73;
  highp vec2 spec = vec2(0.1, 0.1);
  uv.x += -((mouse.x/resolution.x*4.0)-2.0) + sin(i*20.0 + spec.x*5.0*time*6.0 + uv.y*1.5) * spec.y;
  col += abs(0.066/uv.x) * spec.y;
  gl_FragColor = vec4(col+Vertex_Color.x, col+Vertex_Color.y, col+Vertex_Color.z, 1.0);
}
]]











is_opengl_es = gh_renderer.is_opengl_es()

if (is_opengl_es == 1) then
    vertex_color_prog = gh_gpu_program.create_v2("vertex_color_prog",vertex_color_vs_gles2, vertex_color_ps_gles2)
    font_prog = gh_gpu_program.create_v2("font_prog",font_vs_gles2, font_ps_gles2)
    kool_effect_prog = gh_gpu_program.create_v2("kool_effect_prog",kool_effect_vs_gles2, kool_effect_ps_gles2)

else
  --vertex_color_prog = gh_node.getid("vertex_color_prog")
  --font_prog = gh_node.getid("font_prog")
  --kool_effect_prog = gh_node.getid("kool_effect_prog")

  local vs = "#version 120\n" .. vertex_color_vs_gl2
  local ps = "#version 120\n" .. vertex_color_ps_gl2
  vertex_color_prog = gh_gpu_program.create_v2("vertex_color_prog",vs, ps)
  
  vs = "#version 120\n" .. font_vs_gl2
  ps = "#version 120\n" .. font_ps_gl2
  font_prog = gh_gpu_program.create_v2("font_prog",vs, ps)
  
  vs = "#version 120\n" .. kool_effect_vs_gl2
  ps = "#version 120\n" .. kool_effect_ps_gl2
  kool_effect_prog = gh_gpu_program.create_v2("kool_effect_prog",vs, ps)
end




  
  
  



quad = gh_mesh.create_quad(winW, winH)
--gh_mesh.set_vertex_color(quad, 0, 0.2, 0.2, 0.25, 1) --bottom-left
--gh_mesh.set_vertex_color(quad, 1, 0.10, 0.10, 0.10, 1) -- top-left
--gh_mesh.set_vertex_color(quad, 2, 0.50, 0.50, 0.50, 1) --top-right
--gh_mesh.set_vertex_color(quad, 3, 0.50, 0.50, 0.50, 1) --bottom-right

gh_mesh.set_vertex_color(quad, 0, 0.2, 0.2, 0.25, 1) --bottom-left
gh_mesh.set_vertex_color(quad, 1, 0.10, 0.10, 0.10, 1) -- top-left
gh_mesh.set_vertex_color(quad, 2, 0.250, 0.60, 0.70, 1) --top-right
gh_mesh.set_vertex_color(quad, 3, 0.250, 0.60, 0.70, 1) --bottom-right




quad_band_width = 12

quad2 = gh_mesh.create_quad(winW, quad_band_width)
gh_mesh.set_vertex_color(quad2, 0, 0.5, 0.2, 0.0, 1) --bottom-left
gh_mesh.set_vertex_color(quad2, 1, 0.5, 0.2, 0.0, 1) -- top-left
gh_mesh.set_vertex_color(quad2, 2, 0.5, 0.2, 0.0, 1) --top-right
gh_mesh.set_vertex_color(quad2, 3, 0.5, 0.2, 0.0, 1) --bottom-right

quad3 = gh_mesh.create_quad(quad_band_width, winH)
gh_mesh.set_vertex_color(quad3, 0, 0.5, 0.2, 0.0, 1) --bottom-left
gh_mesh.set_vertex_color(quad3, 1, 0.5, 0.2, 0.0, 1) -- top-left
gh_mesh.set_vertex_color(quad3, 2, 0.5, 0.2, 0.0, 1) --top-right
gh_mesh.set_vertex_color(quad3, 3, 0.5, 0.2, 0.0, 1) --bottom-right



--mesh = gh_mesh.create_trefoil_knot(10, 100)
--gh_object.set_position(mesh, 0, 0, 0)
--gh_object.set_scale(mesh, 10, 10, 10)
--gh_mesh.set_vertices_color(mesh, 1.0, 1.0, 0.0, 1)







-- Font loading ------------------------
--

if (is_opengl_es == 1) then

  font_d = gh_font.create_v2("roboto_medium", 22, 512, 512)
  gh_font.build_texture(font_d, 0)
  tex_font_d = gh_font.get_texture(font_d)
  --print("font_d: " .. font_d .. " - tex_font_d: " .. tex_font_d)

else

  font_d = gh_font.create_v2("roboto_medium", 20, 512, 512)
  gh_font.build_texture(font_d, 0)
  tex_font_d = gh_font.get_texture(font_d)

  font_s = gh_font.create_v2("roboto_medium", 20, 512, 512)
  gh_font.build_texture(font_s, 0)
  tex_font_s = gh_font.get_texture(font_s)

  font_h1 = gh_font.create_v2("hacked", 70, 512, 512)
  gh_font.build_texture(font_h1, 0)
  tex_font_h1 = gh_font.get_texture(font_h1)

  font_h3 = gh_font.create_v2("roboto_medium_italic", 20, 512, 512)
  gh_font.build_texture(font_h3, 0)
  tex_font_h3 = gh_font.get_texture(font_h3)

  font_s1 = gh_font.create_v2("hacked", 30, 512, 512)
  gh_font.build_texture(font_s1, 0)
  tex_font_s1 = gh_font.get_texture(font_s1)

end






-- Vulkan API information ------------------------
--
vk_gpus = {}
num_vk_gpus = 0
vk_info_initialized = false

function CreateVkGPU()
  local vk_gpu = {name="", vendor_id=0, device_id=0, api_ver_major=0, api_ver_minor=0, api_ver_patch=0}
  return vk_gpu
end  



function InitVkInfo()
  if (vk_info_initialized) then
    return
  end
  vk_info_initialized = true
  if (gh_utils.is_sbc() == 0) then
    num_vk_gpus = gh_renderer.vk_get_num_gpus()
    for i=0, num_vk_gpus-1 do
      local vkgpu = CreateVkGPU()
      vkgpu.name = gh_renderer.vk_gpu_get_name(i)
      vkgpu.vendor_id, vkgpu.device_id = gh_renderer.vk_gpu_get_device_id(i)
      vkgpu.api_ver_major, vkgpu.api_ver_minor, vkgpu.api_ver_patch = gh_renderer.vk_gpu_get_api_version(i)
      vk_gpus[i+1] = vkgpu
    end
  end
end


InitVkInfo()




rpi_gles = 0
if ((is_opengl_es == 1) and (gh_utils.is_rpi() == 1)) then
  rpi_gles = 1
end  











windows_info = {
  ReleaseId = 0,
  ProductName = "",
  CurrentBuildNumber = 0
}

function ReadWindowsInfo()
  local ret = 0
  local str = ""

  ret, str = gh_utils.win_registry_read_value_string("HKEY_LOCAL_MACHINE", "Software\\Microsoft\\Windows NT\\CurrentVersion", "ReleaseId")
  if (ret == 1) then 
    windows_info.ReleaseId = tonumber(str)
  end

  ret, windows_info.ProductName = gh_utils.win_registry_read_value_string("HKEY_LOCAL_MACHINE", "Software\\Microsoft\\Windows NT\\CurrentVersion", "ProductName")

  ret, str = gh_utils.win_registry_read_value_string("HKEY_LOCAL_MACHINE", "Software\\Microsoft\\Windows NT\\CurrentVersion", "CurrentBuildNumber")
  if (ret == 1) then 
    windows_info.CurrentBuildNumber = tonumber(str) 
  end
end  

















y_offset_start = 100


if (is_opengl_es == 0) then

  r, g, b = gh_utils.hex_color_to_rgb("#ff9900")
  gh_font.clear(font_h1)
  gh_font.text_2d(font_h1, 20, 55, r, g, b, 1.0, "GeeXLab")
  gh_font.update(font_h1, 0)



  g_need_update_font_h3 = 1



  local x_start = 260
  local y_start = 20
  --local y_offset = 100
  local y_offset = 110

  if (winW < 730) then
    x_start = 20
    y_start = 70
    --y_offset = 190
  end


  r, g, b = gh_utils.hex_color_to_rgb("#ffffff")
  gh_font.clear(font_h3)


  gh_font.text_2d(font_h3, 20, 72, 1, 1, 1, 1.0, geexlab_version)


  --gh_font.text_2d(font_h3, x_start, y_start, r, g, b, 1.0, "Prototyping, Pixel Hacking, Gamedev and Creative Coding")
  gh_font.text_2d(font_h3, x_start, y_start, r, g, b, 1.0, "Scriptable Proto-Engine (Lua, Python, GLSL, OpenGL, Vulkan)")
  y_start = y_start + 20

  gh_font.text_2d(font_h3, x_start, y_start, 1.0,0.5,0.0, 1.0, "- 3D Graphics: ")
  if (gh_utils.get_platform() == 1) then
    -- Windows
    gh_font.text_2d_v2(font_h3, 1.0, 1.0, 1.0, 1.0, "OpenGL, Vulkan, Direct3D 12")

  elseif (gh_utils.get_platform() == 2) then 
    -- OSX
    gh_font.text_2d_v2(font_h3, 1.0, 1.0, 1.0, 1.0, "OpenGL")

  elseif (gh_utils.get_platform() == 3) then 
    -- Linux
    if (gh_utils.is_tinker_board() == 1) then
      if (is_opengl_es == 1) then
        gh_font.text_2d_v2(font_h3, 1.0, 1.0, 1.0, 1.0, "OpenGL ES")
      else
        gh_font.text_2d_v2(font_h3, 1.0, 1.0, 1.0, 1.0, "OpenGL")
      end
    
    elseif (gh_utils.is_rpi() == 1) then
        gh_font.text_2d_v2(font_h3, 1.0, 1.0, 1.0, 1.0, "OpenGL")
    
    else
      if (num_vk_gpus > 0) then
        gh_font.text_2d_v2(font_h3, 1.0, 1.0, 1.0, 1.0, "OpenGL, Vulkan")
      else
        gh_font.text_2d_v2(font_h3, 1.0, 1.0, 1.0, 1.0, "OpenGL")
      end
    end
    
  elseif (gh_utils.get_platform() == 4) then 
    -- RPi
    gh_font.text_2d_v2(font_h3, 1.0, 1.0, 1.0, 1.0, "OpenGL ES")
  end  
    
  y_start = y_start + 20
  gh_font.text_2d(font_h3, x_start, y_start, 1.0, 0.5, 0.0, 1.0, "- Scripting: ")
  gh_font.text_2d_v2(font_h3, 1.0, 1.0, 1.0, 1.0, " Lua + Python")
  gh_font.update(font_h3, 0)



  gh_font.clear(font_s)
  gh_font.clear(font_s1)


  local s = ""


  gh_font.text_2d(font_s1, 20, y_offset, 1.0, 1.0, 1.0, 1.0, "OpenGL info:")
  y_offset = y_offset + 20

  gh_font.text_2d(font_s, 25, y_offset, 1.0, 0.6, 0.0, 1.0, "- GL_RENDERER: ")
  --r, g, b = gh_utils.hex_color_to_rgb("#a41e22")
  gh_font.text_2d_v2(font_s, 1.0, 1.0, 1.0, 1.0, gh_renderer.get_renderer_model())
  y_offset = y_offset + 20

  gh_font.text_2d(font_s, 25, y_offset, 1.0, 0.6, 0.0, 1.0, "- GL_VERSION: ")
  local glver_str = gh_renderer.get_api_version()
  local glver_len = string.len(glver_str)
  if (glver_len > 32) then
	  glver_str = string.sub(glver_str, 0, 32) .. "..."
  end
  gh_font.text_2d_v2(font_s, 1.0, 1.0, 1.0, 1.0, glver_str)
  y_offset = y_offset + 20

  if (num_vk_gpus > 0) then
    y_offset = y_offset + 20
    gh_font.text_2d(font_s1, 20, y_offset, 1.0, 1.0, 1.0, 1.0, "Vulkan info:")
    y_offset = y_offset + 20
    
    for i=0, num_vk_gpus-1 do
      local vkgpu = vk_gpus[i+1]
      s = string.format("- GPU %.0f: %s (%4X-%4X) - API: v%.0f.%.0f.%.0f", i+1, vkgpu.name, vkgpu.vendor_id, vkgpu.device_id, vkgpu.api_ver_major, vkgpu.api_ver_minor, vkgpu.api_ver_patch) 
      --gh_font.text_2d(font_s, 25, y_offset, 1.0, 0.6, 0.0, 1.0, s)
      gh_font.text_2d(font_s, 25, y_offset, 1.0, 0.15, 0.1, 1.0, s)
      y_offset = y_offset + 20
    end
  end

  if (gh_utils.is_sbc() == 1) then
    local hw_platform = gh_utils.get_hw_platform()
    y_offset = y_offset + 20
    gh_font.text_2d(font_s, 20, y_offset, 1.0, 1.0, 1.0, 1.0, "HW platform: ")
    gh_font.text_2d_v2(font_s, 1.0, 1.0, 0.0, 1.0, hw_platform)
    y_offset = y_offset + 20
  end 




  --[[
  local os_name, os_codename, os_ver_major, os_ver_minor, os_ver_patch = gh_utils.get_os_info()
  if (os_name == "Windows 10") then
    s = string.format("SW platform: %s (build %.0f)", os_name, os_ver_patch)
  else
    s = string.format("SW platform: %s", os_name)
  end  
  --]]


  if (gh_utils.get_platform() == 1) then -- Windows
    ReadWindowsInfo()
    s = string.format("SW platform: %s ver.%d (build %d)", windows_info.ProductName, windows_info.ReleaseId, windows_info.CurrentBuildNumber)

  else
    local os_name, os_codename, os_ver_major, os_ver_minor, os_ver_patch = gh_utils.get_os_info()
    s = string.format("SW platform: %s", os_name)
  
  end

  y_offset = y_offset + 20 
  gh_font.text_2d(font_s, 20, y_offset, 1.0, 1.0, 1.0, 1.0, s)
  y_offset = y_offset + 20 

  gh_font.update(font_s1, 0)
  gh_font.update(font_s, 0)

  y_offset_start = y_offset

end
  




rpi_gles = 0
if ((is_opengl_es == 1) and (gh_utils.is_rpi() == 1)) then
  rpi_gles = 1
end  


mouse_left_button_status = nil


last_time = gh_utils.get_elapsed_time()
frames = 0
fps = 0

gh_renderer.set_vsync(0)
--gh_renderer.set_depth_test_state(1)







local lib_dir = gh_utils.get_lib_dir() 		
dofile(lib_dir .. "lua/imgui.lua")
imgui_init("dark")

max_points = 360
max_plotlines = 2
plotid = gh_imgui.plot2_create(max_points, max_plotlines)
gh_imgui.plot2_set_color(plotid, 0.0, 1.0, 0.0, 1.0)
gh_imgui.plot2_set_frame_size(plotid, 200.0, 100.0)
gh_imgui.plot2_set_line_thickness(plotid, 2.0)
for i=0, max_points-1 do
	x = i
	y = 20.0 * math.sin(i*3.14159265 / 180.0)
	gh_imgui.plot2_set_value(plotid, 0, i, x, y)
	
	y = 20.0 * math.cos(i*3.14159265 / 180.0)
	gh_imgui.plot2_set_value(plotid, 1, i, x, y)
end








		]]></raw_data>
	</script> 
  
  
  
  
  
  
	<script name="terminate_scene" run_mode="TERMINATE" >
		<raw_data><![CDATA[	

if (nvg_initialized ~= nil) then
  gh_nvg.terminate()
  nvg_initialized = 0
end  

gh_imgui.terminate()

		]]></raw_data>
	</script> 

  
  
  
  
  
  
	<script name="update_scene" run_mode="FRAME" >
		<raw_data><![CDATA[	
    
    
    
------------------------------------------------------------------------------
function mouse_get_position()
  local mx, my = gh_input.mouse_getpos()
  
  if (rpi_gles == 1) then -- RPi+GLES
    local w, h = gh_window.getsize(0)
    mx = mx + w/2
    my = -(my - h/2) 
  end
  
  return mx, my
end    


    
    
    
    
    
    

local elapsed_time = gh_utils.get_elapsed_time()
frames = frames + 1
local dt = elapsed_time - last_time
if (dt >= 1.0) then
  last_time = elapsed_time
  fps = frames
  frames = 0
end





gh_camera.bind(camera_ortho)

gh_renderer.set_depth_test_state(0)
--gh_renderer.clear_color_depth_buffers(0.2, 0.2, 0.2, 1.0, 1.0)
gh_renderer.clear_color_depth_stencil_buffers(0.2, 0.2, 0.2, 1.0, 1.0, 0)



--local mx, my = gh_input.mouse_getpos()
local mx, my = mouse_get_position()
local LEFT_BUTTON = 1
--local is_left_button_down = gh_input.mouse_get_button_state(LEFT_BUTTON) 

local is_mouse_left_button_down = 0


if gh_input.mouse_get_button_state(LEFT_BUTTON) ~= 1 then
  mouse_left_button_status = true
elseif mouse_left_button_status == true then
  mouse_left_button_status = false
  is_mouse_left_button_down = 1
end




gh_gpu_program.bind(kool_effect_prog)
gh_gpu_program.uniform2f(kool_effect_prog, "resolution", winW, winH)
gh_gpu_program.uniform1f(kool_effect_prog, "time", elapsed_time)
if (rpi_gles == 1) then
  gh_gpu_program.uniform2f(kool_effect_prog, "mouse", mx+winW/2, my)
else
  gh_gpu_program.uniform2f(kool_effect_prog, "mouse", mx, winH/2 - my)
end  
gh_object.render(quad)












--[[
gh_renderer.set_depth_test_state(1)
gh_camera.bind(camera)

gh_gpu_program.bind(vertex_color_prog)

gh_object.set_position(mesh, 0, 0, 0)
gh_object.set_euler_angles(mesh, elapsed_time*20, elapsed_time*50, elapsed_time*10)

gh_renderer.wireframe()
gh_object.render(mesh)
gh_renderer.solid()
--]]
















gh_camera.bind(camera_ortho)


--gh_renderer.disable_state("GL_CULL_FACE")
gh_renderer.set_depth_test_state(0)



--[[
local BLEND_FACTOR_ONE = 1
local BLEND_FACTOR_SRC_ALPHA = 2
local BLEND_FACTOR_ONE_MINUS_DST_ALPHA = 3
local BLEND_FACTOR_ONE_MINUS_DST_COLOR = 4
local BLEND_FACTOR_ONE_MINUS_SRC_ALPHA = 5
local BLEND_FACTOR_DST_COLOR = 6
local BLEND_FACTOR_DST_ALPHA = 7
local BLEND_FACTOR_SRC_COLOR = 8
local BLEND_FACTOR_ONE_MINUS_SRC_COLOR = 9
gh_renderer.set_blending_state(1)
gh_renderer.set_blending_factors(BLEND_FACTOR_ONE, BLEND_FACTOR_ONE)
--]]

-- gh_renderer.blending_on("additive")
gh_renderer.blending_on("") -- defaut is additive: BLEND_FACTOR_ONE + BLEND_FACTOR_ONE



local quad2_y = 0
local quad3_x = 0

if (rpi_gles == 1) then
  quad2_y = my
  quad3_x = mx
else  
  quad2_y = winH/2 - my
  quad3_x = mx - winW/2
end  



gh_gpu_program.bind(vertex_color_prog)
gh_mesh.set_vertices_color(quad2, 0.0, 0.15, 0.17, 1.0)
gh_object.set_position(quad2, 0, quad2_y, 0)
gh_object.render(quad2)
gh_mesh.set_vertices_color(quad3, 0.0, 0.15, 0.17, 1.0)
gh_object.set_position(quad3, quad3_x, 0, 0)
gh_object.render(quad3)





gh_gpu_program.bind(font_prog)
gh_gpu_program.uniform1i(font_prog, "tex0", 0)



if (is_opengl_es == 0) then

  gh_texture.bind(tex_font_h1, 0)
  gh_font.render(font_h1)

  gh_texture.bind(tex_font_h3, 0)
  gh_font.render(font_h3)

  gh_texture.bind(tex_font_s, 0)
  gh_font.render(font_s)

  gh_texture.bind(tex_font_s1, 0)
  gh_font.render(font_s1)


  local y_offset = y_offset_start

  gh_font.clear(font_d)

  local s = string.format("Resolution: %.0fx%.0f", winW, winH)
  gh_font.text_2d(font_d, 20, y_offset, 0.4, 0.4, 0.4, 1.0, s)
  y_offset = y_offset + 20 

  s = string.format("Framerate: %.0f FPS - elapsed time: %.2f sec", fps, elapsed_time)
  gh_font.text_2d(font_d, 20, y_offset, 0.4, 0.4, 0.4, 1.0, s)

  gh_texture.bind(tex_font_d, 0)
  gh_font.update(font_d, 0)
  gh_font.render(font_d)

else

  local x_start = 150
  local y_start = 20
  local y_offset = 100


  gh_font.clear(font_d)

  gh_font.text_2d(font_d, 20, 20, 1.0, 0.6, 0.1, 1.0, "[ GEEXLAB ]")

  r, g, b = gh_utils.hex_color_to_rgb("#ffffff")
  gh_font.text_2d(font_d, x_start, y_start, r, g, b, 1.0, "Prototyping, Pixel Hacking, Gamedev and Creative Coding")
  y_start = y_start + 20

  gh_font.text_2d(font_d, x_start, y_start, 1.0,0.5,0.0, 1.0, "- 3D Graphics: ")
  if (gh_utils.get_platform() == 1) then
    -- Windows
    gh_font.text_2d_v2(font_d, 1.0, 1.0, 1.0, 1.0, "OpenGL + Vulkan + Direct3D 12")
  elseif (gh_utils.get_platform() == 2) then 
    -- OSX
    gh_font.text_2d_v2(font_d, 1.0, 1.0, 1.0, 1.0, "OpenGL")
  elseif (gh_utils.get_platform() == 3) then 
    -- Linux
    if (gh_utils.is_sbc() == 1) then
      gh_font.text_2d_v2(font_d, 1.0, 1.0, 1.0, 1.0, "OpenGL + OpenGL ES")
    else
      gh_font.text_2d_v2(font_d, 1.0, 1.0, 1.0, 1.0, "OpenGL + Vulkan")
    end
  elseif (gh_utils.get_platform() == 4) then 
    -- RPi
    gh_font.text_2d_v2(font_d, 1.0, 1.0, 1.0, 1.0, "OpenGL ES")
  end  
    
  y_start = y_start + 20
  gh_font.text_2d(font_d, x_start, y_start, 1.0, 0.5, 0.0, 1.0, "- Scripting: ")
  gh_font.text_2d_v2(font_d, 1.0, 1.0, 1.0, 1.0, " Lua + Python")
  y_start = y_start + 20




  gh_font.text_2d(font_d, 20, y_offset, 1.0, 1.0, 1.0, 1.0, "OpenGL info:")
  y_offset = y_offset + 20
  gh_font.text_2d(font_d, 25, y_offset, 1.0, 0.6, 0.0, 1.0, "- GL_RENDERER: ")

  gh_font.text_2d_v2(font_d, 1.0, 1.0, 1.0, 1.0, gh_renderer.get_renderer_model())

  y_offset = y_offset + 20
  gh_font.text_2d(font_d, 25, y_offset, 1.0, 0.6, 0.0, 1.0, "- GL_VERSION: ")
  gh_font.text_2d_v2(font_d, 1.0, 1.0, 1.0, 1.0, gh_renderer.get_api_version())
  y_offset = y_offset + 20


  if (gh_utils.is_sbc() == 1) then
    local hw_platform = gh_utils.get_hw_platform()
    y_offset = y_offset + 20
    gh_font.text_2d(font_d, 20, y_offset, 1.0, 1.0, 1.0, 1.0, "HW platform: ")
    gh_font.text_2d_v2(font_d, 1.0, 1.0, 0.0, 1.0, hw_platform)
    y_offset = y_offset + 20
  end 


  local os_name, os_codename, os_ver_major, os_ver_minor, os_ver_patch = gh_utils.get_os_info()
  if (os_name == "Windows 10") then
    s = string.format("SW platform: %s (build %.0f)", os_name, os_ver_patch)
  else
    s = string.format("SW platform: %s", os_name)
  end  
  y_offset = y_offset + 20 
  gh_font.text_2d(font_d, 20, y_offset, 1.0, 1.0, 1.0, 1.0, s)
  y_offset = y_offset + 20 





  s = string.format("Resolution: %.0fx%.0f", winW, winH)
  gh_font.text_2d(font_d, 20, y_offset, 0.4, 0.4, 0.4, 1.0, s)
  y_offset = y_offset + 20 

  s = string.format("Framerate: %.0f FPS - elapsed time: %.2f sec", fps, elapsed_time)
  gh_font.text_2d(font_d, 20, y_offset, 0.4, 0.4, 0.4, 1.0, s)

  gh_texture.bind(tex_font_d, 0)
  gh_font.update(font_d, 0)
  gh_font.render(font_d)

end



gh_renderer.blending_off()






if (show_nanovg) then


  if (nvg_initialized == nil) then
    nvg_initialized = 1
    gh_nvg.init(1)
    local demo_dir = gh_utils.get_demo_dir()
    gh_nvg.load_font("icons", demo_dir .. "fonts/entypo.ttf")
    gh_nvg.load_font("sans", demo_dir .. "fonts/Roboto-Regular.ttf")
    gh_nvg.load_font("sans-bold", demo_dir .. "fonts/Roboto-Bold.ttf")
  end  


  --gh_renderer.set_scissor_state(1)
  --gh_renderer.set_depth_test_state(1)
  gh_nvg.begin_frame(winW, winH, 1.0)





  gh_nvg.font_params(18, "sans-bold", 0.0)
  gh_nvg.fill_color(0.4, 0.4, 0.4, 1)

  function IsButtonHovered(button, mx, my)
    if ((mx >= button.x) and (mx <= button.x+button.w) and (my >= button.y) and (my <= button.y + button.h)) then
      return 1
    end
    return 0
  end

  function DrawButton(button)
    local NVG_ICON_CIRCLED_CROSS = 10006
    local NVG_ICON_CHEVRON_RIGHT = 59230
    gh_nvg.button_draw(NVG_ICON_CHEVRON_RIGHT, button.label, button.x, button.y, button.w, button.h, button.r, button.g, button.b, button.a)
    --gh_nvg.button_draw(NVG_ICON_CIRCLED_CROSS, button.label, button.x, button.y, button.w, button.h, button.r, button.g, button.b, button.a)
  end


  local button_y = 60
  local button_width = 160
  local button_height = 24
  local button_vspace = 5

  local bR = 0.15
  local bG = 0.4
  local bB = 0.5

  -------------------------------
  local button1 = {label="Getting Started", x=winW-button_width-10, y=button_y-16, w=button_width, h=button_height+16, r=bR, g=bG, b=bB, a=1, hovered=0}
  if (IsButtonHovered(button1, mx, my) == 1) then
    button1.r = bR + 0.2
    button1.g = bG + 0.2
    button1.b = bB + 0.2
    button1.hovered = 1
  end

  DrawButton(button1)

  if ((button1.hovered==1) and (is_mouse_left_button_down == 1)) then
    gh_utils.open_url("https://geeks3d.com/r/610")
  end





  --------------------------------
  button_y = button_y + button_height + button_vspace
  local button2 = {label="Release Notes", x=winW-button_width-10, y=button_y, w=button_width, h=button_height, r=0.6, g=0.4, b=0.1, a=1, hovered=0}
  if (IsButtonHovered(button2, mx, my) == 1) then
    button2.r = 0.9
    button2.g = 0.45
    button2.b = 0.0
    button2.hovered = 1
  end

  DrawButton(button2)

  if ((button2.hovered==1) and (is_mouse_left_button_down == 1)) then
    gh_utils.open_url("https://geeks3d.com/r/602")
  end


  -------------------------------
  button_y = button_y + button_height + button_vspace
  local button3 = {label="Download Page", x=winW-button_width-10, y=button_y, w=button_width, h=button_height, r=bR, g=bG, b=bB, a=1, hovered=0}
  if (IsButtonHovered(button3, mx, my) == 1) then
    button3.r = bR + 0.2
    button3.g = bG + 0.2
    button3.b = bB + 0.2
    button3.hovered = 1
  end

  DrawButton(button3)

  if ((button3.hovered==1) and (is_mouse_left_button_down == 1)) then
    gh_utils.open_url("https://geeks3d.com/r/615")
  end



  -------------------------------
  button_y = button_y + button_height + button_vspace
  local button4 = {label="Learn Pack", x=winW-button_width-10, y=button_y, w=button_width, h=button_height, r=bR, g=bG, b=bB, a=1, hovered=0}
  if (IsButtonHovered(button4, mx, my) == 1) then
    button4.r = bR + 0.2
    button4.g = bG + 0.2
    button4.b = bB + 0.2
    button4.hovered = 1
  end

  DrawButton(button4)

  if ((button4.hovered==1) and (is_mouse_left_button_down == 1)) then
    gh_utils.open_url("https://geeks3d.com/r/612")
  end



  -------------------------------
  button_y = button_y + button_height + button_vspace
  local button5 = {label="Scripting API", x=winW-button_width-10, y=button_y, w=button_width, h=button_height, r=bR, g=bG, b=bB, a=1, hovered=0}
  if (IsButtonHovered(button5, mx, my) == 1) then
    button5.r = bR + 0.2
    button5.g = bG + 0.2
    button5.b = bB + 0.2
    button5.hovered = 1
  end

  DrawButton(button5)

  if ((button5.hovered==1) and (is_mouse_left_button_down == 1)) then
    gh_utils.open_url("https://geeks3d.com/r/611")
  end


  -------------------------------
  button_y = button_y + button_height + button_vspace
  local button6 = {label="Rootard Guide", x=winW-button_width-10, y=button_y, w=button_width, h=button_height, r=bR, g=bG, b=bB, a=1, hovered=0}
  if (IsButtonHovered(button6, mx, my) == 1) then
    button6.r = bR + 0.2
    button6.g = bG + 0.2
    button6.b = bB + 0.2
    button6.hovered = 1
  end

  DrawButton(button6)

  if ((button6.hovered==1) and (is_mouse_left_button_down == 1)) then
    gh_utils.open_url("https://geeks3d.com/r/613")
  end

  -------------------------------
  button_y = button_y + button_height + button_vspace
  local button7 = {label="Open demos folder", x=winW-button_width-10, y=button_y, w=button_width, h=button_height, r=bR, g=bG, b=bB, a=1, hovered=0}
  if (IsButtonHovered(button7, mx, my) == 1) then
    button7.r = bR + 0.2
    button7.g = bG + 0.2
    button7.b = bB + 0.2
    button7.hovered = 1
  end

  DrawButton(button7)

  if ((button7.hovered==1) and (is_mouse_left_button_down == 1)) then
    local app_dir = gh_utils.get_app_dir()
    gh_utils.open_url(app_dir .. "/demos/")
  end



  ------------------------------------------------------

  button_y = button_y + button_height + button_vspace
  local button8 = {label="Donate", x=winW-button_width-10, y=button_y, w=button_width, h=button_height, r=0.6, g=0.4, b=0.0, a=1, hovered=0}
  if (IsButtonHovered(button8, mx, my) == 1) then
    button8.r = 0.9
    button8.g = 0.45
    button8.b = 0.0
    button8.hovered = 1
  end

  DrawButton(button8)

  if ((button8.hovered==1) and (is_mouse_left_button_down == 1)) then
    gh_utils.open_url("https://geeks3d.com/r/710")
  end


  ------------------------------------------------------

  button_y = button_y + button_height + button_vspace
  local button9 = {label="Demo of the Day", x=winW-button_width-10, y=button_y, w=button_width, h=button_height, r=bR, g=bG, b=bB, a=1, hovered=0}
  if (IsButtonHovered(button9, mx, my) == 1) then
    button9.r = bR + 0.2
    button9.g = bG + 0.2
    button9.b = bB + 0.2
    button9.hovered = 1
  end

  DrawButton(button9)

  if ((button9.hovered==1) and (is_mouse_left_button_down == 1)) then
    gh_utils.open_url("https://geeks3d.com/r/617")
  end



  -------------------------------
  if (gh_utils.get_platform() == 1) then -- Windows
    -- On Windows only. On Linux, there is an alpha blending issue and I don't want to waste time on that bug...
    gh_nvg.demo_eyes_draw(winW-140-button_width-10, 90, 120, 100, mx, my, elapsed_time)
  end



  gh_nvg.end_frame()

end


--gh_renderer.set_scissor_state(0)





local plot_frame_w = 300
local plot_frame_h = 60

imgui_frame_begin()
gh_imgui.set_color(IMGUI_WINDOW_BG_COLOR, 0.2, 0.2, 0.2, 0.2)
gh_imgui.set_color(IMGUI_FRAME_BG_COLOR, 0.2, 0.2, 0.2, 0.4)
local opened = imgui_window_begin_no_titlebar("Plots", plot_frame_w+10, plot_frame_h+20, 20, winH - plot_frame_h-20)
if (opened == 1) then

  local y0 = 0
  for i=0, max_points-1 do
    x = i
    y = 20.0 * math.sin(4.0*i*3.14159265 / 180.0 + elapsed_time*2.0) * math.sin(7.0*i*3.14159265 / 180.0 + elapsed_time*8.0)
    gh_imgui.plot2_set_value(plotid, 0, i, x, y)
    y = 20.0 * math.cos(5.0*i*3.14159265 / 180.0 + elapsed_time*2.0) * math.cos(2.0*i*3.14159265 / 180.0 + elapsed_time*4.0)
    gh_imgui.plot2_set_value(plotid, 1, i, x, y)

  end

  gh_imgui.plot2_set_frame_size(plotid, plot_frame_w, plot_frame_h)
  gh_imgui.plot2_set_line_thickness(plotid, 2.0)
  gh_imgui.plot2_set_scale(plotid, -20, 20, 0)
  gh_imgui.plot2_set_count_and_offset(plotid, max_points, 0)
  --gh_imgui.plot2_set_overlay_text(plotid, string.format("[~ y=%02.2f ~]", y))
  gh_imgui.plot2_set_overlay_text(plotid, "https://geeks3d.com/geexlab/")
  --gh_imgui.plot2_set_tooltip_format(plotid, "angle=%.2f, sin()=%.2f")

  gh_imgui.plot2_set_grid_size_and_subticks(plotid, 0, 100.0, 4)
  gh_imgui.plot2_set_state(plotid, "show_grid_x", 1)
  gh_imgui.plot2_set_grid_size_and_subticks(plotid, 1, 20.0, 4)
  gh_imgui.plot2_set_state(plotid, "show_grid_y", 1)


  gh_imgui.plot2_set_state(plotid, "show_tooltip", 0)
  gh_imgui.plot2_set_color(plotid, 0, 1.0, 0.6, 0.0, 0.5)
  gh_imgui.plot2_set_color(plotid, 1, 1.0, 0.2, 0.1, 0.5)

  gh_imgui.set_color(IMGUI_TEXT_COLOR, 0.7, 0.7, 0.7, 1.0)
  gh_imgui.plot2_draw(plotid, "plotid1")
  gh_imgui.set_color(IMGUI_TEXT_COLOR, 1.0, 1.0, 1.0, 1.0)

end  
imgui_window_end()
imgui_frame_end()





		]]></raw_data>
	</script> 
	

	<script name="resize_scene" run_mode="SIZE" >
		<raw_data><![CDATA[	

winW, winH = gh_window.getsize(0)

local aspect = 1.333
if (winH > 0) then
  aspect = winW / winH
end  
gh_camera.update_persp(camera, 50, aspect, 1.0, 1000.0)
gh_camera.set_viewport(camera, 0, 0, winW, winH)


gh_camera.update_ortho(camera_ortho, -winW/2, winW/2, -winH/2, winH/2, 1.0, 10.0)
gh_camera.set_viewport(camera_ortho, 0, 0, winW, winH)

gh_mesh.update_quad_size(quad, winW, winH)
gh_mesh.update_quad_size(quad2, winW, quad_band_width)
gh_mesh.update_quad_size(quad3, quad_band_width, winH)

		]]></raw_data>
	</script> 


  
<!--  
<gpu_program name="texture_prog" >
    <raw_data_vs><![CDATA[	 
#version 120    
void main()
{
  gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;		
  gl_TexCoord[0] = gl_MultiTexCoord0;
}
  ]]></raw_data_vs>
    <raw_data_ps><![CDATA[	 
#version 120    
uniform sampler2D tex0;
void main (void)
{
  vec2 uv = gl_TexCoord[0].xy;
  uv.y *= -1.0;
  vec3 t = texture2D(tex0,uv).rgb;
  gl_FragColor = vec4(t, 1.0);
}
    ]]></raw_data_ps>
  </gpu_program>
-->
  

<!--
<gpu_program name="vertex_color_prog" >
    <raw_data_vs><![CDATA[	 
#version 120    
void main()
{
  gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;		
  gl_FrontColor = gl_Color;
}
  ]]></raw_data_vs>
    <raw_data_ps><![CDATA[	 
#version 120    
void main (void)
{
  gl_FragColor = gl_Color;
}
    ]]></raw_data_ps>
  </gpu_program>
-->


<!--
<gpu_program name="font_prog" >
    <raw_data_vs><![CDATA[	 
#version 120
uniform mat4 gxl3d_ViewProjectionMatrix;
uniform mat4 gxl3d_ModelMatrix;
uniform vec4 gxl3d_Viewport;
varying vec4 Vertex_UV;
varying vec4 Vertex_Color;
void main()
{
  vec4 P = gl_Vertex;
  vec4 Pw = gxl3d_ModelMatrix * P;
  Pw.x = Pw.x - gxl3d_Viewport.z/2;
  Pw.y = Pw.y + gxl3d_Viewport.w/2;
  gl_Position = gxl3d_ViewProjectionMatrix * Pw;		
  Vertex_UV = gl_MultiTexCoord0;
  Vertex_Color = gl_Color;
}
  ]]></raw_data_vs>
    <raw_data_ps><![CDATA[	 
#version 120
uniform sampler2D tex0;
varying vec4 Vertex_UV;
varying vec4 Vertex_Color;
void main (void)
{
  vec2 uv = Vertex_UV.xy;
  float t = texture2D(tex0,uv).r;
  gl_FragColor = vec4(t * Vertex_Color.rgb, 1.0); 
  //gl_FragColor = vec4(t, 1.0); 
  //gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0); 
  //gl_FragColor = vec4(uv, 0.0, 1.0); 
}
    ]]></raw_data_ps>
  </gpu_program>
-->

<!--
<gpu_program name="kool_effect_prog" >
	<raw_data_vs><![CDATA[	 
#version 120
void main()
{	
  gl_FrontColor = gl_Color;
	gl_TexCoord[0] = gl_MultiTexCoord0;
  gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;		
}
  ]]></raw_data_vs>
  
	<raw_data_ps><![CDATA[	 
#version 120
uniform float time;
uniform vec2 resolution;
uniform vec2 mouse;
void main(void)
{
  //vec2 p = gl_FragCoord.xy / resolution.xy;
  //gl_FragColor = vec4(p.x, p.x, p.x,1.0);
  vec2 uv = 2.0 * (gl_FragCoord.xy / resolution.xy) - 1.0;
  uv *= 2.0;
  float col=0.0;
  float i=0.73;
  vec2 spec = vec2(0.1, 0.1);
  //uv.x += -1.05 + sin(i*20.0 + spec.x*5.0*time*6.0 + uv.y*1.5) * spec.y;
  uv.x += -((mouse.x/resolution.x*4.0)-2.0) + sin(i*20.0 + spec.x*5.0*time*6.0 + uv.y*1.5) * spec.y;
  col += abs(0.066/uv.x) * spec.y;
  //gl_FragColor = vec4(col+0.05, col+0.075, col+0.42, 1.0);
  gl_FragColor = vec4(col+gl_Color.x, col+gl_Color.y, col+gl_Color.z, 1.0);
  	
}  ]]></raw_data_ps>

</gpu_program>
-->

<!--
<gpu_program name="toon_prog" >
    <raw_data_vs><![CDATA[	 
#version 120
uniform mat4 gxl3d_ModelViewProjectionMatrix; // Automatically passed by GeeXLab
uniform mat4 gxl3d_ModelViewMatrix; // Automatically passed by GeeXLab
uniform vec4 light_position;
varying vec4 v_normal;
varying vec4 v_lightdir;
varying vec4 v_eye;
void main()
{
  gl_Position = gxl3d_ModelViewProjectionMatrix * gl_Vertex;
  v_normal = gxl3d_ModelViewMatrix  * vec4(gl_Normal.xyz, 0.0);
  vec4 view_vertex = gxl3d_ModelViewMatrix * gl_Vertex;
  v_lightdir = light_position - view_vertex;
  v_eye = -view_vertex;
}
  ]]></raw_data_vs>
    <raw_data_ps><![CDATA[	 
#version 120
uniform vec4 color1;
uniform vec4 color2;
uniform vec4 color3;
uniform vec4 color4;
varying vec4 v_normal;
varying vec4 v_lightdir;
varying vec4 v_eye;
void main()
{
	vec4 color;
  vec3 L = normalize(v_lightdir.xyz);
  vec3 N = normalize(v_normal.xyz);
	float intensity = dot(L, N);
	if (intensity > 0.95)
		color = color1;
	else if (intensity > 0.5)
		color = color2;
	else if (intensity > 0.25)
		color = color3;
	else
		color = color4;
	gl_FragColor = color;
}
    ]]></raw_data_ps>
  </gpu_program>
  -->
    
</glsl_hacker>
