Merge branch 'master' of github.com:airbnb/lottie-web
diff --git a/player/js/module.js b/player/js/module.js
index d65086a..a1e02c3 100644
--- a/player/js/module.js
+++ b/player/js/module.js
@@ -1,6 +1,6 @@
 /* global locationHref:writable, animationManager, subframeEnabled:writable, defaultCurveSegments:writable, roundValues,
-expressionsPlugin:writable, PropertyFactory, ShapePropertyFactory, Matrix */
-/* exported locationHref, subframeEnabled, expressionsPlugin */
+expressionsPlugin:writable, PropertyFactory, ShapePropertyFactory, Matrix, idPrefix:writable */
+/* exported locationHref, subframeEnabled, expressionsPlugin, idPrefix */
 
 'use strict';
 
@@ -23,6 +23,10 @@
   subframeEnabled = flag;
 }
 
+function setIDPrefix(prefix) {
+  idPrefix = prefix;
+}
+
 function loadAnimation(params) {
   if (standalone === true) {
     params.animationData = JSON.parse(animationData);
@@ -101,6 +105,7 @@
 lottie.mute = animationManager.mute;
 lottie.unmute = animationManager.unmute;
 lottie.getRegisteredAnimations = animationManager.getRegisteredAnimations;
+lottie.setIDPrefix = setIDPrefix;
 lottie.__getFactory = getFactory;
 lottie.version = '[[BM_VERSION]]';
 
diff --git a/player/js/module_worker.js b/player/js/module_worker.js
index 0a0982f..99a721b 100644
--- a/player/js/module_worker.js
+++ b/player/js/module_worker.js
@@ -1,4 +1,5 @@
-/* global defaultCurveSegments:writable, roundValues, animationManager */
+/* global defaultCurveSegments:writable, roundValues, animationManager, idPrefix:writable */
+/* exported idPrefix */
 var lottie = (function () {
   'use strict';
 
@@ -33,6 +34,10 @@
     }
   }
 
+  function setIDPrefix(prefix) {
+    idPrefix = prefix;
+  }
+
   lottiejs.play = animationManager.play;
   lottiejs.pause = animationManager.pause;
   lottiejs.togglePause = animationManager.togglePause;
@@ -51,6 +56,7 @@
   lottiejs.mute = animationManager.mute;
   lottiejs.unmute = animationManager.unmute;
   lottiejs.getRegisteredAnimations = animationManager.getRegisteredAnimations;
+  lottie.setIDPrefix = setIDPrefix;
   lottiejs.version = '[[BM_VERSION]]';
 
   return lottiejs;
diff --git a/player/js/utils/common.js b/player/js/utils/common.js
index 3c6324d..6597283 100644
--- a/player/js/utils/common.js
+++ b/player/js/utils/common.js
@@ -5,6 +5,7 @@
 addSaturationToRGB, addBrightnessToRGB, addHueToRGB, rgbToHex */
 
 var subframeEnabled = true;
+var idPrefix = '';
 var expressionsPlugin;
 var isSafari = /^((?!chrome|android).)*safari/i.test(navigator.userAgent);
 var cachedColors = {};
@@ -120,7 +121,7 @@
   var _count = 0;
   return function createID() {
     _count += 1;
-    return '__lottie_element_' + _count;
+    return idPrefix + '__lottie_element_' + _count;
   };
 }());
 
diff --git a/player/js/utils/expressions/ShapeInterface.js b/player/js/utils/expressions/ShapeInterface.js
index 5739914..92d1f30 100644
--- a/player/js/utils/expressions/ShapeInterface.js
+++ b/player/js/utils/expressions/ShapeInterface.js
@@ -29,6 +29,10 @@
         arr.push(roundedInterfaceFactory(shapes[i], view[i], propertyGroup));
       } else if (shapes[i].ty === 'rp') {
         arr.push(repeaterInterfaceFactory(shapes[i], view[i], propertyGroup));
+      } else if (shapes[i].ty === 'gf') {
+        arr.push(gradientFillInterfaceFactory(shapes[i], view[i], propertyGroup));
+      } else {
+        arr.push(defaultInterfaceFactory(shapes[i], view[i], propertyGroup));
       }
     }
     return arr;
@@ -119,6 +123,51 @@
     return interfaceFunction;
   }
 
+  function gradientFillInterfaceFactory(shape, view, propertyGroup) {
+    function interfaceFunction(val) {
+      if (val === 'Start Point' || val === 'start point') {
+        return interfaceFunction.startPoint;
+      }
+      if (val === 'End Point' || val === 'end point') {
+        return interfaceFunction.endPoint;
+      }
+      if (val === 'Opacity' || val === 'opacity') {
+        return interfaceFunction.opacity;
+      }
+      return null;
+    }
+    Object.defineProperties(interfaceFunction, {
+      startPoint: {
+        get: ExpressionPropertyInterface(view.s),
+      },
+      endPoint: {
+        get: ExpressionPropertyInterface(view.e),
+      },
+      opacity: {
+        get: ExpressionPropertyInterface(view.o),
+      },
+      type: {
+        get: function() {
+          console.log('asdasdasdadPASO');
+          return 'a';
+        },
+      },
+      _name: { value: shape.nm },
+      mn: { value: shape.mn },
+    });
+
+    view.s.setGroupProperty(PropertyInterface('Start Point', propertyGroup));
+    view.e.setGroupProperty(PropertyInterface('End Point', propertyGroup));
+    view.o.setGroupProperty(PropertyInterface('Opacity', propertyGroup));
+    return interfaceFunction;
+  }
+  function defaultInterfaceFactory(shape, view, propertyGroup) {
+    function interfaceFunction(val) {
+      return null;
+    }
+    return interfaceFunction;
+  }
+
   function strokeInterfaceFactory(shape, view, propertyGroup) {
     var _propertyGroup = propertyGroupFactory(interfaceFunction, propertyGroup);
     var _dashPropertyGroup = propertyGroupFactory(dashOb, _propertyGroup);
@@ -234,7 +283,6 @@
       }
       return null;
     }
-
     var _propertyGroup = propertyGroupFactory(interfaceFunction, propertyGroup);
     view.transform.mProps.o.setGroupProperty(PropertyInterface('Opacity', _propertyGroup));
     view.transform.mProps.p.setGroupProperty(PropertyInterface('Position', _propertyGroup));
diff --git a/player/js/utils/imagePreloader.js b/player/js/utils/imagePreloader.js
index a8979f6..46a7b05 100644
--- a/player/js/utils/imagePreloader.js
+++ b/player/js/utils/imagePreloader.js
@@ -122,7 +122,7 @@
     var len = assets.length;
     for (i = 0; i < len; i += 1) {
       if (!assets[i].layers) {
-        if (!assets[i].t) {
+        if (!assets[i].t || assets[i].t === 'seq') {
           this.totalImages += 1;
           this.images.push(this._createImageData(assets[i]));
         } else if (assets[i].t === 3) {