text: function HybridRenderer(animationItem, config){
      this.animationItem = animationItem;
      this.layers = null;
      this.renderedFrame = -1;
      this.renderConfig = {
          className: (config && config.className) || '',
          imagePreserveAspectRatio: (config && config.imagePreserveAspectRatio) || 'xMidYMid slice',
          hideOnTransparent: (config && config.hideOnTransparent === false) ? false : true,
          filterSize: {
              width: config && config.filterSize && config.filterSize.width || '400%',
              height: config && config.filterSize && config.filterSize.height || '400%',
              x: config && config.filterSize && config.filterSize.x || '-100%',
              y: config && config.filterSize && config.filterSize.y || '-100%',
          }
      };
      this.globalData = {
          _mdf: false,
          frameNum: -1,
          renderConfig: this.renderConfig
      };
      this.pendingElements = [];
      this.elements = [];
      this.threeDElements = [];
      this.destroyed = false;
      this.camera = null;
      this.supports3d = true;
      this.rendererType = 'html';
  
  }
  
  extendPrototype([BaseRenderer],HybridRenderer);
  
  HybridRenderer.prototype.buildItem = SVGRenderer.prototype.buildItem;
  
  HybridRenderer.prototype.checkPendingElements  = function(){
      while(this.pendingElements.length){
          var element = this.pendingElements.pop();
          element.checkParenting();
      }
  };
  
  HybridRenderer.prototype.appendElementInPos = function(element, pos){
      var newDOMElement = element.getBaseElement();
      if(!newDOMElement){
          return;
      }
      var layer = this.layers[pos];
      if(!layer.ddd || !this.supports3d){
          if(this.threeDElements) {
              this.addTo3dContainer(newDOMElement,pos);
          } else {
              var i = 0;
              var nextDOMElement, nextLayer, tmpDOMElement;
              while(i<pos){
                  if(this.elements[i] && this.elements[i]!== true && this.elements[i].getBaseElement){
                      nextLayer = this.elements[i];
                      tmpDOMElement = this.layers[i].ddd ? this.getThreeDContainerByPos(i) : nextLayer.getBaseElement();
                      nextDOMElement = tmpDOMElement || nextDOMElement;
                  }
                  i += 1;
              }
              if(nextDOMElement){
                  if(!layer.ddd || !this.supports3d){
                      this.layerElement.insertBefore(newDOMElement, nextDOMElement);
                  }
              } else {
                  if(!layer.ddd || !this.supports3d){
                      this.layerElement.appendChild(newDOMElement);
                  }
              }
          }
          
      } else {
          this.addTo3dContainer(newDOMElement,pos);
      }
  };
  
  HybridRenderer.prototype.createShape = function (data) {
      if(!this.supports3d){
          return new SVGShapeElement(data, this.globalData, this);
      }
      return new HShapeElement(data, this.globalData, this);
  };
  
  HybridRenderer.prototype.createText = function (data) {
      if(!this.supports3d){
          return new SVGTextElement(data, this.globalData, this);
      }
      return new HTextElement(data, this.globalData, this);
  };
  
  HybridRenderer.prototype.createCamera = function (data) {
      this.camera = new HCameraElement(data, this.globalData, this);
      return this.camera;
  };
  
  HybridRenderer.prototype.createImage = function (data) {
      if(!this.supports3d){
          return new IImageElement(data, this.globalData, this);
      }
      return new HImageElement(data, this.globalData, this);
  };
  
  HybridRenderer.prototype.createComp = function (data) {
      if(!this.supports3d){
          return new SVGCompElement(data, this.globalData, this);
      }
      return new HCompElement(data, this.globalData, this);
  
  };
  
  HybridRenderer.prototype.createSolid = function (data) {
      if(!this.supports3d){
          return new ISolidElement(data, this.globalData, this);
      }
      return new HSolidElement(data, this.globalData, this);
  };
  
  HybridRenderer.prototype.createNull = SVGRenderer.prototype.createNull;
  
  HybridRenderer.prototype.getThreeDContainerByPos = function(pos){
      var i = 0, len = this.threeDElements.length;
      while(i<len) {
          if(this.threeDElements[i].startPos <= pos && this.threeDElements[i].endPos >= pos) {
              return this.threeDElements[i].perspectiveElem;
          }
          i += 1;
      }
  };
  
  HybridRenderer.prototype.createThreeDContainer = function(pos, type){
      var perspectiveElem = createTag('div');
      styleDiv(perspectiveElem);
      var container = createTag('div');
      styleDiv(container);
      if(type === '3d') {
          perspectiveElem.style.width = this.globalData.compSize.w+'px';
          perspectiveElem.style.height = this.globalData.compSize.h+'px';
          perspectiveElem.style.transformOrigin = perspectiveElem.style.mozTransformOrigin = perspectiveElem.style.webkitTransformOrigin = "50% 50%";
          container.style.transform = container.style.webkitTransform = 'matrix3d(1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1)';
      }
      
      perspectiveElem.appendChild(container);
      //this.resizerElem.appendChild(perspectiveElem);
      var threeDContainerData = {
          container:container,
          perspectiveElem:perspectiveElem,
          startPos: pos,
          endPos: pos,
          type: type
      };
      this.threeDElements.push(threeDContainerData);
      return threeDContainerData;
  };
  
  HybridRenderer.prototype.build3dContainers = function(){
      var i, len = this.layers.length;
      var lastThreeDContainerData;
      var currentContainer = '';
      for(i=0;i<len;i+=1){
          if(this.layers[i].ddd && this.layers[i].ty !== 3){
              if(currentContainer !== '3d'){
                  currentContainer = '3d';
                  lastThreeDContainerData = this.createThreeDContainer(i,'3d');
              }
              lastThreeDContainerData.endPos = Math.max(lastThreeDContainerData.endPos,i);
          } else {
              if(currentContainer !== '2d'){
                  currentContainer = '2d';
                  lastThreeDContainerData = this.createThreeDContainer(i,'2d');
              }
              lastThreeDContainerData.endPos = Math.max(lastThreeDContainerData.endPos,i);
          }
      }
      len = this.threeDElements.length;
      for(i = len - 1; i >= 0; i --) {
          this.resizerElem.appendChild(this.threeDElements[i].perspectiveElem);
      }
  };
  
  HybridRenderer.prototype.addTo3dContainer = function(elem,pos){
      var i = 0, len = this.threeDElements.length;
      while(i<len){
          if(pos <= this.threeDElements[i].endPos){
              var j = this.threeDElements[i].startPos;
              var nextElement;
              while(j<pos){
                  if(this.elements[j] && this.elements[j].getBaseElement){
                      nextElement = this.elements[j].getBaseElement();
                  }
                  j += 1;
              }
              if(nextElement){
                  this.threeDElements[i].container.insertBefore(elem, nextElement);
              } else {
                  this.threeDElements[i].container.appendChild(elem);
              }
              break;
          }
          i += 1;
      }
  };
  
  HybridRenderer.prototype.configAnimation = function(animData){
      var resizerElem = createTag('div');
      var wrapper = this.animationItem.wrapper;
      resizerElem.style.width = animData.w+'px';
      resizerElem.style.height = animData.h+'px';
      this.resizerElem = resizerElem;
      styleDiv(resizerElem);
      resizerElem.style.transformStyle = resizerElem.style.webkitTransformStyle = resizerElem.style.mozTransformStyle = "flat";
      if(this.renderConfig.className) {
        resizerElem.setAttribute('class', this.renderConfig.className);
      }
      wrapper.appendChild(resizerElem);
  
      resizerElem.style.overflow = 'hidden';
      var svg = createNS('svg');
      svg.setAttribute('width','1');
      svg.setAttribute('height','1');
      styleDiv(svg);
      this.resizerElem.appendChild(svg);
      var defs = createNS('defs');
      svg.appendChild(defs);
      this.data = animData;
      //Mask animation
      this.setupGlobalData(animData, svg);
      this.globalData.defs = defs;
      this.layers = animData.layers;
      this.layerElement = this.resizerElem;
      this.build3dContainers();
      this.updateContainerSize();
  };
  
  HybridRenderer.prototype.destroy = function () {
      this.animationItem.wrapper.innerHTML = '';
      this.animationItem.container = null;
      this.globalData.defs = null;
      var i, len = this.layers ? this.layers.length : 0;
      for (i = 0; i < len; i++) {
          this.elements[i].destroy();
      }
      this.elements.length = 0;
      this.destroyed = true;
      this.animationItem = null;
  };
  
  HybridRenderer.prototype.updateContainerSize = function () {
      var elementWidth = this.animationItem.wrapper.offsetWidth;
      var elementHeight = this.animationItem.wrapper.offsetHeight;
      var elementRel = elementWidth/elementHeight;
      var animationRel = this.globalData.compSize.w/this.globalData.compSize.h;
      var sx,sy,tx,ty;
      if(animationRel>elementRel){
          sx = elementWidth/(this.globalData.compSize.w);
          sy = elementWidth/(this.globalData.compSize.w);
          tx = 0;
          ty = ((elementHeight-this.globalData.compSize.h*(elementWidth/this.globalData.compSize.w))/2);
      }else{
          sx = elementHeight/(this.globalData.compSize.h);
          sy = elementHeight/(this.globalData.compSize.h);
          tx = (elementWidth-this.globalData.compSize.w*(elementHeight/this.globalData.compSize.h))/2;
          ty = 0;
      }
      this.resizerElem.style.transform = this.resizerElem.style.webkitTransform = 'matrix3d(' + sx + ',0,0,0,0,'+sy+',0,0,0,0,1,0,'+tx+','+ty+',0,1)';
  };
  
  HybridRenderer.prototype.renderFrame = SVGRenderer.prototype.renderFrame;
  
  HybridRenderer.prototype.hide = function(){
      this.resizerElem.style.display = 'none';
  };
  
  HybridRenderer.prototype.show = function(){
      this.resizerElem.style.display = 'block';
  };
  
  HybridRenderer.prototype.initItems = function(){
      this.buildAllItems();
      if(this.camera){
          this.camera.setup();
      } else {
          var cWidth = this.globalData.compSize.w;
          var cHeight = this.globalData.compSize.h;
          var i, len = this.threeDElements.length;
          for(i=0;i<len;i+=1){
              this.threeDElements[i].perspectiveElem.style.perspective = this.threeDElements[i].perspectiveElem.style.webkitPerspective = Math.sqrt(Math.pow(cWidth,2) + Math.pow(cHeight,2)) + 'px';
          }
      }
  };
  
  HybridRenderer.prototype.searchExtraCompositions = function(assets){
      var i, len = assets.length;
      var floatingContainer = createTag('div');
      for(i=0;i<len;i+=1){
          if(assets[i].xt){
              var comp = this.createComp(assets[i],floatingContainer,this.globalData.comp,null);
              comp.initExpressions();
              this.globalData.projectInterface.registerComposition(comp);
          }
      }
  };
  