text: (function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.Class = f()}})(function(){var define,module,exports;return (function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i<t.length;i++)o(t[i]);return o}return r})()({1:[function(require,module,exports){
  "use strict";
  
  var extractAnnotations = require("./annotation.js");
  
  var _disableConstructor = false;
  
  // Inherit from a class without calling its constructor.
  function inherit(SuperClass) {
      _disableConstructor = true;
      var __class__ = new SuperClass();
      _disableConstructor = false;
      return __class__;
  }
  
  // Checks if the given function uses abitbol special properties ($super, $name,...)
  function usesSpecialProperty(fn) {
      return Boolean(fn.toString().match(/.*(\$super|\$name|\$computedPropertyName).*/));
  }
  
  var Class = function () {};
  
  Object.defineProperty(Class, "$class", {
      enumerable: false,
      value: Class
  });
  
  Object.defineProperty(Class, "$map", {
      enumerable: false,
      value: {
          attributes: {},
          methods: {},
          computedProperties: {}
      }
  });
  
  Object.defineProperty(Class, "$extend", {
      enumerable: false,
      value: function (properties) {
          var _superClass = this;
          var _classMap = JSON.parse(JSON.stringify(_superClass.$map));  // not pretty :s
  
          // New class
          var __class__ = function () {
              if (_disableConstructor) {
                  return;
              }
              // Abitbol special properties
              Object.defineProperty(this, "$class", {
                  enumerable: false,
                  value: __class__
              });
              Object.defineProperty(this, "$map", {
                  enumerable: false,
                  value: _classMap
              });
              Object.defineProperty(this, "$data", {
                  enumerable: false,
                  value: {}
              });
              // Computed properties
              for (var property in _classMap.computedProperties) {
                  Object.defineProperty(this, property, {
                      enumerable: true,
                      configurable: false,
                      get: (_classMap.computedProperties[property].get !== undefined) ? (function (accessorName) {
                          return function () {
                              return this[accessorName].apply(this, arguments);
                          };
                      })(_classMap.computedProperties[property].get) : undefined,  // jshint ignore:line
                      set: (_classMap.computedProperties[property].set !== undefined) ? (function (mutatorName) {
                          return function () {
                              return this[mutatorName].apply(this, arguments);
                          };
                      })(_classMap.computedProperties[property].set) : undefined   // jshint ignore:line
                  });
              }
              // Bind this
              for (var method in _classMap.methods) {
                  this[method] = this[method].bind(this);
              }
              // Call the constructor if any
              if (this.__init__) {
                  this.__init__.apply(this, arguments);
              }
              return this;
          };
  
          // Inheritance
          __class__.prototype = inherit(this.$class);
  
          properties = properties || {};
  
          var _preBuildHook = properties.__preBuild__ || _superClass.prototype.__preBuild__;
          if (_preBuildHook) {
              _preBuildHook(properties, __class__, _superClass);
          }
  
          var property;
          var computedPropertyName;
          var annotations;
          var i;
          var mixin;
  
          // Copy properties from mixins
          if (properties.__include__) {
              for (i = properties.__include__.length - 1 ; i >= 0 ; i--) {
                  mixin = properties.__include__[i];
                  for (property in mixin) {
                      if (property == "__classvars__") {
                          continue;
                      } else if (properties[property] === undefined) {
                          properties[property] = mixin[property];
                      }
                  }
  
                  // Merging mixin's static properties
                  if (mixin.__classvars__) {
                      if (!properties.__classvars__) {
                          properties.__classvars__ = {};
                      }
                      for (property in mixin.__classvars__) {
                          if (properties.__classvars__[property] === undefined) {
                              properties.__classvars__[property] = mixin.__classvars__[property];
                          }
                      }
                  }
              }
          }
  
          // Add properties
          for (property in properties || {}) {
              if (property == "__include__" || property == "__classvars__") {
                  continue;
              }
              if (typeof properties[property] == "function") {
                  computedPropertyName = undefined;
                  _classMap.methods[property] = {annotations: {}};
                  // Accessors / Mutators
                  if (property.indexOf("get") === 0) {
                      computedPropertyName = property.slice(3, 4).toLowerCase() + property.slice(4, property.length);
                      if (!_classMap.computedProperties[computedPropertyName]) {
                          _classMap.computedProperties[computedPropertyName] = {annotations: {}};
                      }
                      _classMap.computedProperties[computedPropertyName].get = property;
                  } else if (property.indexOf("set") === 0) {
                      computedPropertyName = property.slice(3, 4).toLowerCase() + property.slice(4, property.length);
                      if (!_classMap.computedProperties[computedPropertyName]) {
                          _classMap.computedProperties[computedPropertyName] = {annotations: {}};
                      }
                      _classMap.computedProperties[computedPropertyName].set = property;
                  } else if (property.indexOf("has") === 0) {
                      computedPropertyName = property.slice(3, 4).toLowerCase() + property.slice(4, property.length);
                      if (!_classMap.computedProperties[computedPropertyName]) {
                          _classMap.computedProperties[computedPropertyName] = {annotations: {}};
                      }
                      _classMap.computedProperties[computedPropertyName].get = property;
                  } else if (property.indexOf("is") === 0) {
                      computedPropertyName = property.slice(2, 3).toLowerCase() + property.slice(3, property.length);
                      if (!_classMap.computedProperties[computedPropertyName]) {
                          _classMap.computedProperties[computedPropertyName] = {annotations: {}};
                      }
                      _classMap.computedProperties[computedPropertyName].get = property;
                  }
                  // Annotations
                  annotations = extractAnnotations(properties[property]);
                  for (var annotation in annotations) {
                      _classMap.methods[property].annotations[annotation] = annotations[annotation];
                      if (computedPropertyName) {
                          _classMap.computedProperties[computedPropertyName]
                                   .annotations[annotation] = annotations[annotation];
                      }
                  }
                  // Wrapped method
                  if (usesSpecialProperty(properties[property])) {
                      __class__.prototype[property] = (function (method, propertyName, computedPropertyName) {
                          return function () {
                              var _oldSuper = this.$super;
                              var _oldName = this.$name;
                              var _oldComputedPropertyName = this.$computedPropertyName;
  
                              this.$super = _superClass.prototype[propertyName];
                              this.$name = propertyName;
                              this.$computedPropertyName = computedPropertyName;
  
                              try {
                                  return method.apply(this, arguments);
                              } finally {
                                  if (_oldSuper) {
                                      this.$super = _oldSuper;
                                  } else {
                                      delete this.$super;
                                  }
                                  if (_oldName) {
                                      this.$name = _oldName;
                                  } else {
                                      delete this.$name;
                                  }
                                  if (_oldComputedPropertyName) {
                                      this.$computedPropertyName = _oldComputedPropertyName;
                                  } else {
                                      delete this.$computedPropertyName;
                                  }
                              }
                          };
                      })(properties[property], property, computedPropertyName);  // jshint ignore:line
  
                  // Simple methods
                  } else {
                      __class__.prototype[property] = properties[property];
                  }
              } else {
                  _classMap.attributes[property] = true;
                  __class__.prototype[property] = properties[property];
              }
          }
  
          // Copy super class static properties
          var scStaticProps = Object.getOwnPropertyNames(_superClass);
          // Removes caller, callee and arguments from the list (strict mode)
          // Removes non enumerable Abitbol properties too
          scStaticProps = scStaticProps.filter(function (value) {
              return (["caller", "callee", "arguments", "$class", "$extend", "$map"].indexOf(value) == -1);
          });
          for (i = 0 ; i < scStaticProps.length ; i++) {
              if (__class__[scStaticProps[i]] === undefined) {
                  __class__[scStaticProps[i]] = _superClass[scStaticProps[i]];
              }
          }
  
          // Add static properties
          if (properties.__classvars__) {
              for (property in properties.__classvars__) {
                  __class__[property] = properties.__classvars__[property];
              }
          }
  
          // Add abitbol static properties
          Object.defineProperty(__class__, "$class", {
              enumerable: false,
              value: __class__
          });
          Object.defineProperty(__class__, "$extend", {
              enumerable: false,
              value: Class.$extend
          });
          Object.defineProperty(__class__, "$map", {
              enumerable: false,
              value: _classMap
          });
  
          var _postBuildHook = properties.__postBuild__ || _superClass.prototype.__postBuild__;
          if (_postBuildHook) {
              _postBuildHook(properties, __class__, _superClass);
          }
  
          return __class__;
      }
  });
  
  module.exports = Class;
  
  },{"./annotation.js":2}],2:[function(require,module,exports){
  "use strict";
  
  function cleanJs(js) {
      // remove function fn(param) {
      // or fn(param) {
      // or (param) => {
      var c;
      var p = 0;
      for (var i = 0 ; i < js.length ; i++) {
          c = js[i];
          if (c == "(") {
              ++p;
          } else if (c == ")") {
              --p;
          } else if (c == "{" && p === 0) {
              js = js.slice(i + 1);
              break;
          }
      }
  
      // remove comments (not super safe but should work in most cases)
      js = js.replace(/\/\*(.|\r|\n)*?\*\//g, "");
      js = js.replace(/\/\/.*?\r?\n/g, "\n");
  
      // remove indentation and CR/LF
      js = js.replace(/\s*\r?\n\s*/g, "");
  
      return js;
  }
  
  function extractStrings(js) {
      var strings = [];
  
      var instr = false;
      var inesc = false;
      var quote;
      var buff;
      var c;
  
      for (var i = 0 ; i < js.length ; i++) {
          c = js[i];
  
          if (!instr) {
              // New string
              if (c == "\"" || c == "'") {
                  instr = true;
                  inesc = false;
                  quote = c;
                  buff = "";
              // Char we don't care about
              } else if ([" ", " ", "\n", "\r", ";"].indexOf(c) > -1) {  // jshint ignore:line
                  continue;
              // Other expression -> job finished!
              } else {
                  break;
              }
          } else {
              if (!inesc) {
                  // Escaped char
                  if (c == "\\") {
                      inesc = true;
                  // End of string
                  } else if (c == quote) {
                      strings.push(buff);
                      instr = false;
                  // Any char
                  } else {
                      buff += c;
                  }
              } else {
                  if (c == "\\") {
                      buff += "\\";
                  } else if (c == "n") {
                      buff += "\n";
                  } else if (c == "r") {
                      buff += "\r";
                  } else if (c == "t") {
                      buff += "\t";
                  } else if (c == quote) {
                      buff += quote;
                  // We don't care...
                  } else {
                      buff += "\\" + c;
                  }
                  inesc = false;
              }
          }
      }
  
      return strings;
  }
  
  function autoCast(value) {
      if (value == "true") {
          return true;
      } else if (value == "false") {
          return false;
      } else if (value == "null") {
          return null;
      } else if (value == "undefined") {
          return undefined;
      } else if (value.match(/^([0-9]+\.?|[0-9]*\.[0-9]+)$/)) {
          return parseFloat(value);
      } else {
          return value;
      }
  }
  
  function extractAnnotations(func) {
      var js = cleanJs(func.toString());
      var strings = extractStrings(js);
  
      var annotations = {};
      var string;
      var key;
      var value;
  
      for (var i = 0 ; i < strings.length ; i++) {
          string = strings[i].trim();
  
          if (string.indexOf("@") !== 0) {
              continue;
          }
  
          key = string.slice(1, (string.indexOf(" ") > -1) ? string.indexOf(" ") : string.length);
          value = true;
          if (string.indexOf(" ") > -1) {
              value = string.slice(string.indexOf(" ") + 1, string.length);
              value = value.trim();
              value = autoCast(value);
          }
  
          annotations[key] = value;
      }
  
      return annotations;
  }
  
  module.exports = extractAnnotations;
  
  },{}]},{},[1])(1)
  });
  