// Generated by CoffeeScript 1.9.1
var CATEGORY_BITS, CATEGORY_MASK, CATEGORY_SHIFT, COMBINING_BITS, COMBINING_MASK, COMBINING_SHIFT, EAW_BITS, EAW_MASK, EAW_SHIFT, NUMBER_BITS, NUMBER_MASK, SCRIPT_BITS, SCRIPT_MASK, SCRIPT_SHIFT, UnicodeTrie, bits, data, fs, log2, trie;

UnicodeTrie = require('unicode-trie');

data = require('./data.json');

fs = require('fs');

trie = new UnicodeTrie(fs.readFileSync(__dirname + '/data.trie'));

log2 = Math.log2 || function(n) {
  return Math.log(n) / Math.LN2;
};

bits = function(n) {
  return (log2(n) + 1) | 0;
};

CATEGORY_BITS = bits(data.categories.length - 1);

COMBINING_BITS = bits(data.combiningClasses.length - 1);

SCRIPT_BITS = bits(data.scripts.length - 1);

EAW_BITS = bits(data.eaw.length - 1);

NUMBER_BITS = 10;

CATEGORY_SHIFT = COMBINING_BITS + SCRIPT_BITS + EAW_BITS + NUMBER_BITS;

COMBINING_SHIFT = SCRIPT_BITS + EAW_BITS + NUMBER_BITS;

SCRIPT_SHIFT = EAW_BITS + NUMBER_BITS;

EAW_SHIFT = NUMBER_BITS;

CATEGORY_MASK = (1 << CATEGORY_BITS) - 1;

COMBINING_MASK = (1 << COMBINING_BITS) - 1;

SCRIPT_MASK = (1 << SCRIPT_BITS) - 1;

EAW_MASK = (1 << EAW_BITS) - 1;

NUMBER_MASK = (1 << NUMBER_BITS) - 1;

exports.getCategory = function(codePoint) {
  var val;
  val = trie.get(codePoint);
  return data.categories[(val >> CATEGORY_SHIFT) & CATEGORY_MASK];
};

exports.getCombiningClass = function(codePoint) {
  var val;
  val = trie.get(codePoint);
  return data.combiningClasses[(val >> COMBINING_SHIFT) & COMBINING_MASK];
};

exports.getScript = function(codePoint) {
  var val;
  val = trie.get(codePoint);
  return data.scripts[(val >> SCRIPT_SHIFT) & SCRIPT_MASK];
};

exports.getEastAsianWidth = function(codePoint) {
  var val;
  val = trie.get(codePoint);
  return data.eaw[(val >> EAW_SHIFT) & EAW_MASK];
};

exports.getNumericValue = function(codePoint) {
  var denominator, exp, num, numerator, val;
  val = trie.get(codePoint);
  num = val & NUMBER_MASK;
  if (num === 0) {
    return null;
  } else if (num <= 50) {
    return num - 1;
  } else if (num < 0x1e0) {
    numerator = (num >> 4) - 12;
    denominator = (num & 0xf) + 1;
    return numerator / denominator;
  } else if (num < 0x300) {
    val = (num >> 5) - 14;
    exp = (num & 0x1f) + 2;
    while (exp > 0) {
      val *= 10;
      exp--;
    }
    return val;
  } else {
    val = (num >> 2) - 0xbf;
    exp = (num & 3) + 1;
    while (exp > 0) {
      val *= 60;
      exp--;
    }
    return val;
  }
};

exports.isAlphabetic = function(codePoint) {
  var ref;
  return (ref = exports.getCategory(codePoint)) === 'Lu' || ref === 'Ll' || ref === 'Lt' || ref === 'Lm' || ref === 'Lo' || ref === 'Nl';
};

exports.isDigit = function(codePoint) {
  return exports.getCategory(codePoint) === 'Nd';
};

exports.isPunctuation = function(codePoint) {
  var ref;
  return (ref = exports.getCategory(codePoint)) === 'Pc' || ref === 'Pd' || ref === 'Pe' || ref === 'Pf' || ref === 'Pi' || ref === 'Po' || ref === 'Ps';
};

exports.isLowerCase = function(codePoint) {
  return exports.getCategory(codePoint) === 'Ll';
};

exports.isUpperCase = function(codePoint) {
  return exports.getCategory(codePoint) === 'Lu';
};

exports.isTitleCase = function(codePoint) {
  return exports.getCategory(codePoint) === 'Lt';
};

exports.isWhiteSpace = function(codePoint) {
  var ref;
  return (ref = exports.getCategory(codePoint)) === 'Zs' || ref === 'Zl' || ref === 'Zp';
};

exports.isBaseForm = function(codePoint) {
  var ref;
  return (ref = exports.getCategory(codePoint)) === 'Nd' || ref === 'No' || ref === 'Nl' || ref === 'Lu' || ref === 'Ll' || ref === 'Lt' || ref === 'Lm' || ref === 'Lo' || ref === 'Me' || ref === 'Mc';
};

exports.isMark = function(codePoint) {
  var ref;
  return (ref = exports.getCategory(codePoint)) === 'Mn' || ref === 'Me' || ref === 'Mc';
};
