text: //memory.js
  //Written by Sem Voigtländer
  //Licensed under the MIT License
  
  /*
  	Functionality for geting the memory size of a javascript object
  */
  
  function free(objectName)
  {
  	if(eval(objectName) != 'undefined')
  	{
  		console.log('Helping the garbage collector a little bit with freeing.');
  		eval(objectName + '=undefined;');
  	}
  }
  
  function sizeof(object) {
  
      var objectList = [];
      var stack = [object];
      var bytes = 0;
  
      while (stack.length) {
          var value = stack.pop();
  
          if (typeof value === 'boolean') {
              bytes += 4;
          } else if (typeof value === 'string') {
              bytes += value.length * 2;
          } else if (typeof value === 'number') {
              bytes += 8;
          } else if (
              typeof value === 'object' &&
              objectList.indexOf(value) === -1
          ) {
              objectList.push(value);
  
              for (var i in value) {
                  stack.push(value[i]);
              }
          }
      }
      return bytes;
  }
  
  /* 
  	Functions for swapping the endianness of an integer
  	Supports 16, 32 and 64 bit integers. (Experimental 128-bits as well)
  	Smaller integers are automatically casted to the corresponding size.
  	Bigger integers are not casted to smaller integers as they may lose precision.
  */
  
  function SwapEndian16(integer) {
  
  	var _hex = '0';
  	var _output = '';
  
  	//Input validation
  	if(typeof integer !== 'number')
  		throw new Error('Invalid argument. argument provided is not an integer.');
  	if(integer < 0)
  		throw new Error('Invalid argument. argument provided may not be negative.');
  
  	_hex = integer.toString(16); //Conver the input to a hexadecimal string
  
  	//Conver the hexadecimal string to a 16-bit integer hexadecimal string
  	while(_hex.length < 4)
  		_hex = '0'+_hex;
  
  	let _arr = _hex.split(''); //Convert the 16-bit integer hexadecimal string to a char array
  
  	//Sanity check
  	if (_arr.length != 4)
  		throw new Error('Invalid argument. argument provided is not a 16-bit integer.');
  
  
  	//Swap the endianness
  	_output += (_arr[2] + _arr[3]).toString();
  	_output += (_arr[0] + _arr[1]).toString();
  
  	//Output sanity check
  	if(_output.length != 4)
  		throw new Error('Sanity check failed. Output is not a 16-bit integer');
  
  	_output = parseInt('0x'+_output); //convert the hexadecimal output string to an integer
  
  	//Conversion sanity check
  	if(_output === NaN)
  		throw new Error('Conversion from a hexadecimal string to an integer failed.');
  
  	return _output;
  }
  
  function SwapEndian32(integer) {
  
  	var _hex = '0';
  	var _output = '';
  
  	//Input validation
  	if(typeof integer !== 'number')
  		throw new Error('Invalid argument. argument provided is not an integer.');
  	if(integer < 0)
  		throw new Error('Invalid argument. argument provided may not be negative.');
  
  	_hex = integer.toString(16); //Conver the input to a hexadecimal string
  
  	//Conver the hexadecimal string to a 32-bit integer hexadecimal string
  	while(_hex.length < 8)
  		_hex = '0'+_hex;
  
  	let _arr = _hex.split(''); //Convert the 32-bit integer hexadecimal string to a char array
  
  	//Sanity check
  	if (_arr.length != 8)
  		throw new Error('Invalid argument. argument provided is not a 32-bit integer.');
  
  
  	//Swap the endianness
  	_output += (_arr[6] + _arr[7]).toString();
  	_output += (_arr[4] + _arr[5]).toString();
  	_output += (_arr[2] + _arr[3]).toString();
  	_output += (_arr[0] + _arr[1]).toString();
  
  	//Output sanity check
  	if(_output.length != 8)
  		throw new Error('Sanity check failed. Output is not a 32-bit integer');
  
  	_output = parseInt('0x'+_output); //convert the hexadecimal output string to an integer
  
  	//Conversion sanity check
  	if(_output === NaN)
  		throw new Error('Conversion from a hexadecimal string to an integer failed.');
  
  	//Lets help javascripts garbage collector a bit
  	_arr = undefined;
  	_hex = undefined;
  
  	return _output;
  }	
  
  function SwapEndian64(integer) {
  
  	var _hex = '0';
  	var _output = '';
  
  	//Input validation
  	if(typeof integer !== 'number')
  		throw new Error('Invalid argument. argument provided is not an integer.');
  	if(integer < 0)
  		throw new Error('Invalid argument. argument provided may not be negative.');
  
  	_hex = integer.toString(16); //Conver the input to a hexadecimal string
  
  	//Conver the hexadecimal string to a 64-bit integer hexadecimal string
  	while(_hex.length < 16)
  		_hex = '0'+_hex;
  
  	let _arr = _hex.split(''); //Convert the 64-bit integer hexadecimal string to a char array
  
  	//Sanity check
  	if (_arr.length != 16)
  		throw new Error('Invalid argument. argument provided is not a 64-bit integer.');
  
  
  	//Swap the endianness
  	_output += (_arr[14] + _arr[15]).toString();
  	_output += (_arr[12] + _arr[13]).toString();
  	_output += (_arr[10] + _arr[11]).toString();
  	_output += (_arr[8] + _arr[9]).toString();
  	_output += (_arr[6] + _arr[7]).toString();
  	_output += (_arr[4] + _arr[5]).toString();
  	_output += (_arr[2] + _arr[3]).toString();
  	_output += (_arr[0] + _arr[1]).toString();
  
  	//Output sanity check
  	if(_output.length != 16)
  		throw new Error('Sanity check failed. Output is not a 64-bit integer');
  
  	_output = parseInt('0x'+_output); //convert the hexadecimal output string to an integer
  
  	//Conversion sanity check
  	if(_output === NaN)
  		throw new Error('Conversion from a hexadecimal string to an integer failed.');
  
  	//Lets help javascripts garbage collector a bit
  	_arr = undefined;
  	_hex = undefined;
  
  	return _output;
  }	
  
  function SwapEndian128(integer) {
  
  	var _hex = '0';
  	var _output = '';
  
  	//Input validation
  	if(typeof integer !== 'number')
  		throw new Error('Invalid argument. argument provided is not an integer.');
  	if(integer < 0)
  		throw new Error('Invalid argument. argument provided may not be negative.');
  
  	_hex = integer.toString(16); //Conver the input to a hexadecimal string
  
  	//Conver the hexadecimal string to a 128-bit integer hexadecimal string
  	while(_hex.length < 32)
  		_hex = '0'+_hex;
  
  	let _arr = _hex.split(''); //Convert the 128-bit integer hexadecimal string to a char array
  
  	//Sanity check
  	if (_arr.length != 32)
  		throw new Error('Invalid argument. argument provided is not a 128-bit integer.');
  
  
  	//Swap the endianness
  	_output += (_arr[30] + _arr[31]).toString();
  	_output += (_arr[28] + _arr[29]).toString();
  	_output += (_arr[26] + _arr[27]).toString();
  	_output += (_arr[24] + _arr[25]).toString();
  	_output += (_arr[22] + _arr[23]).toString();
  	_output += (_arr[20] + _arr[21]).toString();
  	_output += (_arr[18] + _arr[19]).toString();
  	_output += (_arr[16] + _arr[17]).toString();
  	_output += (_arr[14] + _arr[15]).toString();
  	_output += (_arr[12] + _arr[13]).toString();
  	_output += (_arr[10] + _arr[11]).toString();
  	_output += (_arr[8] + _arr[9]).toString();
  	_output += (_arr[6] + _arr[7]).toString();
  	_output += (_arr[4] + _arr[5]).toString();
  	_output += (_arr[2] + _arr[3]).toString();
  	_output += (_arr[0] + _arr[1]).toString();
  
  	//Output sanity check
  	if(_output.length != 32)
  		throw new Error('Sanity check failed. Output is not a 128-bit integer');
  
  	_output = parseInt('0x'+_output); //convert the hexadecimal output string to an integer
  
  	//Conversion sanity check
  	if(_output === NaN)
  		throw new Error('Conversion from a hexadecimal string to an integer failed.');
  
  	//Lets help javascripts garbage collector a bit
  	_arr = undefined;
  	_hex = undefined;
  
  	return _output;
  }	
  
  
  /*
  	Functions for reading integers from a given offset in a given array.
  	Supports 16, 32 and 64 bit integers. (Experimental 128-bits as well)
  	It also supports reading with a different Endianness.
  
  */
  
  //Big Endian
  function ReadUint16(arr, off) {
  
  	if(arr.length < 2 || off > arr.length) //sanity check
  		throw new Error('Cannot read OOB.');
  
      return parseInt("0x" + 
      	arr[off].toString(16) + 
      	arr[off + 1].toString(16)
      );
  }
  
  function ReadUint32(arr, off) {
  
  	if(arr.length < 4 || off > arr.length) //sanity check
  		throw new Error('Cannot read OOB.');
  
      return parseInt("0x" + 
      	arr[off].toString(16) + 
      	arr[off + 1].toString(16) + 
      	arr[off + 2].toString(16) + 
      	arr[off + 3].toString(16)
      );
  }
  
  function ReadUint64(arr, off) {
  
  	if(arr.length < 8 || off > arr.length) //sanity check
  		throw new Error('Cannot read OOB.');
  
      return parseInt("0x" + 
      	arr[off].toString(16) + 
      	arr[off + 1].toString(16) + 
      	arr[off + 2].toString(16) + 
      	arr[off + 3].toString(16) +
      	arr[off + 4].toString(16) +
      	arr[off + 5].toString(16) +
      	arr[off + 6].toString(16) +
      	arr[off + 7].toString(16)
      );
  }
  
  function ReadUint128(arr, off) {
  
  	if(arr.length < 16 || off > arr.length) //sanity check
  		throw new Error('Cannot read OOB.');
  
      return parseInt("0x" + 
      	arr[off].toString(16) + 
      	arr[off + 1].toString(16) + 
      	arr[off + 2].toString(16) + 
      	arr[off + 3].toString(16) +
      	arr[off + 4].toString(16) +
      	arr[off + 5].toString(16) +
      	arr[off + 6].toString(16) +
      	arr[off + 7].toString(16) +
      	arr[off + 8].toString(16) +
      	arr[off + 9].toString(16) +
      	arr[off + 10].toString(16) +
      	arr[off + 11].toString(16) +
      	arr[off + 12].toString(16) +
      	arr[off + 13].toString(16) +
      	arr[off + 14].toString(16) +
      	arr[off + 15].toString(16)
      );
  }
  
  //Little Endian
  function ReadUint16LE(arr, off) {
  
  	if(arr.length < 2 || off > arr.length) //sanity check
  		throw new Error('Cannot read OOB.');
      
      return parseInt("0x" + 
      	arr[off + 1].toString(16) + 
      	arr[off].toString(16)
      );
  }
  
  function ReadUint32LE(arr, off) {
  	if(arr.length < 4 || off > arr.length) //sanity check
  		throw new Error('Cannot read OOB.');
  
      return parseInt("0x" + 
      	arr[off + 3].toString(16) + 
      	arr[off + 2].toString(16) + 
      	arr[off + 1].toString(16) + 
      	arr[off].toString(16)
      );
  }
  
  function ReadUint64LE(arr, off) {
  
  	if(arr.length < 8 || off > arr.length) //sanity check
  		throw new Error('Cannot read OOB.');
  
      return parseInt("0x" + 
      	arr[off + 7].toString(16) + 
      	arr[off + 6].toString(16) + 
      	arr[off + 5].toString(16) + 
      	arr[off + 4].toString(16) +
      	arr[off + 3].toString(16) +
      	arr[off + 2].toString(16) +
      	arr[off + 1].toString(16) +
      	arr[off].toString(16)
      );
  }
  
  function ReadUint128LE(arr, off) {
  
  	if(arr.length < 16 || off > arr.length) //sanity check
  		throw new Error('Cannot read OOB.');
  
      return parseInt("0x" + 
      	arr[off + 15].toString(16) + 
      	arr[off + 14].toString(16) + 
      	arr[off + 13].toString(16) + 
      	arr[off + 12].toString(16) +
      	arr[off + 11].toString(16) +
      	arr[off + 10].toString(16) +
      	arr[off + 9].toString(16) +
      	arr[off + 8].toString(16) +
      	arr[off + 7].toString(16) +
      	arr[off + 6].toString(16) +
      	arr[off + 5].toString(16) +
      	arr[off + 4].toString(16) +
      	arr[off + 3].toString(16) +
      	arr[off + 2].toString(16) +
      	arr[off + 1].toString(16) +
      	arr[off].toString(16)
      );
  }
  
  function writeUint8(arr, off, val) {
  	if(arr.length < 2 || off > arr.length || off < 0) {
  		throw new Error('Cannot write OOB.');
  	}
  
  
  	if(val.length > 0xff)
  		throw new Error('Invalid argument. This should be a valid 8-bit integer.');
  	let old = arr[off];
  	arr[off] = val;
  }
  
  function writeUint16(arr, off, val) {
  	if(arr.length < 4 || off > arr.length || off < 0) { //We should never underflow or overflow our buffer
  		throw new Error('Cannot write OOB.');
  	}
  
  
  	if(val.length > 0xffff) //Values that after serialization never will be a 16 bit integer should never be treated
  		throw new Error('Invalid argument. This should be a valid 16-bit integer.');
  	
  	let old = new Array(arr[off], arr[off+1]);
  
  	if(val <= 0xff) { //Integers below 256 are always valid
  		arr[off] = val;
  
  	} else if(val > 0xff && val <= 0xfff) { //Integers bigger than 256 but below 4096 should be treated as two bytes instead of one and fixed with a leading zero
  		arr[off] = parseInt('0x'+(val.toString(16).split('')[0] + val.toString(16).split('')[1]));
  		arr[off+1] = parseInt('0x0'+val.toString(16).split('')[2]);
  
  	} else if(val > 0xff && val <= 0xffff) { //Integers bigger than 256 and below 65535 should be treated as two bytes and can be splitted without having to fix them with a leading zero
  		arr[off] = parseInt('0x'+(val.toString(16).split('')[0] + val.toString(16).split('')[1]));
  		arr[off+1] = parseInt('0x'+val.toString(16).split('')[2] + val.toString(16).split('')[3]);
  
  	}
  
  }