code: function Program(gl, codes, includes) {
      if (typeof codes.vert !== 'string') {
          throw Error('[webgl.program] Missing attribute `vert` in argument `codes`!');
      }
      if (typeof codes.frag !== 'string') {
          throw Error('[webgl.program] Missing attribute `frag` in argument `codes`!');
      }
  
      codes = parseIncludes(codes, includes);
  
      this.gl = gl;
      Object.freeze(this.gl);
  
      this._typesNamesLookup = getTypesNamesLookup(gl);
  
      var shaderProgram = gl.createProgram();
      var shaderVert = getVertexShader(gl, codes.vert);
      var shaderFrag = getFragmentShader(gl, codes.frag);
      gl.attachShader(shaderProgram, shaderVert);
      gl.attachShader(shaderProgram, shaderFrag);
      gl.linkProgram(shaderProgram);
      /*  Si on exécute les 4 lignes suivantes, on ne peut pas debugger les shaders.
        gl.detachShader( shaderProgram, shaderVert );
        gl.deleteShader( shaderVert );
        gl.detachShader( shaderProgram, shaderFrag );
        gl.deleteShader( shaderFrag );
      */
      this.program = shaderProgram;
      Object.freeze(this.program);
  
      this.use();
      createAttributes(this, gl, shaderProgram);
      createUniforms(this, gl, shaderProgram);
  }
docs: Creating  a  WebGL  program  for shaders  is  painful.  This  class
  simplifies the process.
  
  @class Program
  
  Object properties starting with `$` are WebGL uniforms or attributes.
  Uniforms behave as expected: you can read/write a value.
  Attributes when read, return the location. And when written, enable/disabled
  this attribute. So you read integers and writte booleans.
  
  @param gl - WebGL context.
  @param codes  - Object  with two  mandatory attributes:  `vert` for
  vertex shader and `frag` for fragment shader.
  @param  includes  -  (optional)  If  defined,  the  `#include  foo`
  directives  of  shaders   will  be  replaced  by   the  content  of
  `includes.foo`.