Merge branch 'master' of github.com:airbnb/lottie-web
diff --git a/player/index.html b/player/index.html
index 6f53dde..b17f656 100644
--- a/player/index.html
+++ b/player/index.html
@@ -12,7 +12,7 @@
         }
 
         #lottie{
-            background-color:#ddd;
+            background-color:#000;
             width:600px;
             height:400px;
             display:block;
@@ -32,6 +32,7 @@
     <script src="js/utils/helpers/html_elements.js"></script>
     <script src="js/utils/helpers/dynamicProperties.js"></script>
     <script src="js/utils/helpers/blendModes.js"></script>
+    <script src="js/utils/helpers/shapeEnums.js"></script>
     <script src="js/3rd_party/transformation-matrix.js"></script>
     <script src="js/3rd_party/seedrandom.js"></script>
     <script src="js/3rd_party/BezierEaser.js"></script>
diff --git a/player/js/elements/ShapeElement.js b/player/js/elements/ShapeElement.js
index bd829ca..84c25c7 100644
--- a/player/js/elements/ShapeElement.js
+++ b/player/js/elements/ShapeElement.js
@@ -42,16 +42,7 @@
       }
     }
   },
-  lcEnum: {
-    1: 'butt',
-    2: 'round',
-    3: 'square',
-  },
-  ljEnum: {
-    1: 'miter',
-    2: 'round',
-    3: 'bevel',
-  },
+
   searchProcessedElement: function (elem) {
     var elements = this.processedElements;
     var i = 0;
diff --git a/player/js/elements/canvasElements/CVShapeElement.js b/player/js/elements/canvasElements/CVShapeElement.js
index 5e56c82..22b6975 100644
--- a/player/js/elements/canvasElements/CVShapeElement.js
+++ b/player/js/elements/canvasElements/CVShapeElement.js
@@ -1,6 +1,6 @@
 /* global ShapeTransformManager, extendPrototype, BaseElement, TransformElement, CVBaseElement, IShapeElement,
 HierarchyElement, FrameElement, RenderableElement, RenderableDOMElement, PropertyFactory, degToRads, GradientProperty,
-DashProperty, TransformPropertyFactory, CVShapeData, ShapeModifiers, bmFloor */
+DashProperty, TransformPropertyFactory, CVShapeData, ShapeModifiers, bmFloor, lineCapEnum, lineJoinEnum */
 
 function CVShapeElement(data, globalData, comp) {
   this.shapes = [];
@@ -50,8 +50,8 @@
   }
   elementData.o = PropertyFactory.getProp(this, data.o, 0, 0.01, this);
   if (data.ty === 'st' || data.ty === 'gs') {
-    styleElem.lc = this.lcEnum[data.lc] || 'round';
-    styleElem.lj = this.ljEnum[data.lj] || 'round';
+    styleElem.lc = lineCapEnum[data.lc || 2];
+    styleElem.lj = lineJoinEnum[data.lj || 2];
     if (data.lj == 1) { // eslint-disable-line eqeqeq
       styleElem.ml = data.ml;
     }
diff --git a/player/js/elements/helpers/shapes/SVGGradientFillStyleData.js b/player/js/elements/helpers/shapes/SVGGradientFillStyleData.js
index fd75d73..9452eb5 100644
--- a/player/js/elements/helpers/shapes/SVGGradientFillStyleData.js
+++ b/player/js/elements/helpers/shapes/SVGGradientFillStyleData.js
@@ -1,5 +1,5 @@
 /* global PropertyFactory, degToRads, GradientProperty, createElementID, createNS, locationHref,
-extendPrototype, DynamicPropertyContainer */
+extendPrototype, DynamicPropertyContainer, lineCapEnum, lineJoinEnum */
 
 function SVGGradientFillStyleData(elem, data, styleOb) {
   this.initDynamicPropertyContainer(elem);
@@ -38,7 +38,6 @@
     stops.push(stop);
   }
   pathElement.setAttribute(data.ty === 'gf' ? 'fill' : 'stroke', 'url(' + locationHref + '#' + gradientId + ')');
-
   this.gf = gfill;
   this.cst = stops;
 };
@@ -67,6 +66,13 @@
       stops.push(stop);
     }
     maskElement.setAttribute(data.ty === 'gf' ? 'fill' : 'stroke', 'url(' + locationHref + '#' + opacityId + ')');
+    if (data.ty === 'gs') {
+      maskElement.setAttribute('stroke-linecap', lineCapEnum[data.lc || 2]);
+      maskElement.setAttribute('stroke-linejoin', lineJoinEnum[data.lj || 2]);
+      if (data.lj === 1) {
+        maskElement.setAttribute('stroke-miterlimit', data.ml);
+      }
+    }
     this.of = opFill;
     this.ms = mask;
     this.ost = stops;
diff --git a/player/js/elements/htmlElements/HTextElement.js b/player/js/elements/htmlElements/HTextElement.js
index 96f7221..2e87a2c 100644
--- a/player/js/elements/htmlElements/HTextElement.js
+++ b/player/js/elements/htmlElements/HTextElement.js
@@ -1,5 +1,5 @@
 /* global extendPrototype, BaseElement, TransformElement, HBaseElement, HierarchyElement, FrameElement,
-RenderableDOMElement, ITextElement, createSizedArray, createTag, styleDiv, createNS */
+RenderableDOMElement, ITextElement, createSizedArray, createTag, styleDiv, createNS, lineJoinEnum, lineCapEnum */
 
 function HTextElement(data, globalData, comp) {
   this.textSpans = [];
@@ -76,8 +76,8 @@
     if (this.globalData.fontManager.chars) {
       if (!this.textPaths[cnt]) {
         tSpan = createNS('path');
-        tSpan.setAttribute('stroke-linecap', 'butt');
-        tSpan.setAttribute('stroke-linejoin', 'round');
+        tSpan.setAttribute('stroke-linecap', lineCapEnum[1]);
+        tSpan.setAttribute('stroke-linejoin', lineJoinEnum[2]);
         tSpan.setAttribute('stroke-miterlimit', '4');
       } else {
         tSpan = this.textPaths[cnt];
diff --git a/player/js/elements/svgElements/SVGShapeElement.js b/player/js/elements/svgElements/SVGShapeElement.js
index db9ef01..29d9e74 100644
--- a/player/js/elements/svgElements/SVGShapeElement.js
+++ b/player/js/elements/svgElements/SVGShapeElement.js
@@ -1,7 +1,8 @@
 /* global extendPrototype, BaseElement, TransformElement, SVGBaseElement, IShapeElement, HierarchyElement,
 FrameElement, RenderableDOMElement, Matrix, SVGStyleData, SVGStrokeStyleData, SVGFillStyleData,
 SVGGradientFillStyleData, SVGGradientStrokeStyleData, locationHref, getBlendMode, ShapeGroupData,
-TransformPropertyFactory, SVGTransformData, ShapePropertyFactory, SVGShapeData, SVGElementsRenderer, ShapeModifiers */
+TransformPropertyFactory, SVGTransformData, ShapePropertyFactory, SVGShapeData, SVGElementsRenderer, ShapeModifiers,
+lineCapEnum, lineJoinEnum */
 
 function SVGShapeElement(data, globalData, comp) {
   // List of drawable elements
@@ -98,8 +99,8 @@
   }
 
   if (data.ty === 'st' || data.ty === 'gs') {
-    pathElement.setAttribute('stroke-linecap', this.lcEnum[data.lc] || 'round');
-    pathElement.setAttribute('stroke-linejoin', this.ljEnum[data.lj] || 'round');
+    pathElement.setAttribute('stroke-linecap', lineCapEnum[data.lc || 2]);
+    pathElement.setAttribute('stroke-linejoin', lineJoinEnum[data.lj || 2]);
     pathElement.setAttribute('fill-opacity', '0');
     if (data.lj === 1) {
       pathElement.setAttribute('stroke-miterlimit', data.ml);
diff --git a/player/js/utils/BaseEvent.js b/player/js/utils/BaseEvent.js
index 90cef4c..3612690 100644
--- a/player/js/utils/BaseEvent.js
+++ b/player/js/utils/BaseEvent.js
@@ -2,9 +2,9 @@
 BaseEvent.prototype = {
   triggerEvent: function (eventName, args) {
     if (this._cbs[eventName]) {
-      var len = this._cbs[eventName].length;
-      for (var i = 0; i < len; i += 1) {
-        this._cbs[eventName][i](args);
+      var callbacks = this._cbs[eventName];
+      for (var i = 0; i < callbacks.length; i += 1) {
+        callbacks[i](args);
       }
     }
   },
diff --git a/player/js/utils/expressions/TextSelectorPropertyDecorator.js b/player/js/utils/expressions/TextSelectorPropertyDecorator.js
index 0e28554..f7f9519 100644
--- a/player/js/utils/expressions/TextSelectorPropertyDecorator.js
+++ b/player/js/utils/expressions/TextSelectorPropertyDecorator.js
@@ -1,43 +1,41 @@
 /* global expressionHelpers, TextSelectorProp, ExpressionManager */
-/* exported TextExpressionSelectorProp */
+/* exported TextExpressionSelectorPropFactory */
 
-(function () {
-  var TextExpressionSelectorProp = (function () { // eslint-disable-line no-unused-vars
-    function getValueProxy(index, total) {
-      this.textIndex = index + 1;
-      this.textTotal = total;
-      this.v = this.getValue() * this.mult;
-      return this.v;
+var TextExpressionSelectorPropFactory = (function () { // eslint-disable-line no-unused-vars
+  function getValueProxy(index, total) {
+    this.textIndex = index + 1;
+    this.textTotal = total;
+    this.v = this.getValue() * this.mult;
+    return this.v;
+  }
+
+  return function (elem, data) {
+    this.pv = 1;
+    this.comp = elem.comp;
+    this.elem = elem;
+    this.mult = 0.01;
+    this.propType = 'textSelector';
+    this.textTotal = data.totalChars;
+    this.selectorValue = 100;
+    this.lastValue = [1, 1, 1];
+    this.k = true;
+    this.x = true;
+    this.getValue = ExpressionManager.initiateExpression.bind(this)(elem, data, this);
+    this.getMult = getValueProxy;
+    this.getVelocityAtTime = expressionHelpers.getVelocityAtTime;
+    if (this.kf) {
+      this.getValueAtTime = expressionHelpers.getValueAtTime.bind(this);
+    } else {
+      this.getValueAtTime = expressionHelpers.getStaticValueAtTime.bind(this);
     }
-
-    return function TextExpressionSelectorPropFactory(elem, data) {
-      this.pv = 1;
-      this.comp = elem.comp;
-      this.elem = elem;
-      this.mult = 0.01;
-      this.propType = 'textSelector';
-      this.textTotal = data.totalChars;
-      this.selectorValue = 100;
-      this.lastValue = [1, 1, 1];
-      this.k = true;
-      this.x = true;
-      this.getValue = ExpressionManager.initiateExpression.bind(this)(elem, data, this);
-      this.getMult = getValueProxy;
-      this.getVelocityAtTime = expressionHelpers.getVelocityAtTime;
-      if (this.kf) {
-        this.getValueAtTime = expressionHelpers.getValueAtTime.bind(this);
-      } else {
-        this.getValueAtTime = expressionHelpers.getStaticValueAtTime.bind(this);
-      }
-      this.setGroupProperty = expressionHelpers.setGroupProperty;
-    };
-  }());
-
-  var propertyGetTextProp = TextSelectorProp.getTextSelectorProp;
-  TextSelectorProp.getTextSelectorProp = function (elem, data, arr) {
-    if (data.t === 1) {
-      return new TextExpressionSelectorPropFactory(elem, data, arr); // eslint-disable-line no-undef
-    }
-    return propertyGetTextProp(elem, data, arr);
+    this.setGroupProperty = expressionHelpers.setGroupProperty;
   };
 }());
+
+var propertyGetTextProp = TextSelectorProp.getTextSelectorProp;
+TextSelectorProp.getTextSelectorProp = function (elem, data, arr) {
+  if (data.t === 1) {
+    return new TextExpressionSelectorPropFactory(elem, data, arr); // eslint-disable-line no-undef
+  }
+  return propertyGetTextProp(elem, data, arr);
+};
diff --git a/player/js/utils/helpers/shapeEnums.js b/player/js/utils/helpers/shapeEnums.js
new file mode 100644
index 0000000..3833acb
--- /dev/null
+++ b/player/js/utils/helpers/shapeEnums.js
@@ -0,0 +1,13 @@
+/* exported lineCapEnum, lineJoinEnum */
+
+var lineCapEnum = {
+  1: 'butt',
+  2: 'round',
+  3: 'square',
+};
+
+var lineJoinEnum = {
+  1: 'miter',
+  2: 'round',
+  3: 'bevel',
+};
diff --git a/tasks/build.js b/tasks/build.js
index dd18108..14ccf55 100644
--- a/tasks/build.js
+++ b/tasks/build.js
@@ -40,6 +40,10 @@
 		builds: defaultBuilds
 	},
 	{
+		src: 'js/utils/helpers/shapeEnums.js',
+		builds: defaultBuilds
+	},
+	{
 		src: 'js/3rd_party/transformation-matrix.js',
 		builds: defaultBuilds
 	},