text: var Node = require("./node"),
      unitConversions = require("../data/unit-conversions");
  
  var Unit = function (numerator, denominator, backupUnit) {
      this.numerator = numerator ? numerator.slice(0).sort() : [];
      this.denominator = denominator ? denominator.slice(0).sort() : [];
      this.backupUnit = backupUnit;
  };
  
  Unit.prototype = new Node();
  Unit.prototype.type = "Unit";
  Unit.prototype.clone = function () {
      return new Unit(this.numerator.slice(0), this.denominator.slice(0), this.backupUnit);
  };
  Unit.prototype.genCSS = function (context, output) {
      if (this.numerator.length >= 1) {
          output.add(this.numerator[0]);
      } else
      if (this.denominator.length >= 1) {
          output.add(this.denominator[0]);
      } else
      if ((!context || !context.strictUnits) && this.backupUnit) {
          output.add(this.backupUnit);
      }
  };
  Unit.prototype.toString = function () {
      var i, returnStr = this.numerator.join("*");
      for (i = 0; i < this.denominator.length; i++) {
          returnStr += "/" + this.denominator[i];
      }
      return returnStr;
  };
  Unit.prototype.compare = function (other) {
      return this.is(other.toString()) ? 0 : undefined;
  };
  Unit.prototype.is = function (unitString) {
      return this.toString().toUpperCase() === unitString.toUpperCase();
  };
  Unit.prototype.isLength = function () {
      return Boolean(this.toCSS().match(/px|em|%|in|cm|mm|pc|pt|ex/));
  };
  Unit.prototype.isEmpty = function () {
      return this.numerator.length === 0 && this.denominator.length === 0;
  };
  Unit.prototype.isSingular = function() {
      return this.numerator.length <= 1 && this.denominator.length === 0;
  };
  Unit.prototype.map = function(callback) {
      var i;
  
      for (i = 0; i < this.numerator.length; i++) {
          this.numerator[i] = callback(this.numerator[i], false);
      }
  
      for (i = 0; i < this.denominator.length; i++) {
          this.denominator[i] = callback(this.denominator[i], true);
      }
  };
  Unit.prototype.usedUnits = function() {
      var group, result = {}, mapUnit;
  
      mapUnit = function (atomicUnit) {
          /*jshint loopfunc:true */
          if (group.hasOwnProperty(atomicUnit) && !result[groupName]) {
              result[groupName] = atomicUnit;
          }
  
          return atomicUnit;
      };
  
      for (var groupName in unitConversions) {
          if (unitConversions.hasOwnProperty(groupName)) {
              group = unitConversions[groupName];
  
              this.map(mapUnit);
          }
      }
  
      return result;
  };
  Unit.prototype.cancel = function () {
      var counter = {}, atomicUnit, i, backup;
  
      for (i = 0; i < this.numerator.length; i++) {
          atomicUnit = this.numerator[i];
          if (!backup) {
              backup = atomicUnit;
          }
          counter[atomicUnit] = (counter[atomicUnit] || 0) + 1;
      }
  
      for (i = 0; i < this.denominator.length; i++) {
          atomicUnit = this.denominator[i];
          if (!backup) {
              backup = atomicUnit;
          }
          counter[atomicUnit] = (counter[atomicUnit] || 0) - 1;
      }
  
      this.numerator = [];
      this.denominator = [];
  
      for (atomicUnit in counter) {
          if (counter.hasOwnProperty(atomicUnit)) {
              var count = counter[atomicUnit];
  
              if (count > 0) {
                  for (i = 0; i < count; i++) {
                      this.numerator.push(atomicUnit);
                  }
              } else if (count < 0) {
                  for (i = 0; i < -count; i++) {
                      this.denominator.push(atomicUnit);
                  }
              }
          }
      }
  
      if (this.numerator.length === 0 && this.denominator.length === 0 && backup) {
          this.backupUnit = backup;
      }
  
      this.numerator.sort();
      this.denominator.sort();
  };
  module.exports = Unit;
  