text: module.exports.pack = function(format) {
      // http://kevin.vanzonneveld.net
      // +   original by: Tim de Koning (http://www.kingsquare.nl)
      // +      parts by: Jonas Raoni Soares Silva (http://www.jsfromhell.com)
      // +   bugfixed by: Tim de Koning (http://www.kingsquare.nl)
      // %        note 1: Float encoding by: Jonas Raoni Soares Silva
      // %        note 2: Home: http://www.kingsquare.nl/blog/12-12-2009/13507444
      // %        note 3: Feedback: phpjs-pack@kingsquare.nl
      // %        note 4: 'machine dependent byte order and size' aren't
      // %        note 4: applicable for JavaScript; pack works as on a 32bit,
      // %        note 4: little endian machine
      // *     example 1: pack('nvc*', 0x1234, 0x5678, 65, 66);
      // *     returns 1: '4xVAB'
  
      var formatPointer = 0,
          argumentPointer = 1,
          result = '',
          argument = '',
          i = 0,
          r = [],
          instruction, quantifier, word, precisionBits,
          exponentBits, extraNullCount;
  
      // vars used by float encoding
      var bias, minExp, maxExp, minUnnormExp, status, exp, len, bin,
          signal, n, intPart, floatPart, lastBit, rounded, j, k, tmpResult;
  
      while (formatPointer < format.length) {
          instruction = format[formatPointer];
          quantifier = '';
          formatPointer++;
          while ((formatPointer < format.length) &&
                (format[formatPointer].match(/[\d\*]/) !== null)) {
              quantifier += format[formatPointer];
              formatPointer++;
          }
          if (quantifier === '') {
              quantifier = '1';
          }
  
          // Now pack variables: 'quantifier' times 'instruction'
          switch (instruction) {
          case 'a': // NUL-padded string
          case 'A': // SPACE-padded string
  
              if (typeof arguments[argumentPointer] === 'undefined') {
                  throw new Error('Warning:  pack() Type ' + instruction +
                         ': not enough arguments');
              } else {
                  argument = String(arguments[argumentPointer]);
              }
              if (quantifier === '*') {
                  quantifier = argument.length;
              }
              for (i = 0; i < quantifier; i ++) {
                  if (typeof argument[i] === 'undefined') {
                      if (instruction === 'a') {
                          result += String.fromCharCode(0);
                      } else {
                          result += ' ';
                      }
                  } else {
                      result += argument[i];
                  }
              }
              argumentPointer++;
              break;
          case 'h': // Hex string, low nibble first
          case 'H': // Hex string, high nibble first
              if (typeof arguments[argumentPointer] === 'undefined') {
                  throw new Error('Warning: pack() Type ' + instruction +
                          ': not enough arguments');
              } else {
                  argument = arguments[argumentPointer];
              }
              if (quantifier === '*') {
                  quantifier = argument.length;
              }
              if (quantifier > argument.length) {
                  throw new Error('Warning: pack() Type ' + instruction +
                          ': not enough characters in string');
              }
              for (i = 0; i < quantifier; i += 2) {
                  // Always get per 2 bytes...
                  word = argument[i];
                  if (((i + 1) >= quantifier) ||
                          typeof(argument[i + 1]) === 'undefined') {
                      word += '0';
                  } else {
                      word += argument[i + 1];
                  }
                  // The fastest way to reverse?
                  if (instruction === 'h') {
                      word = word[1] + word[0];
                  }
                  result += String.fromCharCode(parseInt(word, 16));
              }
              argumentPointer++;
              break;
  
          case 'c': // signed char
          case 'C': // unsigned char
              // c and C is the same in pack
              if (quantifier === '*') {
                  quantifier = arguments.length - argumentPointer;
              }
              if (quantifier > (arguments.length - argumentPointer)) {
                  throw new Error('Warning:  pack() Type ' + instruction +
                          ': too few arguments');
              }
  
              for (i = 0; i < quantifier; i++) {
                  result += String.fromCharCode(arguments[argumentPointer]);
                  argumentPointer++;
              }
              break;
  
          case 's': // signed short (always 16 bit, machine byte order)
          case 'S': // unsigned short (always 16 bit, machine byte order)
          case 'v':
              // s and S is the same in pack
              if (quantifier === '*') {
                  quantifier = arguments.length - argumentPointer;
              }
              if (quantifier > (arguments.length - argumentPointer)) {
                  throw new Error('Warning:  pack() Type ' + instruction +
                          ': too few arguments');
              }
  
              for (i = 0; i < quantifier; i++) {
                  result += String.fromCharCode(arguments[argumentPointer] &
                          0xFF);
                  result += String.fromCharCode(arguments[argumentPointer] >>
                          8 & 0xFF);
                  argumentPointer++;
              }
              break;
  
          case 'n': // unsigned short (always 16 bit, big endian byte order)
              if (quantifier === '*') {
                  quantifier = arguments.length - argumentPointer;
              }
              if (quantifier > (arguments.length - argumentPointer)) {
                  throw new Error('Warning:  pack() Type ' + instruction +
                          ': too few arguments');
              }
  
              for (i = 0; i < quantifier; i++) {
                  result += String.fromCharCode(arguments[argumentPointer] >>
                          8 & 0xFF);
                  result += String.fromCharCode(arguments[argumentPointer] &
                          0xFF);
                  argumentPointer++;
              }
              break;
  
          case 'i': // signed integer (machine dependent size and byte order)
          case 'I': // unsigned integer (machine dependent size and byte order)
          case 'l': // signed long (always 32 bit, machine byte order)
          case 'L': // unsigned long (always 32 bit, machine byte order)
          case 'V': // unsigned long (always 32 bit, little endian byte order)
              if (quantifier === '*') {
                  quantifier = arguments.length - argumentPointer;
              }
              if (quantifier > (arguments.length - argumentPointer)) {
                  throw new Error('Warning:  pack() Type ' + instruction +
                          ': too few arguments');
              }
  
              for (i = 0; i < quantifier; i++) {
                  result += String.fromCharCode(arguments[argumentPointer] &
                          0xFF);
                  result += String.fromCharCode(arguments[argumentPointer] >>
                          8 & 0xFF);
                  result += String.fromCharCode(arguments[argumentPointer] >>
                          16 & 0xFF);
                  result += String.fromCharCode(arguments[argumentPointer] >>
                          24 & 0xFF);
                  argumentPointer++;
              }
  
              break;
          case 'N': // unsigned long (always 32 bit, big endian byte order)
              if (quantifier === '*') {
                  quantifier = arguments.length - argumentPointer;
              }
              if (quantifier > (arguments.length - argumentPointer)) {
                  throw new Error('Warning:  pack() Type ' + instruction +
                          ': too few arguments');
              }
  
              for (i = 0; i < quantifier; i++) {
                  result += String.fromCharCode(arguments[argumentPointer] >>
                          24 & 0xFF);
                  result += String.fromCharCode(arguments[argumentPointer] >>
                          16 & 0xFF);
                  result += String.fromCharCode(arguments[argumentPointer] >>
                          8 & 0xFF);
                  result += String.fromCharCode(arguments[argumentPointer] &
                          0xFF);
                  argumentPointer++;
              }
              break;
  
          case 'f': // float (machine dependent size and representation)
          case 'd': // double (machine dependent size and representation)
              // version based on IEEE754
  
              precisionBits = 23;
              exponentBits = 8;
              if (instruction === 'd') {
                  precisionBits = 52;
                  exponentBits = 11;
              }
  
              if (quantifier === '*') {
                  quantifier = arguments.length - argumentPointer;
              }
              if (quantifier > (arguments.length - argumentPointer)) {
                  throw new Error('Warning:  pack() Type ' + instruction +
                          ': too few arguments');
              }
              for (i = 0; i < quantifier; i++) {
                  argument = arguments[argumentPointer];
                  bias = Math.pow(2, exponentBits - 1) - 1;
                  minExp = -bias + 1;
                  maxExp = bias;
                  minUnnormExp = minExp - precisionBits;
                  status = isNaN(n = parseFloat(argument)) ||
                          n === -Infinity ||
                          n === +Infinity ? n : 0;
                  exp = 0;
                  len = 2 * bias + 1 + precisionBits + 3;
                  bin = new Array(len);
                  signal = (n = status !== 0 ? 0 : n) < 0;
                  n = Math.abs(n);
                  intPart = Math.floor(n);
                  floatPart = n - intPart;
  
                  for (k = len; k;) {
                      bin[--k] = 0;
                  }
                  for (k = bias + 2; intPart && k;) {
                      bin[--k] = intPart % 2;
                      intPart = Math.floor(intPart / 2);
                  }
                  for (k = bias + 1; floatPart > 0 && k; --floatPart) {
                      (bin[++k] = ((floatPart *= 2) >= 1) - 0);
                  }
                  for (k = -1; ++k < len && !bin[k];) {}
  
                  if (bin[(lastBit = precisionBits - 1 +
                          (k = (exp = bias + 1 - k) >= minExp &&
                          exp <= maxExp ?
                              k + 1 :
                              bias + 1 - (exp = minExp - 1))
                          ) + 1]) {
                      if (!(rounded = bin[lastBit])) {
                          for (j = lastBit + 2;
                                  !rounded &&
                                  j < len; rounded = bin[j++]) {}
                      }
                      for (j = lastBit + 1; rounded && --j >= 0;
                              (bin[j] = !bin[j] - 0) && (rounded = 0)) {}
                  }
  
                  for (k = k - 2 < 0 ? -1 : k - 3; ++k < len && !bin[k];) {}
  
                  if ((exp = bias + 1 - k) >= minExp && exp <= maxExp) {
                      ++k;
                  } else {
                      if (exp < minExp) {
                          if (exp !== bias + 1 - len && exp < minUnnormExp) {
                              /*"encodeFloat::float underflow" */
                          }
                          k = bias + 1 - (exp = minExp - 1);
                      }
                  }
  
                  if (intPart || status !== 0) {
                      exp = maxExp + 1;
                      k = bias + 2;
                      if (status === -Infinity) {
                          signal = 1;
                      } else if (isNaN(status)) {
                          bin[k] = 1;
                      }
                  }
  
                  n = Math.abs(exp + bias);
                  tmpResult = '';
  
                  for (j = exponentBits + 1; --j;) {
                      tmpResult = (n % 2) + tmpResult;
                      n = n >>= 1;
                  }
  
                  n = 0;
                  j = 0;
                  k = (tmpResult = (signal ? '1' : '0') + tmpResult +
                          bin.slice(k, k + precisionBits).join('')).length;
                  r = [];
  
                  for (; k;) {
                      n += (1 << j) * tmpResult.charAt(--k);
                      if (j === 7) {
                          r[r.length] = String.fromCharCode(n);
                          n = 0;
                      }
                      j = (j + 1) % 8;
                  }
  
                  r[r.length] = n ? String.fromCharCode(n) : '';
                  result += r.join('');
                  argumentPointer++;
              }
              break;
  
          case 'x': // NUL byte
              if (quantifier === '*') {
                  throw new Error('Warning: pack(): Type x: \'*\' ignored');
              }
              for (i = 0; i < quantifier; i ++) {
                  result += String.fromCharCode(0);
              }
              break;
  
          case 'X': // Back up one byte
              if (quantifier === '*') {
                  throw new Error('Warning: pack(): Type X: \'*\' ignored');
              }
              for (i = 0; i < quantifier; i ++) {
                  if (result.length === 0) {
                      throw new Error('Warning: pack(): Type X:' +
                              ' outside of string');
                  } else {
                      result = result.substring(0, result.length - 1);
                  }
              }
              break;
  
          case '@': // NUL-fill to absolute position
              if (quantifier === '*') {
                  throw new Error('Warning: pack(): Type X: \'*\' ignored');
              }
              if (quantifier > result.length) {
                  extraNullCount = quantifier - result.length;
                  for (i = 0; i < extraNullCount; i ++) {
                      result += String.fromCharCode(0);
                  }
              }
              if (quantifier < result.length) {
                  result = result.substring(0, quantifier);
              }
              break;
  
          default:
              throw new Error('Warning:  pack() Type ' + instruction +
                      ': unknown format code');
          }
      }
      if (argumentPointer < arguments.length) {
          throw new Error('Warning: pack(): ' +
                  (arguments.length - argumentPointer) + ' arguments unused');
      }
  
      return result;
  }
  