subtracted mask fix
diff --git a/extension/jsx/utils/shapeHelper.jsx b/extension/jsx/utils/shapeHelper.jsx
index b0fa5ef..1f7ae19 100644
--- a/extension/jsx/utils/shapeHelper.jsx
+++ b/extension/jsx/utils/shapeHelper.jsx
@@ -467,7 +467,7 @@
         /*if (!isText) {
             getShapeBounds(layerOb);
         }*/
-        getShapeBounds(layerOb);
+        //getShapeBounds(layerOb);
     }
     
     ob.exportShape = exportShape;
diff --git a/player/index.html b/player/index.html
index 5e1d421..e3cd954 100644
--- a/player/index.html
+++ b/player/index.html
@@ -12,8 +12,8 @@
 
         #bodymovin{
             background-color:#333;
-            width:1000px;
-            height:700px;
+            width:1200px;
+            height:900px;
             /*width:800px;
             height:500px;*/
             display:block;
@@ -97,6 +97,7 @@
     <script src="js/utils/expressions/ShapeInterface.js"></script>
     <script src="js/utils/expressions/LayerInterface.js"></script>
     <script src="js/utils/expressions/CompInterface.js"></script>
+    <script src="js/utils/expressions/TransformInterface.js"></script>
     <script src="js/utils/expressions/ProjectInterface.js"></script>
     <script src="js/effects/SliderEffect.js"></script>
     <script src="js/effects.js"></script>
@@ -114,10 +115,13 @@
     var anim;
     var animData = {
         container: document.getElementById('bodymovin'),
-        renderer: 'canvas',
-        loop: false,
+        renderer: 'svg',
+        loop: true,
         autoplay: true,
         autoloadSegments: true,
+        rendererSettings: {
+            progressiveLoad:true
+        },
         //animationData: anim2
         path: 'exports/render/data.json'
     };
diff --git a/player/js/animation/AnimationItem.js b/player/js/animation/AnimationItem.js
index 3ddb752..efc9372 100644
--- a/player/js/animation/AnimationItem.js
+++ b/player/js/animation/AnimationItem.js
@@ -216,6 +216,8 @@
 };
 
 AnimationItem.prototype.configAnimation = function (animData) {
+    //animData.w = Math.round(animData.w/blitter);
+    //animData.h = Math.round(animData.h/blitter);
     this.animationData = animData;
     this.totalFrames = Math.floor(this.animationData.op - this.animationData.ip);
     this.animationData.tf = this.totalFrames;
diff --git a/player/js/elements/BaseElement.js b/player/js/elements/BaseElement.js
index 1b5cc4e..c54a563 100644
--- a/player/js/elements/BaseElement.js
+++ b/player/js/elements/BaseElement.js
@@ -64,9 +64,34 @@
     return this.isVisible;
 };
 
+BaseElement.prototype.globalToLocal = function(pt){
+    var transforms = [];
+    transforms.push(this.finalTransform);
+    var flag = true;
+    var comp = this.comp;
+    while(flag){
+        if(comp.finalTransform){
+            if(comp.data.hasMask){
+                transforms.splice(0,0,comp.finalTransform);
+            }
+            comp = comp.comp;
+        } else {
+            flag = false;
+        }
+    }
+    var i, len = transforms.length,ptNew;
+    for(i=0;i<len;i+=1){
+        ptNew = transforms[i].mat.applyToPointArray(0,0,0);
+        //ptNew = transforms[i].mat.applyToPointArray(pt[0],pt[1],pt[2]);
+        pt = [pt[0] - ptNew[0],pt[1] - ptNew[1],0];
+    }
+    return pt;
+};
+
 BaseElement.prototype.initExpressions = function(){
     this.layerInterface = LayerExpressionInterface(this);
     //layers[i].layerInterface = LayerExpressionInterface(layers[i]);
+    //layers[i].layerInterface = LayerExpressionInterface(layers[i]);
     if(this.data.hasMask){
         this.layerInterface.registerMaskInterface(this.maskManager);
     }
diff --git a/player/js/elements/ShapeElement.js b/player/js/elements/ShapeElement.js
index ed55b49..42f3510 100644
--- a/player/js/elements/ShapeElement.js
+++ b/player/js/elements/ShapeElement.js
@@ -219,7 +219,7 @@
                     });
                 }
             }
-        }else if(arr[i].ty == 'tm' || arr[i].ty == 'rd'){
+        }else if(arr[i].ty == 'tm' || arr[i].ty == 'rd' || arr[i].ty == 'ms'){
             var modifier = ShapeModifiers.getModifier(arr[i].ty);
             modifier.init(this,arr[i],dynamicProperties);
             this.shapeModifiers.push(modifier);
@@ -267,6 +267,7 @@
         this.hide();
         return;
     }
+    this.globalToLocal([0,0,0]);
 
     this.hidden = false;
     this.renderModifiers();
diff --git a/player/js/elements/svgElements/SVGBaseElement.js b/player/js/elements/svgElements/SVGBaseElement.js
index c14e55f..93702a0 100644
--- a/player/js/elements/svgElements/SVGBaseElement.js
+++ b/player/js/elements/svgElements/SVGBaseElement.js
@@ -55,8 +55,8 @@
             feCTr.appendChild(feFunc);
             this.globalData.defs.appendChild(fil);
             var alphaRect = document.createElementNS(svgNS,'rect');
-            alphaRect.setAttribute('width','100%');
-            alphaRect.setAttribute('height','100%');
+            alphaRect.setAttribute('width',this.comp.data.w);
+            alphaRect.setAttribute('height',this.comp.data.h);
             alphaRect.setAttribute('x','0');
             alphaRect.setAttribute('y','0');
             alphaRect.setAttribute('fill','#ffffff');
diff --git a/player/js/mask.js b/player/js/mask.js
index 9c1ef25..1fd8264 100644
--- a/player/js/mask.js
+++ b/player/js/mask.js
@@ -31,11 +31,11 @@
         if((properties[i].mode == 's' || properties[i].mode == 'i') && count == 0){
             rect = document.createElementNS(svgNS, 'rect');
             rect.setAttribute('fill', '#ffffff');
-            rect.setAttribute('x', '0');
-            rect.setAttribute('y', '0');
-            rect.setAttribute('width', '100%');
-            rect.setAttribute('height', '100%');
+            rect.setAttribute('width', this.element.comp.data.w);
+            rect.setAttribute('height', this.element.comp.data.h);
             currentMasks.push(rect);
+        } else {
+            rect = null;
         }
 
         if(properties[i].mode == 'n' || properties[i].cl === false) {
@@ -123,6 +123,9 @@
             lastPath: '',
             prop:ShapePropertyFactory.getShapeProp(this.element,properties[i],3,this.dynamicProperties,null)
         };
+        if(rect){
+            this.viewData[i].invRect = rect;
+        }
         if(!this.viewData[i].prop.k){
             this.drawPath(properties[i],this.viewData[i].prop.v,this.viewData[i]);
         }
@@ -162,6 +165,10 @@
             if(this.viewData[i].prop.mdf || this.firstFrame){
                 this.drawPath(this.masksProperties[i],this.viewData[i].prop.v,this.viewData[i]);
             }
+            if(this.viewData[i].invRect && (this.element.finalTransform.mProp.mdf || this.firstFrame)){
+                this.viewData[i].invRect.setAttribute('x', -this.element.finalTransform.mProp.v.props[12]);
+                this.viewData[i].invRect.setAttribute('y', -this.element.finalTransform.mProp.v.props[13]);
+            }
             if(this.storedData[i].x && (this.storedData[i].x.mdf || this.firstFrame)){
                 var feMorph = this.storedData[i].expan;
                 if(this.storedData[i].x.v < 0){
diff --git a/player/js/renderers/SVGRenderer.js b/player/js/renderers/SVGRenderer.js
index 01df78f..717e265 100644
--- a/player/js/renderers/SVGRenderer.js
+++ b/player/js/renderers/SVGRenderer.js
@@ -131,6 +131,7 @@
     }else{
         this.renderedFrame = num;
     }
+    //clearPoints();
     /*console.log('-------');
     console.log('FRAME ',num);*/
     this.globalData.frameNum = num;
diff --git a/player/js/utils/DataManager.js b/player/js/utils/DataManager.js
index 8503b33..4cfcef0 100644
--- a/player/js/utils/DataManager.js
+++ b/player/js/utils/DataManager.js
@@ -61,6 +61,7 @@
     function completeShapes(arr){
         var i, len = arr.length;
         var j, jLen;
+        var hasPaths = false;
         for(i=len-1;i>=0;i-=1){
             if(arr[i].ty == 'sh'){
                 if(arr[i].ks.k.i){
@@ -76,10 +77,23 @@
                         }
                     }
                 }
+                hasPaths = true;
             }else if(arr[i].ty == 'gr'){
                 completeShapes(arr[i].it);
             }
         }
+        if(hasPaths){
+            //mx: distance
+            //ss: sensitivity
+            //dc: decay
+            /*arr.push({
+                "ty": "ms",
+                "mx":20,
+                "ss":10,
+                 "dc":0.001,
+                "maxDist":200
+            });*/
+        }
     }
 
     function convertPathsToAbsoluteValues(path){
@@ -172,9 +186,161 @@
         }
     }());
 
+    /*function blitPaths(path){
+        var i, len = path.i.length;
+        for(i=0;i<len;i+=1){
+            path.i[i][0] /= blitter;
+            path.i[i][1] /= blitter;
+            path.o[i][0] /= blitter;
+            path.o[i][1] /= blitter;
+            path.v[i][0] /= blitter;
+            path.v[i][1] /= blitter;
+        }
+    }
+
+    function blitShapes(arr){
+        var i, len = arr.length;
+        var j, jLen;
+        var hasPaths = false;
+        for(i=len-1;i>=0;i-=1){
+            if(arr[i].ty == 'sh'){
+                if(arr[i].ks.k.i){
+                    blitPaths(arr[i].ks.k);
+                }else{
+                    jLen = arr[i].ks.k.length;
+                    for(j=0;j<jLen;j+=1){
+                        if(arr[i].ks.k[j].s){
+                            blitPaths(arr[i].ks.k[j].s[0]);
+                        }
+                        if(arr[i].ks.k[j].e){
+                            blitPaths(arr[i].ks.k[j].e[0]);
+                        }
+                    }
+                }
+                hasPaths = true;
+            }else if(arr[i].ty == 'gr'){
+                blitShapes(arr[i].it);
+            }else if(arr[i].ty == 'rc'){
+                blitProperty(arr[i].p);
+                blitProperty(arr[i].s);
+            }else if(arr[i].ty == 'st'){
+                blitProperty(arr[i].w);
+            }else if(arr[i].ty == 'tr'){
+                blitProperty(arr[i].p);
+                blitProperty(arr[i].sk);
+                blitProperty(arr[i].a);
+            }else if(arr[i].ty == 'el'){
+                blitProperty(arr[i].p);
+                blitProperty(arr[i].s);
+            }else if(arr[i].ty == 'rd'){
+                blitProperty(arr[i].r);
+            }else{
+
+                //console.log(arr[i].ty );
+            }
+        }
+    }
+
+    function blitText(data, fontManager){
+
+    }
+
+    function blitValue(val){
+        if(typeof(val) === 'number'){
+            val /= blitter;
+        } else {
+            var i = val.length-1;
+            while(i>=0){
+                val[i] /= blitter;
+                i-=1;
+            }
+        }
+        return val;
+    }
+
+    function blitProperty(data){
+        if(!data.k.length){
+            data.k = blitValue(data.k);
+        }else if(typeof(data.k[0]) === 'number'){
+            data.k = blitValue(data.k);
+        } else {
+            var i, len = data.k.length;
+            for(i=0;i<len;i+=1){
+                if(data.k[i].s){
+                    //console.log('pre S: ', data.k[i].s);
+                    data.k[i].s = blitValue(data.k[i].s);
+                    //console.log('post S: ', data.k[i].s);
+                }
+                if(data.k[i].e){
+                    //console.log('pre E: ', data.k[i].e);
+                    data.k[i].e = blitValue(data.k[i].e);
+                    //console.log('post E: ', data.k[i].e);
+                }
+            }
+        }
+    }
+
+    function blitLayers(layers,comps, fontManager){
+        var layerData;
+        var animArray, lastFrame;
+        var i, len = layers.length;
+        var j, jLen, k, kLen;
+        for(i=0;i<len;i+=1){
+            layerData = layers[i];
+            if(!('ks' in layerData)){
+                continue;
+            }
+            blitProperty(layerData.ks.a);
+            blitProperty(layerData.ks.p);
+            layerData.completed = true;
+            if(layerData.tt){
+                layers[i-1].td = layerData.tt;
+            }
+            animArray = [];
+            lastFrame = -1;
+            if(layerData.hasMask){
+                var maskProps = layerData.masksProperties;
+                jLen = maskProps.length;
+                for(j=0;j<jLen;j+=1){
+                    if(maskProps[j].pt.k.i){
+                        blitPaths(maskProps[j].pt.k);
+                    }else{
+                        kLen = maskProps[j].pt.k.length;
+                        for(k=0;k<kLen;k+=1){
+                            if(maskProps[j].pt.k[k].s){
+                                blitPaths(maskProps[j].pt.k[k].s[0]);
+                            }
+                            if(maskProps[j].pt.k[k].e){
+                                blitPaths(maskProps[j].pt.k[k].e[0]);
+                            }
+                        }
+                    }
+                }
+            }
+            if(layerData.ty===0){
+                layerData.w = Math.round(layerData.w/blitter);
+                layerData.h = Math.round(layerData.h/blitter);
+                blitLayers(layerData.layers,comps, fontManager);
+            }else if(layerData.ty === 4){
+                blitShapes(layerData.shapes);
+            }else if(layerData.ty == 5){
+                blitText(layerData, fontManager);
+            }else if(layerData.ty == 1){
+                layerData.sh /= blitter;
+                layerData.sw /= blitter;
+            } else {
+            }
+        }
+    }
+
+    function blitAnimation(animationData,comps, fontManager){
+        blitLayers(animationData.layers,comps, fontManager);
+    }*/
+
     function completeData(animationData, fontManager){
         checkColors(animationData);
         completeLayers(animationData.layers, animationData.assets, fontManager);
+        //blitAnimation(animationData, animationData.assets, fontManager);
     }
 
     function completeText(data, fontManager){
diff --git a/player/js/utils/common.js b/player/js/utils/common.js
index 1b03778..c12c664 100644
--- a/player/js/utils/common.js
+++ b/player/js/utils/common.js
@@ -10,6 +10,7 @@
 var bm_floor = Math.floor;
 var bm_max = Math.max;
 var bm_min = Math.min;
+var blitter = 10;
 
 var BMMath = {};
 (function(){
diff --git a/player/js/utils/expressions/LayerInterface.js b/player/js/utils/expressions/LayerInterface.js
index 783b05c..2f56d7f 100644
--- a/player/js/utils/expressions/LayerInterface.js
+++ b/player/js/utils/expressions/LayerInterface.js
@@ -1,21 +1,23 @@
 var LayerExpressionInterface = (function (){
-   function toWorld(arr){
-       var toWorldMat = new Matrix();
-       toWorldMat.reset();
-       this._elem.finalTransform.mProp.applyToMatrix(toWorldMat);
-       if(this._elem.hierarchy && this._elem.hierarchy.length){
-           var i, len = this._elem.hierarchy.length;
-           for(i=0;i<len;i+=1){
-               this._elem.hierarchy[i].finalTransform.mProp.applyToMatrix(toWorldMat);
-           }
-           return toWorldMat.applyToPointArray(arr[0],arr[1],arr[2]||0);
-       }
-       return toWorldMat.applyToPointArray(arr[0],arr[1],arr[2]||0);
-   }
+    function toWorld(arr){
+        var toWorldMat = new Matrix();
+        toWorldMat.reset();
+        this._elem.finalTransform.mProp.applyToMatrix(toWorldMat);
+        if(this._elem.hierarchy && this._elem.hierarchy.length){
+            var i, len = this._elem.hierarchy.length;
+            for(i=0;i<len;i+=1){
+                this._elem.hierarchy[i].finalTransform.mProp.applyToMatrix(toWorldMat);
+            }
+            return toWorldMat.applyToPointArray(arr[0],arr[1],arr[2]||0);
+        }
+        return toWorldMat.applyToPointArray(arr[0],arr[1],arr[2]||0);
+    }
 
 
     return function(elem){
 
+        var transformInterface = TransformExpressionInterface(elem.transform);
+
         function _registerMaskInterface(maskManager){
             _thisLayerFunction.mask = maskManager.getMask.bind(maskManager);
         }
@@ -25,8 +27,9 @@
                 case "ADBE Root Vectors Group":
                 case 2:
                     return _thisLayerFunction.shapeInterface;
-                    //
-                    break;
+                case "Transform":
+                case "transform":
+                    return transformInterface;
                 case 4:
                     return elem.effectsManager;
             }
@@ -46,30 +49,30 @@
         });
         Object.defineProperty(_thisLayerFunction, "rotation", {
             get: function(){
-                return elem.transform.rotation;
+                return transformInterface.rotation;
             }
         });
         Object.defineProperty(_thisLayerFunction, "scale", {
             get: function () {
-                return elem.transform.scale;
+                return transformInterface.scale;
             }
         });
 
         Object.defineProperty(_thisLayerFunction, "position", {
             get: function () {
-                    return elem.transform.position;
-                }
+                return transformInterface.position;
+            }
         });
 
         Object.defineProperty(_thisLayerFunction, "anchorPoint", {
             get: function () {
-                return elem.transform.anchorPoint;
+                return transformInterface.anchorPoint;
             }
         });
 
         Object.defineProperty(_thisLayerFunction, "transform", {
             get: function () {
-                return elem.transform;
+                return transformInterface;
             }
         });
         Object.defineProperty(_thisLayerFunction, "_name", { value:elem.data.nm });
diff --git a/player/js/utils/expressions/TransformInterface.js b/player/js/utils/expressions/TransformInterface.js
new file mode 100644
index 0000000..d6953f4
--- /dev/null
+++ b/player/js/utils/expressions/TransformInterface.js
@@ -0,0 +1,47 @@
+var TransformExpressionInterface = (function (){
+    return function(transform){
+        function _thisFunction(name){
+            switch(name){
+                case "scale":
+                case "Scale":
+                    console.log('transformtransform', transform);
+                    console.log('_thisFunction', _thisFunction.scale);
+                    return _thisFunction.scale;
+                case "rotation":
+                case "Rotation":
+                    return _thisFunction.rotation;
+                case "position":
+                case "Position":
+                    return _thisFunction.position;
+                case "anchorPoint":
+                case "AnchorPoint":
+                    return _thisFunction.anchorPoint;
+            }
+        }
+
+        Object.defineProperty(_thisFunction, "rotation", {
+            get: function(){
+                return transform.rotation;
+            }
+        });
+        Object.defineProperty(_thisFunction, "scale", {
+            get: function () {
+                return transform.scale;
+            }
+        });
+
+        Object.defineProperty(_thisFunction, "position", {
+            get: function () {
+                return transform.position;
+            }
+        });
+
+        Object.defineProperty(_thisFunction, "anchorPoint", {
+            get: function () {
+                return transform.anchorPoint;
+            }
+        });
+
+        return _thisFunction;
+    }
+}());
\ No newline at end of file
diff --git a/player/js/utils/shapes/MouseModifier.js b/player/js/utils/shapes/MouseModifier.js
new file mode 100644
index 0000000..6a775ce
--- /dev/null
+++ b/player/js/utils/shapes/MouseModifier.js
@@ -0,0 +1,229 @@
+function MouseModifier(){};
+extendPrototype(ShapeModifier,MouseModifier);
+MouseModifier.prototype.processKeys = function(forceRender){
+    if(this.elem.globalData.frameId === this.frameId && !forceRender){
+        return;
+    }
+    this.mdf = true;
+
+};
+
+MouseModifier.prototype.addShapeToModifier = function(){
+    this.positions.push([]);
+};
+
+MouseModifier.prototype.processPath = function(path, mouseCoords, positions){
+    var i, len = path.v.length;
+    var vValues = [],oValues = [],iValues = [];
+    var dist;
+    //console.log(mouseCoords);
+    var theta, x,y;
+    //// OPTION A
+    for(i=0;i<len;i+=1){
+        if(!positions.v[i]){
+            positions.v[i] = [path.v[i][0],path.v[i][1]];
+            positions.o[i] = [path.o[i][0],path.o[i][1]];
+            positions.i[i] = [path.i[i][0],path.i[i][1]];
+            positions.distV[i] = 0;
+            positions.distO[i] = 0;
+            positions.distI[i] = 0;
+
+        }
+        theta = Math.atan2(
+            path.v[i][1] - mouseCoords[1],
+            path.v[i][0] - mouseCoords[0]
+        );
+
+        x = mouseCoords[0] - positions.v[i][0];
+        y = mouseCoords[1] - positions.v[i][1];
+        var distance = Math.sqrt( (x * x) + (y * y) );
+        positions.distV[i] += (distance - positions.distV[i]) * this.data.dc;
+
+        positions.v[i][0] = Math.cos(theta) * Math.max(0,this.data.maxDist-positions.distV[i])/2 + (path.v[i][0]);
+        positions.v[i][1] = Math.sin(theta) * Math.max(0,this.data.maxDist-positions.distV[i])/2 + (path.v[i][1]);
+
+
+        theta = Math.atan2(
+            path.o[i][1] - mouseCoords[1],
+            path.o[i][0] - mouseCoords[0]
+        );
+
+        x = mouseCoords[0] - positions.o[i][0];
+        y = mouseCoords[1] - positions.o[i][1];
+        var distance = Math.sqrt( (x * x) + (y * y) );
+        positions.distO[i] += (distance - positions.distO[i]) * this.data.dc;
+
+        positions.o[i][0] = Math.cos(theta) * Math.max(0,this.data.maxDist-positions.distO[i])/2 + (path.o[i][0]);
+        positions.o[i][1] = Math.sin(theta) * Math.max(0,this.data.maxDist-positions.distO[i])/2 + (path.o[i][1]);
+
+
+        theta = Math.atan2(
+            path.i[i][1] - mouseCoords[1],
+            path.i[i][0] - mouseCoords[0]
+        );
+
+        x = mouseCoords[0] - positions.i[i][0];
+        y = mouseCoords[1] - positions.i[i][1];
+        var distance = Math.sqrt( (x * x) + (y * y) );
+        positions.distI[i] += (distance - positions.distI[i]) * this.data.dc;
+
+        positions.i[i][0] = Math.cos(theta) * Math.max(0,this.data.maxDist-positions.distI[i])/2 + (path.i[i][0]);
+        positions.i[i][1] = Math.sin(theta) * Math.max(0,this.data.maxDist-positions.distI[i])/2 + (path.i[i][1]);
+
+        /////OPTION 1
+        vValues.push(positions.v[i]);
+         oValues.push(positions.o[i]);
+         iValues.push(positions.i[i]);
+
+
+
+        /////OPTION 2
+        //vValues.push(positions.v[i]);
+        // iValues.push([path.i[i][0]+(positions.v[i][0]-path.v[i][0]),path.i[i][1]+(positions.v[i][1]-path.v[i][1])]);
+        // oValues.push([path.o[i][0]+(positions.v[i][0]-path.v[i][0]),path.o[i][1]+(positions.v[i][1]-path.v[i][1])]);
+
+
+
+        /////OPTION 3
+        //vValues.push(positions.v[i]);
+        //iValues.push(path.i[i]);
+        //oValues.push(path.o[i]);
+
+
+        /////OPTION 4
+        //vValues.push(path.v[i]);
+         //oValues.push(positions.o[i]);
+         //iValues.push(positions.i[i]);
+    }
+
+
+
+    //// OPTION B
+    /*for(i=0;i<len;i+=1){
+        if(!positions.v[i]){
+            positions.v[i] = [path.v[i][0],path.v[i][1]];
+            positions.o[i] = [path.o[i][0],path.o[i][1]];
+            positions.i[i] = [path.i[i][0],path.i[i][1]];
+            positions.distV[i] = 0;
+
+        }
+        theta = Math.atan2(
+            positions.v[i][1] - mouseCoords[1],
+            positions.v[i][0] - mouseCoords[0]
+        );
+        x = mouseCoords[0] - positions.v[i][0];
+        y = mouseCoords[1] - positions.v[i][1];
+        var distance = this.data.ss * this.data.mx / Math.sqrt( (x * x) + (y * y) );
+
+        positions.v[i][0] += Math.cos(theta) * distance + (path.v[i][0] - positions.v[i][0]) * this.data.dc;
+        positions.v[i][1] += Math.sin(theta) * distance + (path.v[i][1] - positions.v[i][1]) * this.data.dc;
+
+
+        theta = Math.atan2(
+            positions.o[i][1] - mouseCoords[1],
+            positions.o[i][0] - mouseCoords[0]
+        );
+        x = mouseCoords[0] - positions.o[i][0];
+        y = mouseCoords[1] - positions.o[i][1];
+        var distance =  this.data.ss * this.data.mx / Math.sqrt( (x * x) + (y * y) );
+
+        positions.o[i][0] += Math.cos(theta) * distance + (path.o[i][0] - positions.o[i][0]) * this.data.dc;
+        positions.o[i][1] += Math.sin(theta) * distance + (path.o[i][1] - positions.o[i][1]) * this.data.dc;
+
+
+        theta = Math.atan2(
+            positions.i[i][1] - mouseCoords[1],
+            positions.i[i][0] - mouseCoords[0]
+        );
+        x = mouseCoords[0] - positions.i[i][0];
+        y = mouseCoords[1] - positions.i[i][1];
+        var distance =  this.data.ss * this.data.mx / Math.sqrt( (x * x) + (y * y) );
+
+        positions.i[i][0] += Math.cos(theta) * distance + (path.i[i][0] - positions.i[i][0]) * this.data.dc;
+        positions.i[i][1] += Math.sin(theta) * distance + (path.i[i][1] - positions.i[i][1]) * this.data.dc;
+
+        /////OPTION 1
+        //vValues.push(positions.v[i]);
+        // oValues.push(positions.o[i]);
+        // iValues.push(positions.i[i]);
+
+
+
+        /////OPTION 2
+        //vValues.push(positions.v[i]);
+        // iValues.push([path.i[i][0]+(positions.v[i][0]-path.v[i][0]),path.i[i][1]+(positions.v[i][1]-path.v[i][1])]);
+        // oValues.push([path.o[i][0]+(positions.v[i][0]-path.v[i][0]),path.o[i][1]+(positions.v[i][1]-path.v[i][1])]);
+
+
+
+        /////OPTION 3
+        //vValues.push(positions.v[i]);
+        //iValues.push(path.i[i]);
+        //oValues.push(path.o[i]);
+
+
+        /////OPTION 4
+        //vValues.push(path.v[i]);
+        // oValues.push(positions.o[i]);
+        // iValues.push(positions.i[i]);
+    }*/
+
+
+    return {
+        v:vValues,
+        o:oValues,
+        i:iValues,
+        c:path.c
+    };
+}
+
+MouseModifier.prototype.processShapes = function(){
+    var mouseX = this.elem.globalData.mouseX;
+    var mouseY = this.elem.globalData.mouseY;
+    var shapePaths;
+    var i, len = this.shapes.length;
+    var j, jLen;
+
+    if(mouseX){
+        var localMouseCoords = this.elem.globalToLocal([mouseX,mouseY,0]);
+
+        var shapeData, newPaths = [];
+        for(i=0;i<len;i+=1){
+            shapeData = this.shapes[i];
+            if(!shapeData.shape.mdf && !this.mdf){
+                shapeData.shape.paths = shapeData.last;
+            } else {
+                shapeData.shape.mdf = true;
+                shapePaths = shapeData.shape.paths;
+                jLen = shapePaths.length;
+                for(j=0;j<jLen;j+=1){
+                    if(!this.positions[i][j]){
+                        this.positions[i][j] = {
+                            v:[],
+                            o:[],
+                            i:[],
+                            distV:[],
+                            distO:[],
+                            distI:[]
+                        };
+                    }
+                    newPaths.push(this.processPath(shapePaths[j],localMouseCoords, this.positions[i][j]));
+                }
+                shapeData.shape.paths = newPaths;
+                shapeData.last = newPaths;
+            }
+        }
+
+    }
+
+}
+
+MouseModifier.prototype.initModifierProperties = function(elem,data){
+    this.getValue = this.processKeys;
+    this.data = data;
+    this.positions = [];
+};
+
+
+
+ShapeModifiers.registerModifier('ms',MouseModifier);
\ No newline at end of file
diff --git a/player/js/utils/shapes/ShapeModifiers.js b/player/js/utils/shapes/ShapeModifiers.js
index 87a8748..5dd45d7 100644
--- a/player/js/utils/shapes/ShapeModifiers.js
+++ b/player/js/utils/shapes/ShapeModifiers.js
@@ -19,9 +19,11 @@
 
 function ShapeModifier(){}
 ShapeModifier.prototype.initModifierProperties = function(){};
+ShapeModifier.prototype.addShapeToModifier = function(){};
 ShapeModifier.prototype.addShape = function(shape){
     if(!this.closed){
         this.shapes.push({shape:shape,last:[]});
+        this.addShapeToModifier(shape);
     }
 }
 ShapeModifier.prototype.init = function(elem,data,dynamicProperties){
diff --git a/player/js/utils/shapes/ShapeProperty.js b/player/js/utils/shapes/ShapeProperty.js
index 58adf3e..c4abc03 100644
--- a/player/js/utils/shapes/ShapeProperty.js
+++ b/player/js/utils/shapes/ShapeProperty.js
@@ -60,11 +60,27 @@
                 keyPropS = keyData.s[0];
             }
 
+            if(this.v.i.length !== keyPropS.i.length){
+                this.v.i.length = keyPropS.i.length;
+                this.v.o.length = keyPropS.o.length;
+                this.v.v.length = keyPropS.v.length;
+                this.pv.i.length = keyPropS.i.length;
+                this.pv.o.length = keyPropS.o.length;
+                this.pv.v.length = keyPropS.v.length;
+            }
             jLen = this.v.i.length;
             kLen = keyPropS.i[0].length;
             var hasModified = false;
             var vertexValue;
             for(j=0;j<jLen;j+=1){
+                if(!this.v.i[j]){
+                    this.v.i[j] = Array.apply(null,{length:kLen});
+                    this.v.o[j] = Array.apply(null,{length:kLen});
+                    this.v.v[j] = Array.apply(null,{length:kLen});
+                    this.pv.i[j] = Array.apply(null,{length:kLen});
+                    this.pv.o[j] = Array.apply(null,{length:kLen});
+                    this.pv.v[j] = Array.apply(null,{length:kLen});
+                }
                 for(k=0;k<kLen;k+=1){
                     if(isHold){
                         vertexValue = keyPropS.i[j][k];